这是一个稍微复杂一些的例子,程序的功能是这样的:我们通过串口按照规定的通信协议发送控制命令,而使单片机作出相应的动作,比如点亮LED、在LCD显示字符串、测量温度并显示等等。程序展示了命令、数据传输和命令处理的任务结构,是非常实用的一个模板。
其中,我们建立了四个任务,一个任务负责串口数据接收和通信协议处理,一个任务负责收到命令数据的处理,第三个任务负责温度值采样并显示,第四个任务闪烁一个LED。
串口数据的发送接收是用串口中断实现的,这个例子展示了在RTOS中中断函数要注意的问题。
串口通信协议规定如下:先发送两个单字节的起始字(#$),然后发送数据两次。通信协议很容易修改成自己需要的形式。不符合协议的数据流认为是通信出错,单片机能向上位机发回接收数据正确或出错的信息。
比如16进制:24253131, 0x24,0x25是起始字,命令值=0x31 ('1')
命令表:
所有任务启动以后,都等待串口发来的命令数据。一旦串口有数据传来,中断程序启动字节接收,将接收到的字节交给串口接收任务进行协议检查,获得符合协议的数据流以后,提取命令数据作为消息发送给命令处理任务;命令处理任务根据命令的具体内容做出相应处理,比如启动LED闪烁,显示温度值等等。
在这个例子中,我们看到了任务之间传递信息的几种方法:1. 消息 2.信号量 3.全局变量
我们还将看到,信号量除了用来在任务之间传递信息外,还可用来保证任务互斥使用共享资源。所谓共享资源就是多个任务可能使用到的资源,比如LCD显示器,命令处理任务和温度采集任务都要用到,但在某个时刻只能有一个任务使用它(独占),也就是说,一个任务正在使用LCD时,另外的任务就不能使用(互斥)。使用信号量可达到任务互斥使用共享资源,当一个任务正在使用共享资源时,信号量被置起,另外的任务也要使用这个共享资源时,先要查看相关的信号量,如果发现信号量被置起则等待,直到信号量被释放。
另外一个重要点就是函数的可重入性问题。
一个函数要被多个任务或中断同时调用,就必须是可重入的。比如本例中Putchar()函数。一个函数符合下列条件就具有可重入性:
本例中,Puchar()就是用了关中断宏OS_ENTER_CRITICAL()来实现。
测温程序实际上没有写,只是赋值模拟一下。
仿真用到虚拟串口COM3,COM4, Proteus中的串口设置为COM4,波特率9600, 晶振改成11.0592MHz(其他不改)
用串口调试工具向COM3发送数据就可看到结果,比如"#$aa"打开LED,"#$bb"关闭LED
仿真时的截图:
1.虚拟串口
2. Proteus
3.串口调试工具发送数据:
文章评论(0条评论)
登录后参与讨论