段选和位选

例如,你要控制四个数码管,依次是1,2,3,4,你要选择哪一个数码管(一个数码管即为一个“日”)这就是位选,顾名思义为选择位置;之后你要让选择的数码管显示某一个数字或符号,你就要控制数码管的a,b,c,d,e,f,g这七个发光二极管,让其亮或灭,这就是段选,顾名思义为选择数码管的哪一段。

数据存储类型

  • 程序存储器(code)

    程序存储区(64KB),可直接理解为ROM,只读,可由汇编操作码MOVC @A DPTR访问,8051系列仅执行存储在code中的程序;

  • 内部数据存储

    对内部数据存储器的访问是非常快的,因为使用8位地址寻址;

    • data

      可直接寻址的内部数据存储器(128字节),可直接理解为内部RAM,读写速度最快;

    • idata

      间接可寻址内部数据存储器(256字节),其中前128字节和data的128字节完全相同,只是访问方法不一样;

    • bdata

      可位寻址的内部数据存储器(20h to 2Fh 16字节),支持混合位和字节访问。

  • 外部数据存储

    可读写,由于外部数据存储器是通过指针寄存器间接访问的,所以访问速度要比内部数据存储器慢,

    • xdata

      外部数据存储器(64KB),可直接理解外部RAM,可由汇编操作码MOVX @DPTR访问,Large Memory Model在此内存空间中定义变量;

    • pdata

      分页寻址外部数据存储器,其指定外部存储器中的一页(256字节),由操作码MOVX @Rn访问;Compact Memory Model在此内存空间中定义变量。

程序代码

#include "reg52.h"
#include "intrins.h"
#define uint unsigned int


sbit a = P2 ^ 4;
sbit b = P2 ^ 5;
sbit c = P2 ^ 6;
sbit d = P2 ^ 7;

sbit fm = P2 ^ 3;

//定义数码管段选的方式
unsigned char code sz[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

/*
*延迟函数
*/
void Delay(uint ms){
 uint i ,j;
 for(i = ms; i > 0; i--){
  for(j = 112; j>0; j--);
 }
}

/*
*位选数码管函数
*/
void Led(int id){
 switch(id){
  case 1:
   a = 1;b = 0;c = 0;d = 0;
   break;
  case 2:
   a = 0;b = 1;c = 0;d = 0;
   break;
  case 3:
   a = 0;b = 0;c = 1;d = 0;
   break;
  case 4:
   a = 0;b = 0;c = 0;d = 1;
   break;
  default:
   break;
 }
}


void main(){
 int i = 0;
 Led(1);
 while(1){
     P1 = 0xfe;
  for (i = 0; i < 8; i++){
   Led(4 - (i%4));
   P0 = sz[8 - i];
   fm = 0;
   Delay(100);
   fm = 1;

   Delay(1000);
   P1 = _crol_(P1,1);

  }
 }
}

可以看看这个数组定义:

unsigned char code sz[17] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

其中code是一个域修饰符,它指定该数组存储在程序存储区,写入后不可更改。