51单片机智能闹钟 -- 硬件连接与模块函数解析
硬件准备:
- 使用到的模块:
– DHT11温湿度传感器x1
– MQ135空气质量检测传感器x1
– 无源蜂鸣器x1
– OLED12864模块(I2C协议)x1
– DS1302时钟模块x1
– 双引脚式按键(其他按键也行但需要更具手册修改代码)x4-6
– LED灯 x若干
–公对母杜邦线,母对母杜邦线,跳线。x若干
以下均可按需增减改:
- 温湿度传感器DHT11的DATA引脚 -> P17
- 时钟模块DS1302的CLK引脚 -> P25;DAT引脚 -> P26;RST引脚 -> P27
- 蜂鸣器模块的I/O引脚 -> P24
- OLED12864模块的SCL引脚 -> P03;SDA引脚 -> P02
- 按键模块:从1-6:P32-37
- LED灯:绿:P15;黄:P16。
- 此处使用3.3V或5V供电均可
模块函数解析
OLED驱动模块(调用部分)
- X轴:0-127格;Y轴:0-7页(8格每页)
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);
x,y :起点坐标 ;num:数值;
len :数字的位数;size:字体大小(字符间距)
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);
x,y :起点坐标 ;chr:要显示的单个字符;size:字体大小(字符间距)
void OLED_ShowString(u8 x,u8 y, u8 *p,u8 Char_Size);
x,y :起点坐标;*p:字符串;Char_Size:字体大小
void OLED_ShowCHinese(u8 x,u8 y,u8 no);
可以在oledfont文件中的Hzk添加汉字大小的小图片。
- OLED汉字字模生成
生成字模所需软件如下:
- OLED添加字模
添加相应的16进制编号,记得修改一下注释序号,方便查找。
DHT11温湿度传感器(调用部分)
- RH、RL、TH、TL外部可调用变量:
参考显示:
void DHT11_get_Data();
参考显示
DS1302时钟模块(调用部分)
- 外部可调用变量
1.WriteAddr数组会在可调时钟中应用。
2.DS1302time数组中是已将BCD码转换为10进制的数组,可直接使用,并正常显示。 - 代码中BCD转10进制过程
void DS1302_ReadTime(void);
void DS1302_Write(uchar addr,uchar dat);
参数:写入的地址;写入的数据(BCD码)
注意:在进行重写时间的时候需要禁止写保护,写完要开启写保护
运用示例:
蜂鸣器模块(此处是无源蜂鸣器)
void Buzzer_Mode(uchar mode)
参数,可以选择不同的声音模式。此处仅写了2种模式,可以扩写。
空气质量检测模块(DO)
- 这里并未使用ADC转换芯片,故接DO口,直接判断IO口电平状态即可。
按键模块
uchar Key_GetNum();
此写法为阻塞式写法:Delay消抖while等待- 非阻塞式按键写法:
调用部分:某变量 = Key_GetNum();
获取键码值
uchar Key_Num;
/**
* @brief 获取独立按键键码
* @param 无
* @retval 按下按键的键码,范围:0~6,无按键按下时返回值为0
* 说 明:无
// 此代码基于江协科技
*/
uchar Key_GetNum(void)
{
uchar Temp;
Temp = Key_Num;
Key_Num = 0;
return Temp;
}
/**
* @brief 获取独立按键被按下的状态
* @param 无
* @retval 按下按键的键码,范围:0~6,无按键按下时返回值为0
* 说 明:可根据相同的方式续写或更改为所需引脚;非阻塞式写法
// 此代码基于江协科技
*/
uchar Key_GetState(void)
{
if (P3_2 == 0)
{
return 1;
}
if (P3_3 == 0)
{
return 2;
}
if (P3_4 == 0)
{
return 3;
}
if (P3_5 == 0)
{
return 4;
}
if (P3_6 == 0)
{
return 5;
}
if (P3_7 == 0)
{
return 6;
}
return 0;
}
/**
* @brief 判断按下和松手
* @param 无
* @retval 无
* 说 明:根据按键的当前状态和上一次状态比较,来判断按键是否被按下
// 此代码基于江协科技
*/
void Key_Tick(void)
{
static uchar Count;
static uchar CurrState, PrevState;
Count ++;
if (Count >= 20)
{
Count = 0;
PrevState = CurrState;
CurrState = Key_GetState();
if (CurrState == 0 && PrevState != 0)
{
Key_Num = PrevState;
}
}
}
- 非阻塞按键的定时器配置:
#include <REGX52.H>
void Timer0Init(void) //1毫秒@11.0592MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计数
ET0=1; //开定时器0中断开关
EA=1; //开启中断总开关
PT0=0;
}
中断执行函数:
void Timer0_Routine() interrupt 1
{
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
Key_Tick();
}
小节总结
标签:闹钟,引脚,void,51,Key,单片机,模块,按键,u8 From: https://blog.csdn.net/2401_87000537/article/details/144642125“ 勤学如春起之苗,不见其增日有所长。惰学如磨刀之石,不见其损日有所亏。加油,日积月累,就能进步如飞!”