单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

注意了这些,才能更容易地写好单片机中断子程序

[复制链接]
跳转到指定楼层
楼主
单片机里面有很多中断资源,例如外部中断、定时器中断、串口中断等,这些中断资源应当用于处理相应的紧急事件,而不是顺序执行的常规事件,所以在编写中断子程序的时候应当十分注意。
具体的事务处理语句不应放在中断函数里面,中断子程序中的语句应当简洁明了,不应当有太多的语句。假如你在编写中断子程序的时候像在main函数中那样写一大串处理具体事务的指令的话,会在此中断中占用太多的时间,假如当有其他低优先级的中断信号来临的时候也可能导致中断丢失,发生程序的逻辑错误。所以,在中断子程序中的指令语句应当做到最短。
中断子程序中的语句不应当使用延时函数,不使用whiledo-whiledo-until等有等待延时功能的指令。在中断子程序中使用while、do-while、do-until等指令也会导致单片机在执行过程中在该位置延时或者等待太长的时间,当其他中断信号来临的时候同样也可能导致中断丢失。
那么应该怎么做呢?
在编写中断子程序的时候,应当巧用全局状态变量,在中断子程序中只改变状态变量值,在main函数中while(1)程序段内部判断该状态变量的值,根据状态变量的值再分别执行对应的事务处理语句。这就像你接到一个电话要你办某事,你也不能在一直接着电话把这件事做完吧,你需要把事情记下来,挂了电话再安排时间处理。
举个例子,一个串口触摸屏需要根据触屏中按键来执行对应的操作,需要使用到串口中断。假设触屏在触摸按键1时会发送数据A,触摸到按键2时会发送数据B,那么我们可以定义一个全局状态变量command:
unsigned char command;
在串口中断子程序中,根据接收到的不同串口数据改变command的值:
void 串口1中断函数()
{
switch (收到的串口数据)
{case A:  //假如收到按键1的动作,command赋值x1
{command=x1;
break;
}
case B:  //假如收到按键2的动作,command赋值x2
{command=x2;
break;
}
default: break;
}
}
在上面这个串口1的中断子程序中,switch是一个条件选择指令,当串口收到数据A,那么给command赋值x1, 当串口收到数据B,那么给command赋值x2。当然,上面的程序段只是一个说明的示意,不能直接复制编译到单片机中运行,在实际工程中需要根据不同单片机程序的编写规则进行开发。
接着在main函数中根据command的值执行不同的事务处理语句:
main函数()
{
while(1)
{
Switch(command)
{case x1:   //假如收到按键1的动作,执行事务处理1的程序
{事务处理1;
break;
}
case x2:  //假如收到按键2的动作,执行事务处理2的程序
{事务处理2;
break;
}
       default: break;
}
}
}
按照这样的程序,单片机在接收到触屏发出的代表不同按键的串口数据时,在串口中断子程序中改变全局状态变量的值command,这个语句很少,执行时间也短。再到main函数中根据command的不同值分别执行非常耗时间的具体事务处理程序。这样的程序分配,将使单片机运行高效而且合理。
中秋快乐!
沙鸥 乐山 2019.9.13

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

使用道具 举报

沙发
天使之泪雨扬 发表于 2019-9-13 19:36 | 只看该作者
感谢楼主热心分享,中秋佳节快乐!
回复

使用道具 举报

板凳
ttaniscy 发表于 2019-9-15 09:07 | 只看该作者
说得很好,值得大家注意这个问题,谢谢LZ
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

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