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;