基于光照强度控制的路灯系统 - 使用DS1302、AD0832、BH1750和LCD1602
#include \u003creg52.h\u003e
#include \u003cintrins.h\u003e
#include "lcd.h"
#include "typedef.h"
#include "ds1302.h"
#include "AD0832.h"
#include "bh1750.h"
#ifdef __cplusplus
extern "C" {
#endif
sbit K1 = P2 ^ 3; // 按键1 sbit K2 = P2 ^ 4; // 按键2 sbit K3 = P3 ^ 4; // 按键3 sbit Lamp= P1^ 0; // 灯光控制 (路灯开关
u8 SetCnt = 0; // 设置计数 u8 TimeSel = 0; // 时间设置 u8 TimeCnt = 0; // 时间移位设置
extern u8 Timer[3]; // 设置时间 extern u8 hour,min,sec; // 小时和分钟和秒
u8 Openflag; // 开关标志位 u8 Sw; // 按键控制 u8 Keyflag; // 按键按下标志位 u16 Illvalue; // 光照值 u16 IllMin=30; // 最低光照阈值 u16 BatterBuf[5]; // 电压缓存 u8 BatterCnt; // ADC采集计数 u16 BatterValue; // 电压值 u8 UartData[6]; // 接收串口数据 u8 UartTmr=0; // 接收延时 u8 UartCnt=0; // 接收串口数据个数 u8 UartFlg=0; // 接收到数据标志位 //u16 BatterDis = 1000; // 电池电压显示
void Light_Bright(u8 x,u8 y,u8 tmp) { if(tmp==0) { LcdShowStr(x,y,"NO"); // 显示当前字符 } else { LcdShowStr(x,y,"YS"); // 显示当前字符 } }
// 按键程序 void Key_program() { if(K1==1&&K2==1&&K3==1) // 没有按键按下 { Keyflag=1; // 按键按下标志位 } else // 如果有按键按下 { if(Keyflag==1) // 按键按下标志位为1 { Keyflag =0; // 按键按下标志位 if(K1==0) // 如果按键1按下 { if(IllMin<10000) { IllMin++; } } if(K2==0) // 如果按键2按下 { if(IllMin>0) { IllMin--; } } if(K3==0) // 如果按键3按下 { if(++Sw>=2) Sw =0; } } }
}
void UARTRxdData()
{
if(UartFlg==1) // 串口有数据接收
{
if(++UartTmr>=2) // 延时等待接收完毕
{
if(UartCnt==6) // 如果收到数据长度为6
{
Timer[2] = (UartData[0]-0x30)10+(UartData[1]-0x30); // 计算时
Timer[1] = (UartData[2]-0x30)10+(UartData[3]-0x30); // 计算分
Timer[0] = (UartData[4]-0x30)10+(UartData[5]-0x30); // 计算秒
Timer[2] = Timer[2]/1016+Timer[2]%10; // 10进制 转16进制
Timer[1] = Timer[1]/1016+Timer[1]%10; // 10进制 转16进制
Timer[0] = Timer[0]/1016+Timer[0]%10; // 10进制 转16进制
Ds1302WriteTime(); // 写入数据
}
if(UartCnt==4) // 如果收到数据长度为4
{
if(UartData[0]=='o'&&UartData[1]=='p'&&UartData[2]=='e'&&UartData[3]=='n')
{
Sw= 1; // 打开
}
else if(UartData[0]=='c'&&UartData[1]=='l'&&UartData[2]=='s'&&UartData[3]=='e')
{
Sw= 0; // 关闭
}
}
UartTmr=0; // 接收延时
UartFlg=0; // 接收到数据标志位置零
UartCnt=0;
}
}
}
void Uart_init(void) {
// TMOD |= 0x20; // TMOD=0010 0000B,定时器T1工作于方式2
// SCON |= 0x40; // SCON=0100 0000B,串口工作方式1
// PCON &= 0xef;
// TH1 = 0xfd;
// TL1 = 0xfd;
// TR1 = 1;
SCON |= 0x50;
TMOD |= 0x20;
PCON |= 0x00;
TH1 = 0xfd; // 根据规定给定时器T1赋初值 波特率9600
TL1 = 0xfd; // 根据规定给定时器T1赋初值 波特率9600
TI = 0;
RI = 0;
TR1 = 1; // 启动定时器T1
IE |= 0x90;
ES = 1;
} /*******************************************************************************
- 函 数 名 : Timer0Init
- 函数功能 : 定时器0初始化
- 输 入 : 无
- 输 出 : 无 *******************************************************************************/ void Timer0Init() { TMOD|=0X01; // 选择为定时器0模式,工作方式1,仅用TR0打开启动。 TH0=0XFC; // 给定时器赋初值,定时1ms TL0=0X18; ET0=1; // 打开定时器0中断允许 EA=1; // 打开总中断 TR0=1; // 打开定时器 }
void main(void)
{
u8 i = 0;
Uart_init(); // 初始化串口波特率9600
Timer0Init(); // 初始化定时器0
Ds1302Init(); // 初始化DS1302
InitLcd1602(); // 初始化LCD1602
InitBH1750(); //初始化bh1750
while(1)
{
if(++i>=20)
{
i =20;
if(SetCnt == 0)
{
Ds1302ReadTime(); // 读取DS1302时钟
}
Illvalue = Read_BH1750(); // 读取光照值
LcdShowStr(0,0,\"L=\"); // 显示当前字符 \"L=\"
Lcd_DisplayIll(2,0,Illvalue); // 显示当前光照值
LcdShowStr(7,0,\"Lux\"); // 显示当前字符 \"lux\"
Lcd_DisplayIll(11,0,IllMin); // 显示当前光照值
Lcd_Display(0,1,hour); // 当前小时
LcdShowStr(2,1,\":\"); // 显示当前字符
Lcd_Display(3,1,min); // 当前分钟
LcdShowStr(5,1,\":\"); // 显示当前字符
Lcd_Display(6,1,sec); // 当前秒
Light_Bright(9,1,Openflag); // 显示开关状态
Lcd_DisplayBatter(12,1,BatterValue);
}
TR0=0; // 关闭定时器0
BatterBuf[BatterCnt] = Read_ADC0832(0)*1.97*2; // 电压缓存
TR0=1; // 打开定时器0
if(++BatterCnt>=5)
{
BatterCnt =0;
BatterValue=(BatterBuf[0]+BatterBuf[1]+BatterBuf[2]+BatterBuf[3]+BatterBuf[4])/5/10+2; // 取平均值
if(BatterValue>=42)
BatterValue =42;
}
if(Sw==0)
{
if(Illvalue < IllMin) // 光照小于阈值
{
Lamp = 0; // 灯光打开
Openflag=1; // 开关标志位置1
}
else
{
Lamp = 1; // 灯光关闭
Openflag=0; // 开关标志位置0
}
}
else if(Sw==1)
{
Lamp = 0; // 灯光打开
Openflag=1; // 开关标志位置1
}
UARTRxdData();
}
}
/*******************************************************************************
-
函 数 名 : void Timer0() interrupt 1
-
函数功能 : 定时器0中断函数
-
输 入 : 无
-
输 出 : 无 *******************************************************************************/ void Timer0() interrupt 1 {
TH0 = 0xDC; // 给定时器赋初值,定时10ms TL0 = 0x00; Key_program(); // 按键程序
}
void Serial_INT() interrupt 4 {
unsigned char temp; //用于存放读出的寄存器SBUF中的值
if(RI) //检测串口接收中断标志,接收时为1
{
temp = SBUF; //将SBUF寄存器的值存在temp中
UartData[UartCnt]=temp;
RI = 0; //清中断标志
++UartCnt;
UartFlg=1; // 接收到数据标志位
UartTmr=0; // 接收延时
}
} #ifdef __cplusplus } #endif此程序涉及什么问题 内容:This program controls a light system based on the ambient light intensity. It uses a DS1302 real-time clock module, an AD0832 analog-to-digital converter, a BH1750 light sensor, and an LCD1602 display. The program also includes UART communication for remote control.
The program initializes the modules and variables, and then enters an infinite loop. In each iteration of the loop, it reads the current time from the DS1302 and the light intensity from the BH1750 sensor. It also reads the battery voltage using the AD0832 ADC.
The program checks if any buttons are pressed and adjusts the light intensity threshold accordingly. It then checks the light intensity and controls the lamp based on the threshold and switch status. The program also updates the LCD display with the current values.
Additionally, the program includes UART communication to receive commands for setting the time and controlling the lamp. It reads the UART data and performs the corresponding actions.
Overall, the program controls the light system based on the ambient light intensity and allows for remote control through UART communication.
原文地址: https://www.cveoy.top/t/topic/pIub 著作权归作者所有。请勿转载和采集!