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

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

用sbit声明某一个端口

sbit LED = P1^0;


2、74HC573(锁存器)

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

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

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;


你可能感兴趣的:(蓝桥杯单片机组,单片机,蓝桥杯)