找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1005|回复: 3
打印 上一主题 下一主题
收起左侧

这上面还有些按键功能怎么删掉啊还不影响本来的单片机程序 求大神

[复制链接]
跳转到指定楼层
楼主
ID:1016612 发表于 2022-4-7 22:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1. #include <reg51.h>                //头文件
  2. #include "1.h"


  3. #include   <intrins.h>

  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. #define u8 unsigned char



  7. #define        PWM_Cycle  100
  8. //数据定义区
  9. unsigned char Minute_set=1;                //定时时间设置
  10. unsigned char Distance_DIS=50; //设定的距离提醒举例

  11. sbit TX=P1^6;        //超声波传感器的接口
  12. sbit RX=P1^5;

  13. sbit PWM_1=P1^7;
  14. sbit PWM_2=P2^2;
  15. sbit LED_ALARM=P1^4;
  16. #define LED_PORT P3//灯光控制

  17. unsigned long int counter_time=0;
  18. unsigned char  Minute_time=0;
  19. unsigned char  second_time=0;

  20. uint  time=0;  //声波时间
  21. uint   S=0;          //距离

  22. //LCD port
  23. sbit LCD1602_RS= P1^2;
  24. sbit LCD1602_RW= P1^1;
  25. sbit LCD1602_EN= P1^0;

  26. sfr  LCD1602_DATAPINS= 0x80;                //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

  27. sbit KEY1=P2^0;
  28. sbit KEY2=P2^1;
  29. sbit KEY3=P2^2;
  30. sbit KEY4=P2^3;

  31. #define KEY3_VALUE 3
  32. #define KEY4_VALUE 4

  33. extern  void  Delay1ms(uint c);                 //@11.0592MHz
  34. uchar KEY_Scan(uchar mode);
  35. //在LCD1602上显示时间
  36. void Display_Time_lcd1602();
  37. uchar code number[10]={"0123456789"};



  38. void delayms ( uint c)                //@12.000MHz
  39. {
  40.         unsigned char i, j;
  41.   for(;c>0;c--)
  42.         {
  43.                         i = 2;
  44.                 j = 239;
  45.                 do
  46.                 {
  47.                         while (--j);
  48.                 } while (--i);
  49.         }
  50. }


  51. #define Lcd1602_Delay1ms  delayms


  52. /*******************************************************************************
  53. * 函 数 名         : LcdWriteCom
  54. * 函数功能                   : 向LCD写入一个字节的命令
  55. * 输    入         : com
  56. * 输    出         : 无
  57. *******************************************************************************/
  58. #ifndef LCD1602_4PINS         //当没有定义这个LCD1602_4PINS时
  59. void Write_LCD_Command(uchar com)          //写入命令
  60. {
  61.         LCD1602_EN = 0;     //使能
  62.         LCD1602_RS = 0;           //选择发送命令
  63.         LCD1602_RW = 0;           //选择写入
  64.         
  65.         LCD1602_DATAPINS = com;     //放入命令
  66.         Lcd1602_Delay1ms(1);                //等待数据稳定

  67.         LCD1602_EN = 1;                  //写入时序
  68.         Lcd1602_Delay1ms(5);          //保持时间
  69.         LCD1602_EN = 0;
  70. }
  71. #else
  72. void Write_LCD_Command(uchar com)          //写入命令
  73. {
  74.         LCD1602_EN = 0;         //使能清零
  75.         LCD1602_RS = 0;         //选择写入命令
  76.         LCD1602_RW = 0;         //选择写入

  77.         LCD1602_DATAPINS = com;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
  78.         Lcd1602_Delay1ms(1);

  79.         LCD1602_EN = 1;         //写入时序
  80.         Lcd1602_Delay1ms(5);
  81.         LCD1602_EN = 0;

  82.         LCD1602_DATAPINS = com << 4; //发送低四位
  83.         Lcd1602_Delay1ms(1);

  84.         LCD1602_EN = 1;         //写入时序
  85.         Lcd1602_Delay1ms(5);
  86.         LCD1602_EN = 0;
  87. }
  88. #endif
  89. /*******************************************************************************
  90. * 函 数 名         : LcdWriteData
  91. * 函数功能                   : 向LCD写入一个字节的数据
  92. * 输    入         : dat
  93. * 输    出         : 无
  94. *******************************************************************************/                  
  95. #ifndef         LCD1602_4PINS                  
  96. void Write_LCD_Data(uchar dat)                        //写入数据
  97. {
  98.         LCD1602_EN = 0;        //使能清零
  99.         LCD1602_RS = 1;        //选择输入数据
  100.         LCD1602_RW = 0;        //选择写入

  101.         LCD1602_DATAPINS = dat; //写入数据
  102.         Lcd1602_Delay1ms(1);

  103.         LCD1602_EN = 1;   //写入时序
  104.         Lcd1602_Delay1ms(5);   //保持时间
  105.         LCD1602_EN = 0;
  106. }
  107. #else
  108. void Write_LCD_Data(uchar dat)                        //写入数据
  109. {
  110.         LCD1602_EN = 0;          //使能清零
  111.         LCD1602_RS = 1;          //选择写入数据
  112.         LCD1602_RW = 0;          //选择写入

  113.         LCD1602_DATAPINS = dat;        //由于4位的接线是接到P0口的高四位,所以传送高四位不用改
  114.         Lcd1602_Delay1ms(1);

  115.         LCD1602_EN = 1;          //写入时序
  116.         Lcd1602_Delay1ms(5);
  117.         LCD1602_E = 0;

  118.         LCD1602_DATAPINS = dat << 4; //写入低四位
  119.         Lcd1602_Delay1ms(1);

  120.         LCD1602_EN = 1;          //写入时序
  121.         Lcd1602_Delay1ms(5);
  122.         LCD1602_EN = 0;
  123. }
  124. #endif

  125. void LCD_Init() //1602LCD 初始化
  126. {
  127.                 Write_LCD_Command(0x01);//清屏
  128.                 Write_LCD_Command(0x38);//设置8位格式,2行,5*8
  129.                 Write_LCD_Command(0x0c);//整体显示,关光标,不闪烁
  130.                 Write_LCD_Command(0x06);//设定输入方式,增量不移位
  131. }


  132. /****************写一个字符数据到指定的位置***************/
  133. void DisplayOneChar(uchar X,uchar Y,uchar DData)
  134. {                                                
  135.                 Y&=1;                                                
  136.                 X&=15;                                                
  137.                 if(Y)X|=0x40;                                       
  138.                 X|=0x80;                        
  139.                 Write_LCD_Command(X);               
  140.                 Write_LCD_Data(DData);               
  141. }

  142. void Lcd1602SetCursor(uchar X,uchar Y)
  143. {
  144.         Y&=1;                                                
  145.         X&=15;                                                
  146.         if(Y)X|=0x40;                                       
  147.         X|=0x80;                        
  148.         Write_LCD_Command(X);

  149. }
  150. /****************写多个个字符数据到指定的位置***************/
  151. void DisplayChars(uchar X,uchar Y,uchar *str)
  152. {        
  153.         
  154.    Lcd1602SetCursor(X, Y);   //设置起始地址
  155.          while (*str != '\0')  
  156.     {
  157.         Write_LCD_Data(*(str++));
  158.     }               
  159. }


  160. /*********************************************************************
  161. 函数名称:Disp_number()
  162. 功能描述:显示四数字
  163. 入口参数:num:显示的数字 n:数字位数
  164. 返回值:无
  165. ************************************************************************/
  166. void Disp_number(uchar X,uchar Y,uint num,u8 n)
  167. {
  168.                         u8 a; //个位
  169.                         u8 b; //十位
  170.                         u8 c; //百位
  171.                         u8 d; //千位
  172.                         u8 e; //万位

  173.         Y&=1;                                                
  174.         X&=15;                                                
  175.         if(Y)X|=0x40;                                       
  176.         X|=0x80;                        
  177.         Write_LCD_Command(X);
  178.                         switch(n)
  179.                         {
  180.                         case 1:Write_LCD_Data(num+0x30);
  181.                         break;
  182.                         case 2:b=num/10;
  183.                         a=num%10;
  184.                         Write_LCD_Data(number[b]);
  185.                         Write_LCD_Data(number[a]);
  186.                         break;
  187.                         case 3:c=num/100;
  188.                         b=num%100/10;
  189.                         a=num%10;
  190.                         Write_LCD_Data(number[c]);
  191.                         Write_LCD_Data(number[b]);
  192.                         Write_LCD_Data(number[a]);
  193.                         break;
  194.                         case 4:d=num/1000;
  195.                         c=num%1000/100;
  196.                         b=num%1000%100/10;
  197.                         a=num%10;
  198.                         Write_LCD_Data(number[d]);
  199.                         Write_LCD_Data(number[c]);
  200.                         Write_LCD_Data(number[b]);
  201.                         Write_LCD_Data(number[a]);
  202.                         break;
  203.                         case 5:
  204.                         e=num/10000;
  205.                         d=num%10000/1000;
  206.                         c=num%1000/100;
  207.                         b=num%100/10;
  208.                         a=num%10;
  209.                         Write_LCD_Data(number[e]);
  210.                         Write_LCD_Data(number[d]);
  211.                         Write_LCD_Data(number[c]);
  212.                         Write_LCD_Data(number[b]);
  213.                         Write_LCD_Data(number[a]);
  214.                         break;
  215.                         }
  216. }


  217. void Count(void)  //计算距离的函数
  218. {
  219.         time=(TH0<<8)+TL0;
  220.         TH0=0;
  221.         TL0=0;        
  222.         time=time+counter_time*65536;//us
  223.         S=time/58;     //算出来是CM 340m/S声速

  224. }

  225. //************************************
  226. //定时器初始化
  227. //初始化为10MS定时器        
  228. //************************************
  229. void Time0_init()
  230. {
  231.   TMOD |= 0x01;                         //使用模式1,16位定时器
  232.   TH0   = 0;        //定时器装入初始值10ms
  233.   TL0   = 0;
  234.   EA    = 1;  //总中断
  235.   ET0   = 1;//定时器0初始化
  236.   TR0   = 0;

  237. }
  238. //定时器1初始化
  239. void Timer1Init(void)                //1毫秒@12.000MHz
  240. {
  241.         //AUXR &= 0xBF;                //定时器时钟12T模式
  242.         TMOD &= 0x0F;                //设置定时器模式
  243.         TMOD |= 0x10;                //设置定时器模式
  244.         TL1 = 0x18;                //设置定时初值
  245.         TH1 = 0xFC;                //设置定时初值
  246.         TF1 = 0;                //清除TF1标志
  247.         TR1 = 1;                //定时器1开始计时
  248.         ET1=1;
  249. }


  250. void  StartModule()                        
  251. {
  252.   TX=1;                                         //800MS  启动一次模块
  253.   _nop_();
  254.   _nop_();
  255.   _nop_();
  256.   _nop_();
  257.   _nop_();
  258.   _nop_();
  259.   _nop_();
  260.   _nop_();
  261.   _nop_();
  262.   _nop_();
  263.   _nop_();
  264.   _nop_();
  265.   _nop_();
  266.   _nop_();
  267.   _nop_();
  268.   _nop_();
  269.   _nop_();
  270.   _nop_();
  271.   _nop_();
  272.   _nop_();
  273.   _nop_();
  274.   TX=0;
  275. }



  276. unsigned int DATA_V;


  277. bit  channel=0;


  278. uint AD_val=0;
  279. float  code H_num=0.625 ;      //这是一个距离的比例系数
  280.         

  281. //超声波检测
  282. uchar HC_SR04_Task(void)
  283. {
  284.         static  unsigned long try=0;
  285.         static  uchar timeout_flag=0;
  286.                       StartModule();
  287.                                         while(!RX)                //当RX为零时等待
  288.                                 {
  289.                                          try++;
  290.                                          if(try>600000)         //等待时间不能太长,防止程序死机
  291.                                          {
  292.                                                  try=0;
  293.                                                 timeout_flag=1;//置位超时标志
  294.                                                 break;
  295.                                         }
  296.                                 }
  297.                                   counter_time=0;
  298.                                    TH0=0;
  299.                                         TL0=0;
  300.                                         TR0=1;                            //开启计数
  301.                                 if(timeout_flag==0)
  302.                                 {
  303.                                                 while(RX)                        //当RX为1计数并等待
  304.                                         {
  305.                                                 try++;
  306.                                                  if(try>6000000)          //等待时间不能太长,防止程序死机
  307.                                                  {
  308.                                                                 try=0;
  309.                                                                 timeout_flag=1;        //置位超时标志
  310.                                                                 break;
  311.                                                 }
  312.                                         }
  313.                                 }
  314.                                         TR0=0;                                //关闭计数
  315.                                 if(timeout_flag)//如果超时了
  316.                                 {
  317.                                           TH0=0;
  318.                                                 TL0=0;
  319.                                                 timeout_flag=0;
  320.                                 }
  321.                                 else//正常数据
  322.                                 {
  323.                                                 Count();                        //计算
  324.                                 }
  325.                                   if(S>=Distance_DIS)
  326.                                     return 0;         
  327.                                   else//当距离小于或等于50时,                                                
  328.                                         {                 
  329.                                                   return 4;
  330.                                                 
  331.                                         }
  332.                                         return 0;
  333. }


  334. bit Alarm_Time_flag=0;

  335. void compare_light_time()
  336. {
  337.         uchar key=0;
  338.         if(Alarm_Time_flag)
  339.         {
  340.                 Write_LCD_Command(0x01);//清屏
  341.                 while(1)
  342.                 {
  343.                         //请注意休息,声光报警
  344.                         LED_ALARM=0;
  345.                         DisplayChars(0,0,"Please have");//在LCD1602上显示Light
  346.                         DisplayChars(0,1,"A good rest");
  347.                         key=KEY_Scan(0);        
  348.                  if(key==KEY4_VALUE)//进入设置界面
  349.                         {

  350.                                 Alarm_Time_flag=0;//时间到达设定值
  351.                                 LED_ALARM=1;
  352.                                 Write_LCD_Command(0x01);//清屏
  353.                                 break;
  354.                         }
  355.                 }
  356.         }
  357.         LED_ALARM=1;
  358. }


  359. /********************************************************************
  360. * 名称 : Main()
  361. * 功能 : 主函数
  362. * 输入 : 无
  363. * 输出 : 无
  364. ***********************************************************************/
  365. void Main(void)
  366. {

  367.         uchar key=0,state=0;
  368.   Time0_init();         //初始化定时器         超声波使用的
  369.         Timer1Init();//定时器1初始化  1ms中断1次
  370.   LCD_Init();//LCD1602初始化
  371.         while(1)
  372.         {
  373.                 key=KEY_Scan(0);        //按键的扫描
  374.                 switch(state)
  375.                 {
  376.                         case 0:
  377.                                                                 state=HC_SR04_Task();//超声波检测代码
  378.                         
  379.                                                                 DisplayChars(0,1,"DIS:"); //
  380.                                                                 Disp_number(4,1,S,2);
  381.                                                                 DisplayChars(6,1,"cm");
  382.                         
  383.                                                                 compare_light_time();//比较时间报警
  384.                                                                 Disp_number(10,1,Minute_time,2);
  385.                                                                 DisplayOneChar(12,1,'-');
  386.                                                                 Disp_number(13,1,second_time,2);
  387.                                        if(key==KEY4_VALUE)//进入设置界面
  388.                                                                 {
  389.                                                                         second_time=0;
  390.                                                                         Minute_time=0;//清除时间
  391.                                                                         Alarm_Time_flag=0;//时间到达设定值
  392.                                                                         Write_LCD_Command(0x01);//清屏
  393.                                                                         break;
  394.                                                                 }
  395.                                                                 break;
  396.                         case 4:
  397.                                                                         LED_ALARM=0;
  398.                                                                         state=HC_SR04_Task();//超声波检测代码                        
  399.                                                                         DisplayChars(0,0,"Please adjust");
  400.                                                                         DisplayChars(0,1,"Your sitting pos");        
  401.                                                                         if(state==0)
  402.                                                                         {        LED_ALARM=1;
  403.                                                                                 Write_LCD_Command(0x01);//清屏
  404.                                                                         }
  405.                                                                         break;
  406.                         default:break;
  407.                 }        
  408.         }               
  409. }

  410. void timer0() interrupt 1  //10us定时器累加
  411. {
  412.   TH0   = 0;        //定时器装入初始值10ms
  413.   TL0   = 0;
  414.   counter_time++;
  415. }

  416. void time1_ISR() interrupt 3
  417. {
  418.         static uint count=0;
  419.         
  420.         TL1 = 0x18;                //设置定时初值
  421.         TH1 = 0xFC;                //设置定时初值
  422.         count++;
  423.         if(count>=1000)//1s
  424.         {
  425.                 count=0;
  426.                 second_time++;
  427.                
  428.                 if(second_time>=60)
  429.                 {
  430.                
  431.                         Minute_time++;
  432.                         second_time=0;
  433.                         if(Minute_time>=Minute_set)
  434.                                 Alarm_Time_flag=1;        //超出时间
  435.                         else
  436.                                 Alarm_Time_flag=0;        
  437.                         
  438.                 }
  439.         }
  440.         
  441. }



  442. //按键控制
  443. uchar KEY_Scan(uchar mode)
  444. {
  445.         static u8 key=1;        
  446.         if(mode==1) //连续按键按下
  447.         {
  448.                 key=1;
  449.         }
  450.         if(KEY3==0||KEY4==0) //任意一个按键按下
  451.         {
  452.                 delayms(10);  //消抖
  453.                 key=0;
  454.                 if(KEY3==0)
  455.                 {
  456.                         return KEY3_VALUE;
  457.                 }
  458.                 else if(KEY4==0)
  459.                 {
  460.                         return KEY4_VALUE;
  461.                 }
  462.         }
  463.         else if(KEY3==1&&KEY4==1)    //无按键按下
  464.         {
  465.                 key=1;
  466.         }

  467.         return 0;
  468. }
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:123289 发表于 2022-4-8 13:46 | 只看该作者
删除一句,运行N次。如果你认为可以,就删掉。反之就留着。
回复

使用道具 举报

板凳
ID:1016612 发表于 2022-4-9 21:27 | 只看该作者
yzwzfyz 发表于 2022-4-8 13:46
删除一句,运行N次。如果你认为可以,就删掉。反之就留着。

这。。。。。。
回复

使用道具 举报

地板
ID:139866 发表于 2022-4-13 11:58 | 只看该作者
如果你觉得沙发的的办法比较笨,那我就告诉你一个显得他的方法不那么笨的方式
把你这程序完完全全弄明白了,包括1602的配置使用,io口检测,也就是你说的按键,定时器,中断,串口配置,包括你用的这款芯片的 数据手册
相比之下还是沙发给的方法更省时省力吧
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表