【蓝桥杯单片机组】(2)锁存器、数码管、蜂鸣器、继电器

2019-04-15 18:40发布

1、C51数据类型扩充
sfr 声明8位寄存器
sfr16 声明16为寄存器
sbit 声明寄存器中某一位,某IO口
bit 位变量声明

用sbit声明某一个端口
sbit LED = P1^0;

2、74HC573(锁存器)

WR端通过J13一直接地
Y4~Y7端通过138译码器接P25~P27
控制部分代码: P2 |= 0xe0; //选为Y7,使Y7=0 P0 = 0xc0; //传输到锁存器的数据 P2 &= 0X1F; //锁存,数据为第一行的取反

3、数码管 数码管采用共阳级(3.1更正) 数据:char code num[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; com1~com7为位选,置高为选通:
控制流程: P2 |= 0Xc0; //Y6C = 1 P0 = 0X01; //钻中第一位数码管com1 P2 &= 0X3F; //Y6C = 0; LOCK P0 = 0xff; //消隐 //当 P2 |= ...不起作用时,可能是P2之前的数据不对,导致无法用或操作修改为正确的数据;换成=即可 P2 |= 0XF0; //Y7C = 1; P0 = num[3]; //数字数据 P2 &= 0X0F; //Y7C = 0; LOCK delay(); //TODO:设置其他位
附:display.c #include "display.h" unsigned char num[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; void delayms(int x) { int i,j; for(i=x;i>0;i--) { for(j=110;j>0;j--); } } void display1(unsigned int displaynum) // 在第一组数码管上显示一个int数据 { unsigned char bit1,bit2,bit3,bit4; if(displaynum >= 10000) { bit1 = 9; bit2 = 9; bit3 = 9; bit4 = 9; } else if(displaynum >= 1000) { bit1 = displaynum/1000; bit2 = (displaynum%1000)/100; bit3 = (displaynum%100)/10; bit4 = (displaynum%10); } else if(displaynum >= 100) { bit1 = 0; bit2 = displaynum/100; bit3 = (displaynum%100)/10; bit4 = (displaynum%10); } else if(displaynum >= 10) { bit1 = 0; bit2 = 0; bit3 = displaynum/10; bit4 = displaynum%10; } if(displaynum < 10) { bit1 = 0; bit2 = 0; bit3 = 0; bit4 = displaynum; } P2 = 0xc0; P0 = 0x01; //bit1 P2 &= 0x3f; P0 = 0xff; P2 = 0xe0; P0 = num[bit1]; P2 &= 0x1f; delayms(5); P2 = 0xc0; P0 = 0x02; //bit2 P2 &= 0x3f; P0 = 0xff; P2 = 0xe0; P0 = num[bit2]; P2 &= 0x1f; delayms(5); P2 = 0xc0; P0 = 0x04; //bit3 P2 &= 0x3f; P0 = 0xff; P2 = 0xe0; P0 = num[bit3]; P2 &= 0x1f; delayms(5); P2 = 0xc0; P0 = 0x08; //bit4 P2 &= 0x3f; P0 = 0xff; P2 = 0xe0; P0 = num[bit4]; P2 &= 0x1f; delayms(5); } void display2(unsigned int displaynum) // 在第一组数码管上显示一个int数据 { unsigned char bit1,bit2,bit3,bit4; if(displaynum >= 10000) { bit1 = 9; bit2 = 9; bit3 = 9; bit4 = 9; } else if(displaynum >= 1000) { bit1 = displaynum/1000; bit2 = (displaynum%1000)/100; bit3 = (displaynum%100)/10; bit4 = (displaynum%10); } else if(displaynum >= 100) { bit1 = 0; bit2 = displaynum/100; bit3 = (displaynum%100)/10; bit4 = (displaynum%10); } else if(displaynum >= 10) { bit1 = 0; bit2 = 0; bit3 = displaynum/10; bit4 = displaynum%10; } if(displaynum < 10) { bit1 = 0; bit2 = 0; bit3 = 0; bit4 = displaynum; } P2 = 0xc0; P0 = 0x10; //bit1 P2 &= 0x3f; P0 = 0xff; P2 = 0xe0; P0 = num[bit1]; P2 &= 0x1f; delayms(5); P2 = 0xc0; P0 = 0x20; //bit2 P2 &= 0x3f; P0 = 0xff; P2 = 0xe0; P0 = num[bit2]; P2 &= 0x1f; delayms(5); P2 = 0xc0; P0 = 0x40; //bit3 P2 &= 0x3f; P0 = 0xff; P2 = 0xe0; P0 = num[bit3]; P2 &= 0x1f; delayms(5); P2 = 0xc0; P0 = 0x80; //bit4 P2 &= 0x3f; P0 = 0xff; P2 = 0xe0; P0 = num[bit4]; P2 &= 0x1f; delayms(5); } void display_reg(int x) //在数码管上显示两个8位寄存器的值,方便调试 { int a,b; if(x == 0) { a = TH0; b = TL0; display1(a); display2(b); } if(x == 1) { a = TH1; b = TL1; display1(a); display2(b); } }
P.S:之前在使用display(thenum)做频率计的时候出现显示乱码的问题 问题出在:用在索引字形码的bitx变量使用了int数据类型,int类型在实际使用时,未被使用的高位用1填充了,如: int a; char tl1; tl1 = TL1; //设TL1 = 0x0d; a = th1; //此时在仿真观察窗口内a = 0xff0d;此时使用num[a]无法索引数据,导致乱码。


4、ULN2003(反相器) 


5、继电器/蜂鸣器
蜂鸣器采用有源蜂鸣器
P2 = 0xa0; //Y5C buzz = 0; //close;open=1 P2 &= 0x5f; P2 = 0xa0; //Y5C relay = 0; //close;open=1 P2 &= 0x5f;