第十三届蓝桥杯单片机省赛冲刺-巩固练习
下面内容来自小蜜蜂老师公众号更新内容 , 讲了AT24C02 、PCF8591、以及led和数码管冲突问题 , 在更新的内容中小蜜蜂老师换了之前对锁存器初始化的写法 , 主要是加了一句所有锁存器都不选择的代码 , 更好的可以避免不同操作之间的影响 , 其次在进行锁存器操作端口赋值的时候也换了写法 , 之前是先选择要操作的锁存器后再进行赋值 , 现在是先将要赋的值送到端口然后在打开锁存器 。【【第十三届蓝桥杯单片机省赛冲刺-巩固练习重点】】
小蜜蜂老师操作总结 yyds在编程中应该把握的原则是 , P0端口的数据只送到目标外设 。我的一个经验是:在上电初始化完成时 , 把所有外设连接的锁存器关闭;在需要对目标外设传输数据时 , 先把数据送到P0端口 , 然后再打开外设对应的锁存器 , 用完马关闭锁存器 。保证在不需要的时候P0端口的变化不影响任何外设 , 在需要控制时 , 外设只接收正确的信息
一、灯闪烁与数码管计数#include "reg52.h"sbit LED1 = P0^0;sbit LED2 = P0^1;sbit LED8 = P0^7;unsigned char led_stat = 0xff;unsigned char value1 = 0,value2 = 0;unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90};void SMG_Display_Data(void);//1.简单延时void delay(unsigned int t){while(t--);}void Delay_s(unsigned int t){while(t--){SMG_Display_Data();//在延时期间保持数码管刷新}}//2.锁存器初始化void Init_74HC138(unsigned char channel){switch(channel) {case 4:P2 = (P2 & 0x1f) | 0x80;break;//Y4输出0 , LED控制case 5:P2 = (P2 & 0x1f) | 0xa0;break;//Y5输出0 , 蜂鸣器和继电器控制case 6:P2 = (P2 & 0x1f) | 0xc0;break; //Y6输出0 , 数码管位选case 7:P2 = (P2 & 0x1f) | 0xe0;break;//Y7输出0 , 数码管段码case 0:P2 = (P2 & 0x1f) | 0x00;break;//所有锁存器不选择 }P2 = (P2 & 0x1f) | 0x00;//所有锁存器不选择}//3.数码管安位操作void SMG_DisplayBit(unsigned char pos,unsigned char dat){P0 = (0x01 << pos); //数码管的段位 Init_74HC138(6); P0 = dat;//数码管显示内容 Init_74HC138(7);}//4.操作所有数码管void SMG_All(unsigned char dat){P0 = 0xff;//数码管的段位 Init_74HC138(6); P0 = dat;//数码管显示内容 Init_74HC138(7);}//5.系统初始化void Init_System(void){P0 = 0xff;//关闭所有led Init_74HC138(4); P0 = 0x00;//关闭蜂鸣器和继电器 Init_74HC138(5); SMG_All(0xff); //关闭所有数码管}//6.数码管数据显示void SMG_Display_Data(void){ SMG_DisplayBit(0,smg_data[value1]); delay(200); SMG_DisplayBit(1,0xff); delay(200); SMG_DisplayBit(2,0xff); delay(200); SMG_DisplayBit(3,0xff); delay(200); SMG_DisplayBit(4,0xff); delay(200); SMG_DisplayBit(5,0xff); delay(200); SMG_DisplayBit(6,smg_data[value2/10]); delay(200); SMG_DisplayBit(7,smg_data[value2%10]); delay(200); SMG_All(0xff); delay(200); }//7.led操作void Led_Tackle(void){led_stat &= ~0x80;//led8电亮 P0 = led_stat; Init_74HC138(4); Delay_s(200); led_stat |= 0x80;//熄灭 P0 = led_stat; Init_74HC138(4); Delay_s(200); value2++; if(value2 == 100) {value2 = 0; } //led1 和led2 灯同时翻转 if((led_stat & 0x03) == 0x03) {led_stat &= ~0x03; } else {led_stat |= 0x03; } P0 = led_stat; Init_74HC138(4); value1++; if(value1 > 9) {value1 = 0; } }void main(void){ Init_System(); while(1) {Led_Tackle();SMG_Display_Data();}} 注意在这个代码中需要我们注意的是 , 在进行led操作函数中我们进行延时的时候也要进行数码管的刷新显示 , 第一次写就只是简单延时没有进行数码管的刷新显示 , 结果就是数码管一直在跳led没有闪烁变化 , 在延时函数中加上数码管动态显示后就可以了 。
二、24C02基本读写操作#include "reg52.h"#include "iic.h"unsigned char dat1,dat2,dat3;unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90};//1.简单延时void delay(unsigned int t){while(t--);}//2.锁存器操作void Init_74HC138(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; } P2 = (P2 & 0x1f) | 0x00;}//3.数码管安位操作void SMG_DisplayBit(unsigned char pos,unsigned char dat){ P0 = (0x01 << pos); Init_74HC138(6); P0 = dat; Init_74HC138(7);}//关闭所有数码管void SMG_Close(void){P0 = 0xff; Init_74HC138(6); P0 = 0xff; Init_74HC138(7);}//4.系统初始化void Init_System(void){ Init_74HC138(0);P0 = 0x00; Init_74HC138(5); P0 = 0xff; Init_74HC138(4);}//5.数码管数据显示void SMG_Display_Data(void){SMG_DisplayBit(0,smg_data[dat1/10]); delay(200); SMG_DisplayBit(1,smg_data[dat1%10]); delay(200); SMG_DisplayBit(2,0xbf); delay(200); SMG_DisplayBit(3,smg_data[dat2/10]); delay(200); SMG_DisplayBit(4,smg_data[dat2%10]); delay(200); SMG_DisplayBit(5,0xbf); delay(200); SMG_DisplayBit(6,smg_data[dat3/10]); delay(200); SMG_DisplayBit(7,smg_data[dat3%10]); delay(200); SMG_Close(); delay(200);}//6.at24c02数据写void AT24C02_Write(unsigned char addr,unsigned char dat){IIC_Start();//起始信号 IIC_SendByte(0xa0);//EEPROM的写设备地址 IIC_WaitAck();//等待从机应答 IIC_SendByte(addr);//内存单元地址 IIC_WaitAck();//等待从机应答 IIC_SendByte(dat);//内存写入数据 IIC_WaitAck();//等待从机应答 IIC_Stop();//停止信号}//7.at24c02数据读unsigned char AT24C02_Read(unsigned char addr){unsigned char tmp = 0;//首先 , 进行一个伪写操作IIC_Start();//起始信号IIC_SendByte(0xa0);//EEPROM的写设备地址IIC_WaitAck();//等待从机应答IIC_SendByte(addr);//内存单元地址IIC_WaitAck();//等待从机应答//然后 , 开始字节读操作IIC_Start();//起始信号IIC_SendByte(0xa1);//EEPROM的读设备地址IIC_WaitAck();//等待从机应答tmp = IIC_RecByte();//读取内存中的数据IIC_SendAck(1);//产生非应答信号IIC_Stop();//停止信号return tmp;}//8.数据处理void Read_Write_Data(void){//先读取数据 dat1 =AT24C02_Read(0x01); dat2 =AT24C02_Read(0x03); dat3 =AT24C02_Read(0x05); dat1= dat1 +1; dat2= dat2 +2; dat3= dat3 + 3 ; if( dat1 > 10) {dat1 = 0; } if(dat2> 20) {dat2 = 0; } if(dat3> 30) {dat3 = 0; } //将数据写回去 AT24C02_Write(0x01,dat1); delay(1000); AT24C02_Write(0x03,dat2); delay(1000); AT24C02_Write(0x05,dat3); delay(1000);}void main(void){Init_System(); Read_Write_Data(); while(1) {SMG_Display_Data(); }} 三、24C02存储按键触发次数#include "iic.h"#include "reg52.h"sbit S6 = P3^1;sbit S5 = P3^2;sbit S4 = P3^3;unsigned char s4_value = https://tazarkount.com/read/0,s5_value = 0,s6_value = 0;unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90};//1.简单延时void delay(unsigned int t){while(t--);}//2.锁存器初始化void Init_74HC138(unsigned char channel){switch(channel) {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; } P2 = (P2 & 0x1f) | 0x00;}//3.数码管安位操作void SMG_DisplayBit(unsigned char pos,unsigned char dat){P0 = (0x01 << pos); Init_74HC138(6); P0 = dat; Init_74HC138(7);}//4.操作所有数码管void SMG_All(unsigned char dat){P0 = 0xff; Init_74HC138(6); P0 = dat; Init_74HC138(7);}//5.系统初始化void Init_System(void){P0 = 0xff; Init_74HC138(4); P0 = 0x00; Init_74HC138(5); SMG_All(0xff);}//6.数码管显示数据void SMG_Display_Data(void){SMG_DisplayBit(0,smg_data[s4_value/10]); delay(200); SMG_DisplayBit(1,smg_data[s4_value%10]); delay(200); SMG_DisplayBit(2,0xbf); delay(200); SMG_DisplayBit(3,smg_data[s5_value/10]); delay(200); SMG_DisplayBit(4,smg_data[s5_value%10]); delay(200); SMG_DisplayBit(5,0xbf); delay(200); SMG_DisplayBit(6,smg_data[s6_value/10]); delay(200); SMG_DisplayBit(7,smg_data[s6_value%10]); delay(200); SMG_All(0xff); delay(200);}//7.at24c02写数据void AT24C02_Write(unsigned char addr,unsigned char dat){IIC_Start(); IIC_SendByte(0x90); IIC_WaitAck(); IIC_SendByte(addr); IIC_WaitAck(); IIC_SendByte(dat); IIC_WaitAck(); IIC_Stop();}//8.at24c04读数据unsigned char AT24C02_Read(unsigned char addr){ unsigned char temp = 0; IIC_Start(); IIC_SendByte(0x90); IIC_WaitAck(); IIC_SendByte(addr); IIC_WaitAck(); IIC_Start(); IIC_SendByte(0x91); IIC_WaitAck(); temp = IIC_RecByte(); IIC_SendAck(1); IIC_Stop(); return temp;}//9.系统上电后 , 先从24C04存储器的0x00、0x01和0x02这三个地址单元读取数据void AT24C02_Data_Init(void){s4_value =AT24C02_Read(0x00); delay(1000); s5_value =AT24C02_Read(0x01); delay(1000); s6_value =AT24C02_Read(0x02); delay(1000);}//10.按键控制void Key_Scans(void){ if(S4 == 0) {delay(20);if(S4 == 0){while(S4 == 0);s4_value++;if(s4_value> 13){s4_value = https://tazarkount.com/read/0;}AT24C02_Write(0x00,s4_value);} }if(S5 == 0) {delay(20);if(S5 == 0){while(S5 == 0);s5_value++;if(s5_value> 13){s5_value = https://tazarkount.com/read/0;}AT24C02_Write(0x01,s5_value);}}if(S6 == 0) {delay(20);if(S6 == 0){while(S6 == 0);s6_value++;if(s6_value> 13){s6_value = https://tazarkount.com/read/0;}AT24C02_Write(0x02,s6_value);} }}void main(void){ Init_System(); AT24C02_Data_Init(); while(1) {SMG_Display_Data() ;Key_Scans(); }} 四、采样可变电阻电压与光敏电阻电压#include "iic.h"#include "reg52.h"sbit S4 = P3^3;unsigned char channel = 1;unsigned int adc_value = https://tazarkount.com/read/0,adc_volt = 0;unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90};unsigned char code smg_dot[] ={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//1.简单延时void delay(unsigned int t){while(t--);}//2.锁存器初始化void Init_74HC138(unsigned char channel){switch(channel) {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; }P2 = (P2 & 0x1f) | 0x00;}//数码管安位操作void SMG_DisplayBit(unsigned char pos,unsigned char dat){P0 = (0x01 << pos); Init_74HC138(6); P0 = dat; Init_74HC138(7);}//操作所有数码管void SMG_All(unsigned char dat){P0 = 0xff; Init_74HC138(6); P0 = dat; Init_74HC138(7);}//系统初始化void Init_System(void){P0 = 0xff; Init_74HC138(4); P0 = 0x00; Init_74HC138(5); SMG_All(0xff);}//数码管数据显示void SMG_Display_Data(void){SMG_DisplayBit(0,0xbf); delay(200); SMG_DisplayBit(1,smg_data[channel]); delay(200); SMG_DisplayBit(2,0xbf); delay(200); SMG_DisplayBit(3,0xff); delay(200); SMG_DisplayBit(4,0xff); delay(200); SMG_DisplayBit(5,smg_dot[adc_volt/100]); delay(200); SMG_DisplayBit(6,smg_data[adc_volt/10%10]); delay(200); SMG_DisplayBit(7,smg_data[adc_volt%10]); delay(200); SMG_All(0xff); delay(200);}//PCF8591数据读取void PCF8591_Read_Data(unsigned char channel){ IIC_Start(); IIC_SendByte(0x90); IIC_WaitAck(); if(channel == 1) {IIC_SendByte(0x01);} else if(channel == 3) {IIC_SendByte(0x03);} IIC_WaitAck(); IIC_Stop(); IIC_Start(); IIC_SendByte(0x91); IIC_WaitAck(); adc_value = IIC_RecByte(); IIC_SendAck(1); IIC_Stop(); adc_volt = adc_value * (5.0/255)*100;//扩大100倍方便显示}//按键操作void Key_Tackle(void){if(S4 == 0) {delay(20);if(S4 == 0){while(S4 == 0){if(channel == 1){channel = 3;}else if(channel == 3){channel = 1;}PCF8591_Read_Data(channel);SMG_Display_Data();}} }}//主函数void main(void){Init_System();while(1) {Key_Tackle();PCF8591_Read_Data(channel);SMG_Display_Data(); }} 加油- 春季老年人吃什么养肝?土豆、米饭换着吃
- 三八妇女节节日祝福分享 三八妇女节节日语录
- 老人谨慎!选好你的“第三只脚”
- 校方进行了深刻的反思 青岛一大学生坠亡校方整改校规
- 脸皮厚的人长寿!有这特征的老人最长寿
- 长寿秘诀:记住这10大妙招 100%增寿
- 春季老年人心血管病高发 3条保命要诀
- 眼睛花不花要看四十八 老年人怎样延缓老花眼
- 香槟然能防治老年痴呆症? 一天三杯它人到90不痴呆
- 老人手抖的原因 为什么老人手会抖
