基于单片机控制的路灯系统设计与实现
"#include "reg52.h"
"#include "intrins.h"
"#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; // 灯光控制\t(路灯开关
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; // 接收延时
}
} 解释此程序定时器中断的作用
原文地址: https://www.cveoy.top/t/topic/pImy 著作权归作者所有。请勿转载和采集!