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

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

揽江楼一楼在装修

夜里熬到了两点左右,早上九点多起来,状态比较低迷,有点困的状态持续到了现在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

相关文章

Java如何将文件内容转换为MD5哈希值

《Java如何将文件内容转换为MD5哈希值》:本文主要介绍Java如何将文件内容转换为MD5哈希值的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java文件内容转换为MD5哈希值一个完整的Java示例代码代码解释注意事项总结Java文件内容转换为MD5

使用Python自动化生成PPT并结合LLM生成内容的代码解析

《使用Python自动化生成PPT并结合LLM生成内容的代码解析》PowerPoint是常用的文档工具,但手动设计和排版耗时耗力,本文将展示如何通过Python自动化提取PPT样式并生成新PPT,同时... 目录核心代码解析1. 提取 PPT 样式到 jsON关键步骤:代码片段:2. 应用 JSON 样式到

Oracle 通过 ROWID 批量更新表的方法

《Oracle通过ROWID批量更新表的方法》在Oracle数据库中,使用ROWID进行批量更新是一种高效的更新方法,因为它直接定位到物理行位置,避免了通过索引查找的开销,下面给大家介绍Orac... 目录oracle 通过 ROWID 批量更新表ROWID 基本概念性能优化建议性能UoTrFPH优化建议注

全解析CSS Grid 的 auto-fill 和 auto-fit 内容自适应

《全解析CSSGrid的auto-fill和auto-fit内容自适应》:本文主要介绍了全解析CSSGrid的auto-fill和auto-fit内容自适应的相关资料,详细内容请阅读本文,希望能对你有所帮助... css  Grid 的 auto-fill 和 auto-fit/* 父元素 */.gri

Redis中6种缓存更新策略详解

《Redis中6种缓存更新策略详解》Redis作为一款高性能的内存数据库,已经成为缓存层的首选解决方案,然而,使用缓存时最大的挑战在于保证缓存数据与底层数据源的一致性,本文将介绍Redis中6种缓存更... 目录引言策略一:Cache-Aside(旁路缓存)策略工作原理代码示例优缺点分析适用场景策略二:Re

Pandas利用主表更新子表指定列小技巧

《Pandas利用主表更新子表指定列小技巧》本文主要介绍了Pandas利用主表更新子表指定列小技巧,通过创建主表和子表的DataFrame对象,并使用映射字典进行数据关联和更新,实现了从主表到子表的同... 目录一、前言二、基本案例1. 创建主表数据2. 创建映射字典3. 创建子表数据4. 更新子表的 zb

Python实现word文档内容智能提取以及合成

《Python实现word文档内容智能提取以及合成》这篇文章主要为大家详细介绍了如何使用Python实现从10个左右的docx文档中抽取内容,再调整语言风格后生成新的文档,感兴趣的小伙伴可以了解一下... 目录核心思路技术路径实现步骤阶段一:准备工作阶段二:内容提取 (python 脚本)阶段三:语言风格调

一文详解如何在Python中从字符串中提取部分内容

《一文详解如何在Python中从字符串中提取部分内容》:本文主要介绍如何在Python中从字符串中提取部分内容的相关资料,包括使用正则表达式、Pyparsing库、AST(抽象语法树)、字符串操作... 目录前言解决方案方法一:使用正则表达式方法二:使用 Pyparsing方法三:使用 AST方法四:使用字

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown