【蓝桥杯单片机】小蜜蜂老师—工厂灯光控制系统代码(IO模式)

本文档展示了一个使用单片机实现的数码管显示和串口通信程序,包括定时器初始化、串口初始化、数码管显示、按键扫描和串口数据解析等功能。代码中结合了多位博主的思路,实现了时间显示和外部设备的控制,并通过串口接收上位机命令。程序还包括了系统初始化、LED灯测试和数码管测试等步骤,以确保硬件正确工作。
摘要由CSDN通过智能技术生成

【本代码定时器与串口部分的初始化函数均由ISP自动生成。】

本代码参考多位csdn博主,进行融汇修改,可自行烧录查看。

#include"reg52.h"

unsigned char code SMG_duanma[18] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};  //记得最后有;	


sfr AUXR = 0x8e; //辅助寄存器
sbit S5 = P3^2;//定义按键S5引脚
sbit S4 = P3^3;//定义按键S4引脚


void InitSys();  //系统初始化,关闭无关设备
void Timer0Init(); //定时器初始化
void UartInit();//串口初始化

void LED_Check();//LED灯测试
void SMG_Check();//数码管测试

void SMG_Bit(unsigned char value,unsigned char pos); //数码管显示指定数据
void SMG_Display();//时间显示
void SendData(unsigned char dat); //单字节发送数据
void ExecuteCommand();  //数据解析函数

void HC573(unsigned char n); //寄存器选择
void Delay_SW(unsigned char t);
void Delay_SMG(unsigned int t);
void Delay_LED(unsigned int t); //延时函数
void ScanKeys(); //按键扫描



//========================================锁存器选择函数=====================================
void HC573(unsigned char n)
{
	switch(n)
	{
		case 4: P2 = (P2 & 0x1f) | 0x80; break;
		case 5: P2 = (P2 & 0x1f) | 0xa0; break;
		case 6: P2 = (P2 & 0x1f) | 0xc0; break;
		case 7: P2 = (P2 & 0x1f) | 0xe0; break;
		case 0: P2 = (P2 & 0x1f) | 0x00; break;	  //所有锁存器不选择
	}
}

//========================================定时器T0初始化函数==================================
void Timer0Init(void)		//50毫秒@11.0592MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x00;		//设置定时初始值
	TH0 = 0x4C;		//设置定时初始值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	//以上由ISP生成
	
	ET0 = 1;
	EA = 1;
}

//========================================定时器T0中断服务函数================================
unsigned char t_h = 0;
unsigned char t_m = 0;
unsigned char t_s = 0;

unsigned char count = 0;

void ServiceTime0() interrupt 1
{
	TH0 = (65535 - 50000) / 256;	//50000脉冲对应50ms
	TL0 = (65535 - 50000) % 256;

	count++;
	if(count == 20)  //50000*20=1000000脉冲对应1000ms即1s
	{
		count = 0;
		t_s++;
	}
	if(t_s == 60)
	{
		t_m++;
		t_s = 0;
		if(t_m == 60)
		{
			t_h++;
			t_m = 0;
		}
	}
}

//========================================串口初始化函数======================================
void UartInit(void)		//9600bps@11.0592MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器时钟1T模式
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xE0;		//设置定时初始值
	TH1 = 0xFE;		//设置定时初始值
	ET1 = 0;		//禁止定时器%d中断
	TR1 = 1;		//定时器1开始计时
	//以上由ISP生成

	ES = 1;
	EA = 1;
}
//========================================串口发送单字节函数==================================
void SendData(unsigned char dat)
{
	SBUF = dat;
	while(TI == 0);
	TI = 0;
}

//========================================串口中断服务函数====================================
unsigned char command = 0;	//!!!!串口命令字接受变量
void ServiceUart() interrupt 4
{
	if (RI)
    {
		//改成
		command = SBUF;
		RI = 0;
		
		/*
		RI = 0;                 //清除RI位
		P0 = SBUF;              //P0显示串口数据
        P22 = RB8;              //P2.2显示校验位
		*/
        //以上由ISP生成
    }
    /*
	if (TI)
    {
        TI = 0;                 //清除TI位
        busy = 0;               //清忙标志
    }
	*/
    //以上由ISP生成
}

//========================================上位机命令执行解析函数==============================
unsigned char stat_led = 0xff;  
void ExecuteCommand()
{
	if(command)
	{
		switch(command & 0xf0)
		{
			case 0xa0:
				HC573(4);
				stat_led = (stat_led | 0x0f) & (~command | 0xf0);  //(stat_led | 0x0f):保持高四位状态不变
				P0 = stat_led;
				HC573(0);
				command = 0x00;                    //清零
			break;

			case 0xb0:
				SendData((t_h / 10 << 4)|(t_h % 10));
				SendData((t_m / 10 << 4)|(t_m % 10));
				SendData((t_s / 10 << 4)|(t_s % 10));
				command = 0x00;		//清零
			break;
		}
	}
}
//========================================独立按键扫描函数====================================
void Delay_SW(unsigned char t)
{
	while(t--);
}

void ScanKeys() 
{
	if (S5 == 0)//按键S5控制L7
	{
		Delay_SW(100);
		if (S5 == 0)
		{
			while(S5 == 0) //等待按键S5松开(没有结束,不能空等待)
			{
				SMG_Display();//等待的同时不断刷新数码管
			}
			HC573(4);
			stat_led = (stat_led | 0x40) & (~stat_led | 0xbf);
			P0 = stat_led;// (1111 1111 | 0100 000)&(0000 0000 | 1011 1111)
			HC573(0); //        1011 1111 & 1011 1111 = 1011 1111(S7亮)
		}
	}
	if (S4 == 0)//按键S5控制L7
	{
		Delay_SW(100);
		if (S4 == 0)
		{
			while(S4 == 0) //等待按键S5松开(没有结束,不能空等待)
			{
				SMG_Display();//等待的同时不断刷新数码管
			}
			HC573(4);
			stat_led = (stat_led | 0x80) & (~stat_led | 0x7f);
			P0 = stat_led;// (1111 1111 | 1000 000)&(0000 0000 | 0111 1111)
			HC573(0); //        0111 1111 & 0111 1111 = 0111 1111(S8亮)
		}
	}
}
//========================================LED检测=============================================
void Delay_LED(unsigned int t)	  //是int!!!!!!char会特别快
{
	while(t--);
	while(t--);       
}

unsigned int i = 0;
void LED_Check()
{
	HC573(4);
	for(i = 1; i <= 8; i++)	   //i=1开始 且i <= 8
	{
		P0 = 0xff << i;		  //0xff
		Delay_LED(60000);
		Delay_LED(60000);  
	}
	for(i = 1; i <= 8; i++)
	{					
		P0 = ~(0xff << i);		
		Delay_LED(60000);
		Delay_LED(60000); 
	}
	HC573(0);
}


//========================================时间显示模块检测函数================================

void Delay_SMG(unsigned int t)
{
	while(t--);
}

void SMG_Bit(unsigned char value,unsigned char pos)
{
	HC573(7);  
	P0 = 0xff;
	HC573(6);
	P0 = 0x01 << pos;
	HC573(7);
	P0 = value;
}

void SMG_Check()
{	
	HC573(7);
	P0 = 0x00;
	for(i = 0; i < 8; i++)
	{
		HC573(6);
		P0 = ~(0xff << i);
		Delay_SMG(60000);
		Delay_SMG(60000);
		Delay_SMG(60000);
	}	
	for(i = 0; i < 8; i++)
	{
		HC573(6);
		P0 = 0xff << i;
		Delay_SMG(60000);
		Delay_SMG(60000);
		Delay_SMG(60000);
	}
	HC573(0);	 //!!
}
//========================================系统显示时间========================================
void SMG_Display()
{
	SMG_Bit(SMG_duanma[t_h/10],0);
	Delay_SMG(600);
	SMG_Bit(SMG_duanma[t_h%10],1);
	Delay_SMG(600);

	SMG_Bit(SMG_duanma[16],2);
	Delay_SMG(600);

	SMG_Bit(SMG_duanma[t_m/10],3);
	Delay_SMG(600);
	SMG_Bit(SMG_duanma[t_m%10],4);
	Delay_SMG(600);

	SMG_Bit(SMG_duanma[16],5);
	Delay_SMG(600);

	SMG_Bit(SMG_duanma[t_s/10],6);
	Delay_SMG(600);
	SMG_Bit(SMG_duanma[t_s%10],7);
	Delay_SMG(600);
}



//========================================系统初始化函数======================================
void InitSys()
{
	HC573(5);
	P0 = 0x00;
	HC573(4);
	P0 = 0xff;
	HC573(0);
}


//========================================主函数===============================================
void main()
{
	InitSys();
	LED_Check();
	SMG_Check();
	Timer0Init();
	UartInit();
	while(1)
	{
		ExecuteCommand();
		SMG_Display();
		ScanKeys();
	}
}

详细注释下述代码:#include <reg52.h> #include <onewire.h> unsigned char duanma[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; unsigned char duanma_x[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; unsigned int temp=0; unsigned int temp_h=0; unsigned int temp_l=30; void Delay_SMG(unsigned int t) { while(t--); } void SelectHC573(unsigned char n) { switch(n) { case 0 : P2 = (P2 & 0x1f ) | 0x00; break; case 4 : P2 = (P2 & 0x1f ) | 0x80; break; case 5 : P2 = (P2 & 0x1f ) | 0xa0; break; case 6 : P2 = (P2 & 0x1f ) | 0xc0; break; case 7 : P2 = (P2 & 0x1f ) | 0xe0; break; } } void DisplaySMG_Bit(unsigned char pos,unsigned char dat) { P2=0xE0;P0=0xff;//先全部关掉数码管,避免显示不正常 P2=0xC0;P0=0x01<<pos; P2=0xE0;P0=dat; } void DisplaySMG_temp() { DisplaySMG_Bit(1,duanma[temp%10]); Delay_SMG(100); DisplaySMG_Bit(0,duanma[temp/10]); //第0位和第1位显示温度 Delay_SMG(100); DisplaySMG_Bit(5,0xbf); Delay_SMG(100); DisplaySMG_Bit(7,duanma[temp_l%10]); Delay_SMG(100); DisplaySMG_Bit(6,duanma[temp_l/10]); Delay_SMG(100); DisplaySMG_Bit(2,0xbf); Delay_SMG(100); DisplaySMG_Bit(4,duanma[temp_h%10]); Delay_SMG(100); DisplaySMG_Bit(3,duanma[temp_h/10]); Delay_SMG(100); P2=0xC0;P0=0xff; P2=0xE0;P0=0xff; } void Delay(unsigned int t) { while(t--) { DisplaySMG_temp(); } } void Read_DS18B20_temp() { unsigned char LSB,MSB; init_ds18b20(); Write_DS18B20(0xcc); Write_DS18B20(0x44); Delay(1000); init_ds18b20(); Write_DS18B20(0xcc); Write_DS18B20(0xbe); LSB=Read_DS18B20(); MSB=Read_DS18B20(); temp=MSB; temp=(temp<<8)|LSB; temp>>=4; } void open_buzz() { P0|=0x40; SelectHC573(5); SelectHC573(0); } void close_buzz() { P0&=0xbf; SelectHC573(5); SelectHC573(0); } void main() { P2=0x80;P0=0xff; while(1) { Read_DS18B20_temp(); if(temp>temp_h) { temp_h=temp; } if(temp_l>temp) { temp_l=temp; } if(temp>=30) { open_buzz(); }else if(temp<30) { close_buzz(); } DisplaySMG_temp(); } }
05-30
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值