备战蓝桥杯单片机倒数第四天 小蜜蜂老师公众号更新内容

本文主要是介绍备战蓝桥杯单片机倒数第四天 小蜜蜂老师公众号更新内容,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

揽江楼一楼在装修

夜里熬到了两点左右,早上九点多起来,状态比较低迷,有点困的状态持续到了现在14:48,发现小蜜蜂老师的微信公众号进行了一波更新,而且基本上都是凌晨更新的,有被激励到,来了点工作的感觉(其实也是因为迷糊够了醒困了),废话不多说,把相关内容整理整理


目录

【进阶01】灯光闪烁与数码管计数

【进阶02】长按与短按控制数码管显示 

【进阶03】24C02的基本读写操作

【进阶04】24C02存储按键触发次数

【进阶05】采样光敏电阻与可调电阻的电压

【进阶06】基于PCF8591的DAC模拟电压输出 

【特训案例1】基于PCF8591的智能照明控制器 

【特训案例2】DS18B20温度传感器数据采样与显示

【底层驱动代码移植与应用】


【进阶01】灯光闪烁与数码管计数

这个主要是解决LED和数码管冲突问题,对锁存器初始化的写法加上了所有锁存器都不选择的代码,更好的可以避免不同操作之间的影响,并且先将要赋的值送到端口然后在打开锁存器

特训案例【进阶02】长按与短按控制数码管显示

#include "reg52.h"sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L8 = P0^7;
unsigned char led_stat = 0xff;
unsigned char num1 = 0,num2 = 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();                //在延时期间保持数码管刷新}
}void Init_74HC138(unsigned char channel)//主要是在使用之后确定把锁存器关掉了
{switch(channel){case 4:P2 = (P2 & 0x1f) | 0x80;break;//LEDcase 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()
{P0 = 0xff;      Init_74HC138(4);P0 = 0x00;     Init_74HC138(5);SMG_All(0xff); 
}void SMG_Display_Data(void)
{SMG_DisplayBit(0,smg_data[num1]);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[num2/10]);delay(200);SMG_DisplayBit(7,smg_data[num2%10]);delay(200);SMG_All(0xff);delay(200);	
}void Led()
{led_stat &= ~0x80;  //L8电亮P0 = led_stat;Init_74HC138(4);Delay_s(200);   //在进行LED操作的时候也对数码管进行刷新led_stat |= 0x80;   //熄灭P0 = led_stat;Init_74HC138(4);Delay_s(200);value2++;if(value2 == 100){value2 = 0;}//L1 和L2 灯同时翻转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();SMG_Display_Data(); 	}
}

【进阶02】长按与短按控制数码管显示 

之前一直没学长按短按,但是既然小蜜蜂老师写了这个,就学一下,然后看完老师给出的代码恍然大悟,原来就是一个定时器就搞定了呀!这下考到也不担心了

#include "reg52.h"sbit S4 = P3^3;
unsigned char count = 0,press = 0,num =28;	//计时,按键长按标志,数值
unsigned char code smg_data[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};	//段码void delay(unsigned int t)
{while(t--);
}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_All(unsigned char dat)
{	P0 = 0xff;Init_74HC138(6);P0 = dat;Init_74HC138(7);
}void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{P0 = (0x01 << pos);Init_74HC138(6);P0 = dat;Init_74HC138(7);
}void SMG_Display_Data()
{SMG_DisplayBit(6,smg_data[value/10]);delay(200);SMG_DisplayBit(6,0xff);delay(200);SMG_DisplayBit(7,smg_data[value%10]);delay(200);SMG_DisplayBit(7,0xff);SMG_All(0xff);delay(200);
}void Init_System(void)
{P0 = 0xff;Init_74HC138(4);P0 = 0x00;Init_74HC138(5);SMG_All(0xff);
}void Scan_Keys()
{if(S4 == 0){delay(1000);      //去抖动处理if(S4 == 0)          //确认为按下信号{count = 0;      //时间计数变量清0press = 1;        //标志按键按下状态while(S4 == 0)    //等待按键松开{SMG_Display_Data();  //在按下期间保持数码管正常显示}press = 0;        //标志按键松开状态if(count > 100)  //按下时间大于1秒,长按{num = 0;        //数码管计数清除为00}else              //按下时间小于1秒,短按{num++;          //数码管计数加1if(num == 100){num = 0;      //计数超出最大值99后恢复00}}}}
}void Init_Timer()
{TMOD = 0x01;TH0  =(65535-10000)/256;	//10msTL0  =(65535-10000)%256;ET0  = 1;TR0  = 1;EA   = 1;
}void main(void)
{Init_System();Init_Timer();while(1){Scan_Keys();SMG_Display_Data();}
}void Server_Timer0() interrupt 1
{TH0 = (65535-10000)/256;TL0 = (65535-10000)%256;if(press==1){count++;}
}

 【进阶03】24C02的基本读写操作

#include "reg52.h"
#include "iic.h"unsigned char dat1=0,dat2=0,dat3=0;
unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90};void delay(unsigned int t)
{while(t--);
}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;
}void SMG_DisplayBit(unsigned char pos,unsigned char dat)
{P0 = (0x01 << pos);Init_74HC138(6);P0 = dat;Init_74HC138(7);
}void SMG_Close()
{P0 = 0xff;Init_74HC138(6);P0 = 0xff;Init_74HC138(7);
}void Init_System()
{Init_74HC138(0);P0 = 0x00;Init_74HC138(5);P0 = 0xff;Init_74HC138(4);
}void SMG_Display_Data()
{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);
}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();       //停止信号
}//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;
}
ATC02读取与写入
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();}
}

【进阶04】24C02存储按键触发次数

#include "iic.h"
#include "reg52.h"sbit S6 = P3^1;
sbit S5 = P3^2;
sbit S4 = P3^3;unsigned char dat1 = 0,dat2 = 0,dat3 = 0;
unsigned char code smg_data[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90};void delay(unsigned int t)
{while(t--);
}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()
{P0 = 0xff;Init_74HC138(4);P0 = 0x00;Init_74HC138(5);SMG_All(0xff);
}void SMG_Display_Data()
{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_All(0xff);delay(200);
}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();
}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;
}void Read_AT24C02_Init()
{dat1 = 	AT24C02_Read(0x00);delay(1000);dat2 =  AT24C02_Read(0x01);delay(1000);dat3 =  AT24C02_Read(0x02);delay(1000);
}void Key_Scans()
{if(S4 == 0){delay(20);if(S4 == 0){dat1++;if(dat1 > 13){dat1 = 0;}AT24C02_Write(0x00,dat1);}}else if(S5 == 0){delay(20);if(S5 == 0){dat2++;if(dat2 > 13){dat2 = 0;}AT24C02_Write(0x01,dat2);}}if(S6 == 0){delay(20);if(S6 == 0){dat3++;if(dat3 > 13){dat3 = 0;}AT24C02_Write(0x02,dat3);}}				
}void main(void)
{Init_System();Read_AT24C02_Init();while(1){SMG_Display_Data() ;Key_Scans();}
}

 【进阶05】采样光敏电阻与可调电阻的电压

#include "reg52.h"
#include "iic.h"unsigned char adc1_value = 0;    //AIN1的采样数据
float adc1_volt = 0;            //AIN1的换算电压
unsigned int smg1_volt = 0;      //AIN1的显示电压
unsigned char adc3_value = 0;    //AIN3的采样数据
float adc3_volt = 0;            //AIN3的换算电压
unsigned int smg3_volt = 0;      //AIN3的显示电压unsigned char code smg_data[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
unsigned char code smg_data_dot[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};void delay(unsigned int t)
{while(t--);
}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 DisplaySMG_ADC()
{SMG_DisplayBit(0,smg_data_dot[smg1_volt/100]);delay(200);SMG_DisplayBit(0,0xff);delay(200);SMG_DisplayBit(1,smg_data[smg1_volt/10%10]);delay(200);SMG_DisplayBit(1,0xff);delay(200);SMG_DisplayBit(2,smg_data[smg1_volt%10]);delay(200);SMG_DisplayBit(2,0xff);delay(200);SMG_DisplayBit(5,smg_data_dot[smg3_volt/100]);delay(200);SMG_DisplayBit(5,0xff);SMG_DisplayBit(6,smg_data[smg3_volt/10%10]);delay(200);SMG_DisplayBit(6,0xff);delay(200);SMG_DisplayBit(7,smg_data[smg3_volt%10]);delay(200);SMG_DisplayBit(7,0xff);delay(200);SMG_All(0xff);delay(200);
}unsigned char Read_PCF8591_ADC(unsigned char ain)
{unsigned char tmp;IIC_Start();          IIC_SendByte(0x90);    //PCF8591的写设备地址 IIC_WaitAck();        if(ain == 1){IIC_SendByte(0x01); //通道1,光敏电阻电压}else if(ain == 3){IIC_SendByte(0x03); //通道3,可调电阻电压}    IIC_WaitAck();              IIC_Stop(); DisplaySMG_ADC();      //等待电压转换完成IIC_Start();                  IIC_SendByte(0x91);   //PCF8591的读设备地址IIC_WaitAck();                 tmp = IIC_RecByte();   //读出AD采样数据IIC_SendAck(1);         //产生非应答信号                 IIC_Stop();return tmp;
}void Read_AIN1_AIN3()
{adc1_value = Read_PCF8591_ADC(1);adc1_volt = adc1_value * (5.0 / 255);smg1_volt = adc1_volt * 100;adc3_value = Read_PCF8591_ADC(3);adc3_volt = adc3_value * (5.0 / 255);smg3_volt = adc3_volt * 100;
}void Init_System()
{P0 = 0xff;Init_74HC138(4);P0 = 0x00;Init_74HC138(5);SMG_All(0xff);
}void main()
{Init_sys();               //系统初始化while(1){Read_AIN1_AIN3();      //循环采样电压DisplaySMG_ADC();      //动态刷新数码管}
}

【进阶06】基于PCF8591的DAC模拟电压输出 

其实就是一个很简单的数码管、按键和某一个特殊模块的综合

#include "reg52.h"
#include "iic.h"sbit S4 = P3^3;
unsigned char mode = 1; //输出模式
unsigned int volt_value = 0,ad_value = 0;	 //数码管显示电压、采样变量
unsigned char code smg_data[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
unsigned char code smg_data_dot[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};void delay(unsigned int t )
{while(t--);
}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 SMG_Display_Data(void)
{SMG_DisplayBit(0,0xbf);delay(200);SMG_DisplayBit(0,0xff);delay(200);SMG_DisplayBit(1,smg_data[mode]);delay(200);SMG_DisplayBit(1,0xff);delay(200);SMG_DisplayBit(2,0xbf);delay(200);SMG_DisplayBit(2,0xff);delay(200);SMG_DisplayBit(5,smg_data_dot[volt_value/100]);delay(200);SMG_DisplayBit(5,0xff);delay(200);SMG_DisplayBit(6,smg_data[volt_value/10%10]);delay(200);SMG_DisplayBit(6,0xff);delay(200);SMG_DisplayBit(7,smg_data[volt_value%10]);delay(200);SMG_DisplayBit(7,0xff);delay(200);SMG_All(0xff);delay(200);
}	//PCF8591数据读取
void Read_ADC()
{IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(0x43);IIC_WaitAck();IIC_Stop();IIC_Start();IIC_SendByte(0x91);IIC_WaitAck();ad_value = IIC_RecByte();IIC_SendAck(1);IIC_Stop();volt_value = ad_value * (5.0/255)* 100;
}void Read_DAC(float dat)
{IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(0x43);IIC_WaitAck();IIC_SendByte(dat);IIC_WaitAck();IIC_Stop();
}void Init_System()
{P0 = 0xff;Init_74HC138(4);P0 = 0x00;Init_74HC138(5);SMG_All(0xff);
}void Key_Scans()
{if(S4 == 0){delay(20);if(S4 == 0){while(S4 == 0){SMG_Display_Data();}if(mode == 1){mode = 2;Read_DAC(204);volt_value = 4*100;break;}else if(mode == 2){mode = 3;}else if(mode == 3){mode = 1;Read_DAC(102);volt_value = 2*100;}}}
}void main(void)
{Init_System();while(1){Key_Scans();SMG_Display_Data();}
}

【特训案例1】基于PCF8591的智能照明控制器 

#include "reg52.h"
#include "iic.h"sbit S4 = P3^3;
sbit S5 = P3^2;unsigned char code SMG_NoDot[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
unsigned char code SMG_Dot[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
unsigned char adc_value = 0;    //采样数据
float adc_volt = 0;              //换算电压
unsigned int smg_volt = 0;      //显示电压
unsigned char stat_led = 0xff;  //定义LED灯当前状态
unsigned char level = 0;        //灯光控制等级
void delay(unsigned int t )
{while(t--);
}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 SMG_Display_Data()
{SMG_DisplayBit(0,0xbf);delay(200);SMG_DisplayBit(0,0xff);delay(200);SMG_DisplayBit(1,SMG_NoDot[level]);delay(200);SMG_DisplayBit(1,0xff);delay(200);SMG_DisplayBit(2,0xbf);delay(200);SMG_DisplayBit(2,0xff);delay(200);SMG_DisplayBit(5,SMG_Dot[smg_volt / 100]);delay(200);SMG_DisplayBit(5,0xff);delay(200);SMG_DisplayBit(6,SMG_NoDot[(smg_volt / 10) % 10]);delay(200);SMG_DisplayBit(6,0xff);delay(200);SMG_DisplayBit(7,SMG_NoDot[smg_volt  % 10]);delay(200);SMG_DisplayBit(7,0xff);delay(200);SMG_All(0xff);delay(200);
}	
//24C02单字节写入
void Write_24C02(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();            //停止信号
}
//24C02单字节读取
unsigned char Read_24C02(unsigned char addr)
{unsigned char tmp;//首先,进行一个伪写操作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;
}
//PCF8591电压采样处理函数
void Read_PCF8591_AIN1()
{IIC_Start();          IIC_SendByte(0x90);    //PCF8591的写设备地址 IIC_WaitAck();    IIC_SendByte(0x01);   //通道1,光敏电阻电压  IIC_WaitAck();              IIC_Stop(); DisplaySMG_Info();    //等待电压转换完成IIC_Start();                  IIC_SendByte(0x91);   //PCF8591的读设备地址IIC_WaitAck();                 adc_value = IIC_RecByte(); //读出AD采样数据IIC_SendAck(1);         //产生非应答信号                 IIC_Stop();//将ADC采样到的数据换算成对应的电压值adc_volt = adc_value * (5.0 / 255);smg_volt = adc_volt * 100;SMG_Display_Data();
}
//照明自动控制函数
void LED_Auto_Control()
{Read_PCF8591_AIN1();  //获取当前光照电压if(adc_volt > 4.0){stat_led = 0xfe;    //L1点亮level = 1;    }else if(adc_volt > 3.0){stat_led = 0xfc;    //L1至L2点亮level = 2;  }else if(adc_volt > 2.0){stat_led = 0xf0;    //L1至L4点亮level = 3;}else if(adc_volt > 1.0){stat_led = 0xc0;    //L1至L6点亮level = 4;}else{stat_led = 0x00;    //L1至L8点亮level = 5;}P0 = stat_led;        //更新灯光控制数据Init_74HC138(4);        //控制LED灯
}
//保存当前控制数据
void Save_to_24C02()
{Write_24C02(0x01, level);DisplaySMG_Info();Write_24C02(0x02, adc_value);DisplaySMG_Info();
}
//读取历史控制数据
void Read_from_24C02()
{level = Read_24C02(0x01);adc_value = Read_24C02(0x02);adc_volt = adc_value * (5.0 / 255);smg_volt = adc_volt * 100;
}
//独立按键扫描处理
void Scan_Keys()
{//按键S4的扫描处理if(S4 == 0){delay(100);          //去抖动if(S4 == 0){Save_to_24C02();      //保存当前数据while(S4 == 0)        //松手检测{SMG_Display_Data();  }}}//按键S5的扫描处理if(S5 == 0){delay(100);          //去抖动if(S5 == 0){P0 = 0xff;Init_74HC138(4);        //关闭全部灯光Read_from_24C02();    //读取历史数据        while(S5 == 0)        //松手检测{SMG_Display_Data();  //显示历史数据}}}
}void Init_System()
{P0 = 0xff;Init_74HC138(4);P0 = 0x00;Init_74HC138(5);SMG_All(0xff);
}//主函数
void main()
{Init_System();                //系统初始化        while(1){Scan_Keys();            //扫描按键LED_Auto_Control();      //照明自动控制}
}

【特训案例2】DS18B20温度传感器数据采样与显示

若提供的DS18B20底层驱动的头文件是基于12T89C52运行环境,则需要将底层驱动文件中的延时参数放大10倍

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{while(t--);
}
可修改为://单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{unsigned int n;          //新定义一个延时参数n = t * 10;              //放大10倍延时参数while(n--);
}
#include "reg52.h"
#include "onewire.h"unsigned char code SMG_NoDot[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f};
unsigned char code SMG_Dot[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
float temp_ds18b20 = 0;          //实际温度值
unsigned int smg_ds18b20 = 0;    //数码管显示温度值
void delay(unsigned int t )
{while(t--);
}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 Read_Dsiplay_DS18B20()
{if(smg_ds18b20>99){SMG_DisplayBit(5,SMG_NoDot[smg_ds18b20 / 100]);        delay(500);SMG_DisplayBit(5,0xff);    //消隐}SMG_DisplayBit(6,SMG_Dot[(smg_ds18b20 / 10) % 10]);delay(200);SMG_DisplayBit(6,0xff);delay(200);SMG_DisplayBit(7,SMG_NoDot[smg_ds18b20  % 10]);delay(200);SMG_DisplayBit(7,0xff);delay(200);SMG_All(0xff);delay(200);
}	//==============DS18B20温度读出与显示==============
void Read_Dsiplay_DS18B20()
{unsigned char LSB,MSB;      unsigned int temp = 0;      init_ds18b20();              //初始化DS18B20Write_DS18B20(0xcc);        //忽略ROM操作Write_DS18B20(0x44);        //启动温度转换DisplaySMG_Temp();init_ds18b20();              //初始化DS18B20Write_DS18B20(0xcc);        //忽略ROM操作Write_DS18B20(0xbe);        //读出内部存储器LSB = Read_DS18B20();        //第0字节:温度低8位MSB = Read_DS18B20();        //第1字节:温度高8位init_ds18b20();              //初始化,停止读取temp = MSB;                  //合成16位温度原始数据temp = (temp << 8) | LSB;if((temp & 0xf800) == 0x0000)    //处理正温度{temp_ds18b20 = temp * 0.0625;  //计算实际温度值}smg_ds18b20 = temp_ds18b20 * 10;DisplaySMG_Temp();
}void Init_System()
{P0 = 0xff;Init_74HC138(4);P0 = 0x00;Init_74HC138(5);SMG_All(0xff);
}void main()
{Init_System();  while(1){Read_Dsiplay_DS18B20();}
}

【底层驱动代码移植与应用】

  • DS18B20的单总线底层驱动代码:若提供的是52的,需要将时序*10,但要注意到底需要不需要进行修改

bit init_ds18b20(void)
{bit initflag = 0;DQ = 1;Delay_OneWire(12);DQ = 0;Delay_OneWire(80);DQ = 1;Delay_OneWire(10); initflag = DQ;     Delay_OneWire(5);return initflag;
}时序修正后,该复位函数的代码是:bit init_ds18b20(void)
{bit initflag = 0;DQ = 1;Delay_OneWire(120);DQ = 0;Delay_OneWire(800);DQ = 1;Delay_OneWire(100); initflag = DQ;     Delay_OneWire(50);return initflag;
}
  • 确认头文件是否完整

这篇关于备战蓝桥杯单片机倒数第四天 小蜜蜂老师公众号更新内容的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500035

相关文章

Redis缓存问题与缓存更新机制详解

《Redis缓存问题与缓存更新机制详解》本文主要介绍了缓存问题及其解决方案,包括缓存穿透、缓存击穿、缓存雪崩等问题的成因以及相应的预防和解决方法,同时,还详细探讨了缓存更新机制,包括不同情况下的缓存更... 目录一、缓存问题1.1 缓存穿透1.1.1 问题来源1.1.2 解决方案1.2 缓存击穿1.2.1

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

SpringCloud配置动态更新原理解析

《SpringCloud配置动态更新原理解析》在微服务架构的浩瀚星海中,服务配置的动态更新如同魔法一般,能够让应用在不重启的情况下,实时响应配置的变更,SpringCloud作为微服务架构中的佼佼者,... 目录一、SpringBoot、Cloud配置的读取二、SpringCloud配置动态刷新三、更新@R

Ubuntu 24.04 LTS怎么关闭 Ubuntu Pro 更新提示弹窗?

《Ubuntu24.04LTS怎么关闭UbuntuPro更新提示弹窗?》Ubuntu每次开机都会弹窗提示安全更新,设置里最多只能取消自动下载,自动更新,但无法做到直接让自动更新的弹窗不出现,... 如果你正在使用 Ubuntu 24.04 LTS,可能会注意到——在使用「软件更新器」或运行 APT 命令时,

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

hdu 1754 I Hate It(线段树,单点更新,区间最值)

题意是求一个线段中的最大数。 线段树的模板题,试用了一下交大的模板。效率有点略低。 代码: #include <stdio.h>#include <string.h>#define TREE_SIZE (1 << (20))//const int TREE_SIZE = 200000 + 10;int max(int a, int b){return a > b ? a :

AI行业应用(不定期更新)

ChatPDF 可以让你上传一个 PDF 文件,然后针对这个 PDF 进行小结和提问。你可以把各种各样你要研究的分析报告交给它,快速获取到想要知道的信息。https://www.chatpdf.com/

GIS图形库更新2024.8.4-9.9

更多精彩内容请访问 dt.sim3d.cn ,关注公众号【sky的数孪技术】,技术交流、源码下载请添加微信:digital_twin123 Cesium 本期发布了1.121 版本。重大新闻,Cesium被Bentley收购。 ✨ 功能和改进 默认启用 MSAA,采样 4 次。若要关闭 MSAA,则可以设置scene.msaaSamples = 1。但是通过比较,发现并没有多大改善。