- #include <reg51.h> //头文件
- #include "1.h"
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- #define u8 unsigned char
- #define PWM_Cycle 100
- //数据定义区
- unsigned char Minute_set=1; //定时时间设置
- unsigned char Distance_DIS=50; //设定的距离提醒举例
- sbit TX=P1^6; //超声波传感器的接口
- sbit RX=P1^5;
- sbit PWM_1=P1^7;
- sbit PWM_2=P2^2;
- sbit LED_ALARM=P1^4;
- #define LED_PORT P3//灯光控制
- unsigned long int counter_time=0;
- unsigned char Minute_time=0;
- unsigned char second_time=0;
- uint time=0; //声波时间
- uint S=0; //距离
- //LCD port
- sbit LCD1602_RS= P1^2;
- sbit LCD1602_RW= P1^1;
- sbit LCD1602_EN= P1^0;
- sfr LCD1602_DATAPINS= 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
- sbit KEY1=P2^0;
- sbit KEY2=P2^1;
- sbit KEY3=P2^2;
- sbit KEY4=P2^3;
- #define KEY3_VALUE 3
- #define KEY4_VALUE 4
- extern void Delay1ms(uint c); //@11.0592MHz
- uchar KEY_Scan(uchar mode);
- //在LCD1602上显示时间
- void Display_Time_lcd1602();
- uchar code number[10]={"0123456789"};
- void delayms ( uint c) //@12.000MHz
- {
- unsigned char i, j;
- for(;c>0;c--)
- {
- i = 2;
- j = 239;
- do
- {
- while (--j);
- } while (--i);
- }
- }
- #define Lcd1602_Delay1ms delayms
- /*******************************************************************************
- * 函 数 名 : LcdWriteCom
- * 函数功能 : 向LCD写入一个字节的命令
- * 输 入 : com
- * 输 出 : 无
- *******************************************************************************/
- #ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时
- void Write_LCD_Command(uchar com) //写入命令
- {
- LCD1602_EN = 0; //使能
- LCD1602_RS = 0; //选择发送命令
- LCD1602_RW = 0; //选择写入
-
- LCD1602_DATAPINS = com; //放入命令
- Lcd1602_Delay1ms(1); //等待数据稳定
- LCD1602_EN = 1; //写入时序
- Lcd1602_Delay1ms(5); //保持时间
- LCD1602_EN = 0;
- }
- #else
- void Write_LCD_Command(uchar com) //写入命令
- {
- LCD1602_EN = 0; //使能清零
- LCD1602_RS = 0; //选择写入命令
- LCD1602_RW = 0; //选择写入
- LCD1602_DATAPINS = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
- Lcd1602_Delay1ms(1);
- LCD1602_EN = 1; //写入时序
- Lcd1602_Delay1ms(5);
- LCD1602_EN = 0;
- LCD1602_DATAPINS = com << 4; //发送低四位
- Lcd1602_Delay1ms(1);
- LCD1602_EN = 1; //写入时序
- Lcd1602_Delay1ms(5);
- LCD1602_EN = 0;
- }
- #endif
- /*******************************************************************************
- * 函 数 名 : LcdWriteData
- * 函数功能 : 向LCD写入一个字节的数据
- * 输 入 : dat
- * 输 出 : 无
- *******************************************************************************/
- #ifndef LCD1602_4PINS
- void Write_LCD_Data(uchar dat) //写入数据
- {
- LCD1602_EN = 0; //使能清零
- LCD1602_RS = 1; //选择输入数据
- LCD1602_RW = 0; //选择写入
- LCD1602_DATAPINS = dat; //写入数据
- Lcd1602_Delay1ms(1);
- LCD1602_EN = 1; //写入时序
- Lcd1602_Delay1ms(5); //保持时间
- LCD1602_EN = 0;
- }
- #else
- void Write_LCD_Data(uchar dat) //写入数据
- {
- LCD1602_EN = 0; //使能清零
- LCD1602_RS = 1; //选择写入数据
- LCD1602_RW = 0; //选择写入
- LCD1602_DATAPINS = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
- Lcd1602_Delay1ms(1);
- LCD1602_EN = 1; //写入时序
- Lcd1602_Delay1ms(5);
- LCD1602_E = 0;
- LCD1602_DATAPINS = dat << 4; //写入低四位
- Lcd1602_Delay1ms(1);
- LCD1602_EN = 1; //写入时序
- Lcd1602_Delay1ms(5);
- LCD1602_EN = 0;
- }
- #endif
- void LCD_Init() //1602LCD 初始化
- {
- Write_LCD_Command(0x01);//清屏
- Write_LCD_Command(0x38);//设置8位格式,2行,5*8
- Write_LCD_Command(0x0c);//整体显示,关光标,不闪烁
- Write_LCD_Command(0x06);//设定输入方式,增量不移位
- }
- /****************写一个字符数据到指定的位置***************/
- void DisplayOneChar(uchar X,uchar Y,uchar DData)
- {
- Y&=1;
- X&=15;
- if(Y)X|=0x40;
- X|=0x80;
- Write_LCD_Command(X);
- Write_LCD_Data(DData);
- }
- void Lcd1602SetCursor(uchar X,uchar Y)
- {
- Y&=1;
- X&=15;
- if(Y)X|=0x40;
- X|=0x80;
- Write_LCD_Command(X);
- }
- /****************写多个个字符数据到指定的位置***************/
- void DisplayChars(uchar X,uchar Y,uchar *str)
- {
-
- Lcd1602SetCursor(X, Y); //设置起始地址
- while (*str != '\0')
- {
- Write_LCD_Data(*(str++));
- }
- }
- /*********************************************************************
- 函数名称:Disp_number()
- 功能描述:显示四数字
- 入口参数:num:显示的数字 n:数字位数
- 返回值:无
- ************************************************************************/
- void Disp_number(uchar X,uchar Y,uint num,u8 n)
- {
- u8 a; //个位
- u8 b; //十位
- u8 c; //百位
- u8 d; //千位
- u8 e; //万位
- Y&=1;
- X&=15;
- if(Y)X|=0x40;
- X|=0x80;
- Write_LCD_Command(X);
- switch(n)
- {
- case 1:Write_LCD_Data(num+0x30);
- break;
- case 2:b=num/10;
- a=num%10;
- Write_LCD_Data(number[b]);
- Write_LCD_Data(number[a]);
- break;
- case 3:c=num/100;
- b=num%100/10;
- a=num%10;
- Write_LCD_Data(number[c]);
- Write_LCD_Data(number[b]);
- Write_LCD_Data(number[a]);
- break;
- case 4:d=num/1000;
- c=num%1000/100;
- b=num%1000%100/10;
- a=num%10;
- Write_LCD_Data(number[d]);
- Write_LCD_Data(number[c]);
- Write_LCD_Data(number[b]);
- Write_LCD_Data(number[a]);
- break;
- case 5:
- e=num/10000;
- d=num%10000/1000;
- c=num%1000/100;
- b=num%100/10;
- a=num%10;
- Write_LCD_Data(number[e]);
- Write_LCD_Data(number[d]);
- Write_LCD_Data(number[c]);
- Write_LCD_Data(number[b]);
- Write_LCD_Data(number[a]);
- break;
- }
- }
- void Count(void) //计算距离的函数
- {
- time=(TH0<<8)+TL0;
- TH0=0;
- TL0=0;
- time=time+counter_time*65536;//us
- S=time/58; //算出来是CM 340m/S声速
- }
- //************************************
- //定时器初始化
- //初始化为10MS定时器
- //************************************
- void Time0_init()
- {
- TMOD |= 0x01; //使用模式1,16位定时器
- TH0 = 0; //定时器装入初始值10ms
- TL0 = 0;
- EA = 1; //总中断
- ET0 = 1;//定时器0初始化
- TR0 = 0;
- }
- //定时器1初始化
- void Timer1Init(void) //1毫秒@12.000MHz
- {
- //AUXR &= 0xBF; //定时器时钟12T模式
- TMOD &= 0x0F; //设置定时器模式
- TMOD |= 0x10; //设置定时器模式
- TL1 = 0x18; //设置定时初值
- TH1 = 0xFC; //设置定时初值
- TF1 = 0; //清除TF1标志
- TR1 = 1; //定时器1开始计时
- ET1=1;
- }
- void StartModule()
- {
- TX=1; //800MS 启动一次模块
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- TX=0;
- }
- unsigned int DATA_V;
- bit channel=0;
- uint AD_val=0;
- float code H_num=0.625 ; //这是一个距离的比例系数
-
- //超声波检测
- uchar HC_SR04_Task(void)
- {
- static unsigned long try=0;
- static uchar timeout_flag=0;
- StartModule();
- while(!RX) //当RX为零时等待
- {
- try++;
- if(try>600000) //等待时间不能太长,防止程序死机
- {
- try=0;
- timeout_flag=1;//置位超时标志
- break;
- }
- }
- counter_time=0;
- TH0=0;
- TL0=0;
- TR0=1; //开启计数
- if(timeout_flag==0)
- {
- while(RX) //当RX为1计数并等待
- {
- try++;
- if(try>6000000) //等待时间不能太长,防止程序死机
- {
- try=0;
- timeout_flag=1; //置位超时标志
- break;
- }
- }
- }
- TR0=0; //关闭计数
- if(timeout_flag)//如果超时了
- {
- TH0=0;
- TL0=0;
- timeout_flag=0;
- }
- else//正常数据
- {
- Count(); //计算
- }
- if(S>=Distance_DIS)
- return 0;
- else//当距离小于或等于50时,
- {
- return 4;
-
- }
- return 0;
- }
- bit Alarm_Time_flag=0;
- void compare_light_time()
- {
- uchar key=0;
- if(Alarm_Time_flag)
- {
- Write_LCD_Command(0x01);//清屏
- while(1)
- {
- //请注意休息,声光报警
- LED_ALARM=0;
- DisplayChars(0,0,"Please have");//在LCD1602上显示Light
- DisplayChars(0,1,"A good rest");
- key=KEY_Scan(0);
- if(key==KEY4_VALUE)//进入设置界面
- {
- Alarm_Time_flag=0;//时间到达设定值
- LED_ALARM=1;
- Write_LCD_Command(0x01);//清屏
- break;
- }
- }
- }
- LED_ALARM=1;
- }
- /********************************************************************
- * 名称 : Main()
- * 功能 : 主函数
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void Main(void)
- {
- uchar key=0,state=0;
- Time0_init(); //初始化定时器 超声波使用的
- Timer1Init();//定时器1初始化 1ms中断1次
- LCD_Init();//LCD1602初始化
- while(1)
- {
- key=KEY_Scan(0); //按键的扫描
- switch(state)
- {
- case 0:
- state=HC_SR04_Task();//超声波检测代码
-
- DisplayChars(0,1,"DIS:"); //
- Disp_number(4,1,S,2);
- DisplayChars(6,1,"cm");
-
- compare_light_time();//比较时间报警
- Disp_number(10,1,Minute_time,2);
- DisplayOneChar(12,1,'-');
- Disp_number(13,1,second_time,2);
- if(key==KEY4_VALUE)//进入设置界面
- {
- second_time=0;
- Minute_time=0;//清除时间
- Alarm_Time_flag=0;//时间到达设定值
- Write_LCD_Command(0x01);//清屏
- break;
- }
- break;
- case 4:
- LED_ALARM=0;
- state=HC_SR04_Task();//超声波检测代码
- DisplayChars(0,0,"Please adjust");
- DisplayChars(0,1,"Your sitting pos");
- if(state==0)
- { LED_ALARM=1;
- Write_LCD_Command(0x01);//清屏
- }
- break;
- default:break;
- }
- }
- }
- void timer0() interrupt 1 //10us定时器累加
- {
- TH0 = 0; //定时器装入初始值10ms
- TL0 = 0;
- counter_time++;
- }
- void time1_ISR() interrupt 3
- {
- static uint count=0;
-
- TL1 = 0x18; //设置定时初值
- TH1 = 0xFC; //设置定时初值
- count++;
- if(count>=1000)//1s
- {
- count=0;
- second_time++;
-
- if(second_time>=60)
- {
-
- Minute_time++;
- second_time=0;
- if(Minute_time>=Minute_set)
- Alarm_Time_flag=1; //超出时间
- else
- Alarm_Time_flag=0;
-
- }
- }
-
- }
- //按键控制
- uchar KEY_Scan(uchar mode)
- {
- static u8 key=1;
- if(mode==1) //连续按键按下
- {
- key=1;
- }
- if(KEY3==0||KEY4==0) //任意一个按键按下
- {
- delayms(10); //消抖
- key=0;
- if(KEY3==0)
- {
- return KEY3_VALUE;
- }
- else if(KEY4==0)
- {
- return KEY4_VALUE;
- }
- }
- else if(KEY3==1&&KEY4==1) //无按键按下
- {
- key=1;
- }
- return 0;
- }
复制代码
|