找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机使用外部中断0切换使用模式但是不成功,求大佬帮忙看一下

[复制链接]
跳转到指定楼层
楼主
ID:349989 发表于 2020-3-21 17:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
5黑币
RT最近在做一个小制作,用单片机设计一个时钟,我用外部中断0做了一个模式切换的功能,每按一下中断触发键就可以使变量mod加一。其他两个模式(时钟调整,闹钟调整)都能正常的切换,但是最后一个利用串口连接手机校准时间的模式无法正常切换,进去就卡在那里切不出去,实在是不知道为什么了,麻烦大佬帮我看一眼,多谢!代码写的少,可能写的很不好,如果有建议希望大佬多指教!
为了阅读方便我删去了前两个模式的代码,用定时器0来生成秒,send函数和receive函数利用了定时器1来生成波特率,串口校准模式的设计思路是先发送一个“1”给手机,再接收手机发送的“1”,确定连接建立后再接收手机发送的数据。因为手机端的开发还没做完,所以暂时测试只用来校准hour

单片机源程序如下:
  1. #include<reg52.h>

  2. typedef unsigned int u16;      //对数据类型进行声明定义
  3. typedef unsigned char u8;

  4. #define data8b P0

  5. sbit K1=P3^2;               //外部中断0
  6. sbit K2=P3^3;               //外部中断1
  7. sbit K3=P3^4;
  8. sbit K4=P3^5;
  9. sbit p=PSW^0;
  10. sbit RW=P2^1;        //4脚,数据(1)or命令(0)
  11. sbit RS=P2^0;        //5脚,读(1)写(0)
  12. sbit E=P2^2;         //6脚,使能信号

  13. u8 code dat1[]={0X30,0X31,0X32,0X33,
  14.                                    0X34,0X35,0X36,0X37,
  15.                                    0X38,0X39};
  16.                                             //LCD1602字符

  17.                                                                  
  18. u8 min=0,hour=0;              //时间初始化
  19. u16 i=0;
  20. u8 s=0;
  21. u8 mod=0;                         //mod初值
  22. bit signal=0;                       //发送                                          
  23. u8 temp=0;

  24.                     
  25.                                                                  

  26. void delay(u16 i)      //延时函数
  27. {
  28.     while(i--);
  29. }

  30. void open012()   //打开中断0,1,定时器中断0
  31. {
  32.     TMOD|=0X01;   //选择为定时器0模式,工作方式1
  33.   
  34.     ET0=1;        //打开定时器0中断允许
  35.     EA=1;        //打开总中断
  36.     TR0=1;       //打开定时器            
  37.     EX0=1;              //打开外部中断0
  38.     IT0=1;             //边沿触发方式
  39.     EX1=1;              //打开外部中断1
  40.     IT1=1;             //边沿触发
  41.   
  42. }


  43. void wrm(u8 dat)              //写入命令
  44. {
  45.     delay(1000);
  46.     RS=0;
  47.     RW=0;
  48.     E=0;
  49.     data8b=dat;
  50.     E=1;
  51.     delay(1000);
  52.     E=0;
  53. }


  54. void wrd(u8 dat)             //写入数据
  55. {
  56.     delay(1000);
  57.     RS=1;
  58.     RW=0;
  59.     E=0;
  60.     data8b=dat;
  61.     E=1;
  62.     delay(1000);
  63.     E=0;
  64. }

  65. void init()                  //LCD初始化
  66. {
  67.     wrm(0X38);                 //八位数据,两行显示,5*7
  68.     wrm(0X0c);                  //无光标,打开显示
  69.     wrm(0X06);                  //光标右移,屏幕不移动
  70.     wrm(0X01);                  //清屏
  71.     wrm(0X80);                  //设置数据指针起点
  72. }



  73. void display()
  74. {
  75.   wrd(dat1[hour/10]);                 //时十位
  76.     wrd(dat1[hour%10]);                 //时个位
  77.     wrd(0x3A);                     //:
  78.     wrd(dat1[min/10]);                 //分十位
  79.     wrd(dat1[min%10]);                 //分个位
  80.     wrd(0x3A);                     //:
  81.     wrd(dat1[(s/10)]);                 //秒十
  82.     wrd(dat1[(s%10)]);                 //秒个
  83. }


  84.      //秒个

  85. void chuli()                                  //处理进位
  86. {
  87.     if(min==60)
  88.     {
  89.         hour++;
  90.         min=0;
  91.     }

  92.     if(hour==24)
  93.     {
  94.    
  95.         hour=0;
  96.     }
  97.    
  98.     if(s==60)
  99.     {
  100.         min++;
  101.         s=0;
  102.     }
  103.    
  104. }

  105. void send()                                    //发送函数,定时器T1为方式2,串口为方式3,波特率9600,采用偶校验
  106. {
  107.     TMOD=0x20;
  108.     SCON=0xc0;
  109.     PCON=0x00;
  110.     TH1=0xfd;
  111.     TL1=0xfd;
  112.     TB8=P;
  113.     SBUF=1;
  114.     while(TI==0);
  115.     ;
  116.     TI==0;
  117. }

  118. u8 receive()                             //接收函数
  119. {
  120.     u8 dat;
  121.     TMOD=0x20;
  122.     SCON=0xd0;
  123.     PCON=0x00;
  124.     TH1=0xfd;
  125.     TL1=0xfd;
  126.     TR1=1;
  127.     REN=1;
  128.    
  129.     while(RI==0);
  130.     ;
  131.     RI==0;
  132.     ACC=SBUF;
  133.     if(RB8==P)
  134.     {
  135.         dat=ACC;
  136.         return dat;
  137.     }
  138. }

  139. void dis_string(u8 *pp, u16 n)                  //显示字符串的函数
  140. {
  141.     int i;
  142.     for (i=0;i<n;i++)
  143.     wrd(pp[i]);
  144. }

  145. u8 p1[]="connecting";
  146. u8 p2[]="OK!";
  147. u8 p3[]="over";



  148. void main()
  149. {
  150.     IP=1;
  151.     open012();
  152.     init();
  153.     chuli();
  154.     display();
  155.    
  156.    
  157.    
  158.    
  159.     while(1)
  160.     {
  161.         while(mod==0)
  162.     {
  163.         EX1=1;              //打开外部中断1
  164.         chuli();
  165.         wrm(0x80);
  166.         display();
  167.     }
  168.    
  169.         
  170.         
  171.         
  172.         while(mod==1)
  173.         {
  174.             init();
  175.             EX1=0;
  176.             TR0=0;
  177.             TR1=1;
  178.             dis_string(p1,10);                            //输出字符connecting
  179.             wrm(0x80+0x40);                                    //换行   
  180.             send();
  181.             delay(1000);
  182.             signal=receive();
  183.             while(1)
  184.             {
  185.                 if(signal=1)
  186.                 {
  187.                     dis_string(p2,3);                        //如果标志位=1,则连接成功,输出ok!;如果标志位为0,则继续接收
  188.                     break;   
  189.                 }
  190.             
  191.                 else if(signal=0)
  192.                 {
  193.                     signal=receive();
  194.                 }
  195.             }
  196.             send();
  197.             temp=receive();                                 //将接受数据装入temp中并赋给hour;
  198.             hour=temp;
  199.             init();
  200.             if(temp!=0)
  201.             {
  202.                 dis_string(p3,4);                             //输出over
  203.                 delay(1000);
  204.             }
  205.             
  206.                                              
  207.             TR1=0;
  208.             
  209.             }
  210.             }
  211.     }
  212.    

  213.    
  214.    
  215.             
  216.             

  217. void time0() interrupt 1
  218. {
  219.    TH0=0XFC;         //给定时器赋初值,定时1ms
  220.      TL0=0X18;
  221.      i++;
  222.      if(i==1000)     //ms转化为s
  223.      {
  224.         i=0;
  225.          s++;
  226.         
  227.      }   
  228. }

  229. void key1() interrupt 0     //外部中断0,切换模式
  230. {
  231.     EX0=0;
  232.     delay(1000);
  233.     if(K1==0)
  234.       {
  235.             
  236.           mod++;
  237.             while(!K1);
  238.       }

  239. if(mod>1)
  240. {
  241.     mod=0;
  242. }
  243.     EX0=1;
  244. }
复制代码

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

使用道具 举报

沙发
ID:235200 发表于 2020-3-21 21:15 | 只看该作者
所谓卡在那里是程序没有应答你的输入还是根本不知道程序运行到了哪里?仿真调试可能是串口被占用,烧录运行肯定是程序有BUG
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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