本文主要是介绍备战蓝桥杯单片机倒数第四天 小蜜蜂老师公众号更新内容,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
揽江楼一楼在装修
夜里熬到了两点左右,早上九点多起来,状态比较低迷,有点困的状态持续到了现在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底层驱动的头文件是基于12T的89C52运行环境,则需要将底层驱动文件中的延时参数放大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;
}
- 确认头文件是否完整
这篇关于备战蓝桥杯单片机倒数第四天 小蜜蜂老师公众号更新内容的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!