基于ucosII操作系统的数采装置设计,设计LED 、LCD 、BEEP、 CAN通信、ADC。

题目及要求

课程名称: 嵌入式系统与应用

考试形式:□专题研究报告 □论文 √大作业 □综合考试 一、题目:“基于ucosII操作系统的数采装置设计” 二、报告内容

1 功能综述
(1)进行ADC采集,对于每一路,默认设置为当1000<ADC<2000时,低门限报警,蜂鸣器1Hz报警;当2000<ADC<3900时,高门限报警,蜂鸣器10Hz报警;当ADC<5或这ADC>3900时,故障报警,蜂鸣器100Hz报警;
(2)使用两个LED灯分别指示故障报警和超限报警,(故障报警时LED灯常亮、超限报警时LED灯的报警频率1Hz);
(3)报警优先级:故障>高报>低报(同时存在多种报警时,按此优先级进行报警);
(4)主界面LCD实时显示ADC的采集值与当前时间。当处于正常状态时使用绿色小方块标记表示,处于高报状态时使用红色小方块,处于低报时,使用黄色方块,处于故障时使用黑色小方块,并实时更新;
图1 开发板LCD显示界面
(5)具有开机自检功能,自检有三个自检过程:正常工作状态自检、报警状态自检、故障状态自检,并具有以下功能:
1)三个自检过程在开机时自动进行,每种持续一分钟,结束后进入主界面。
2)正常工作状态自检时,LCD显示当前自检模式;报警状态自检时LCD显示当前自检模式和ADC当前的高低门限值,LED和蜂鸣器报警(蜂鸣器先低报后高报,分别30秒);故障状态自检时,LCD显示当前自检模式,LED与蜂鸣器指示报警。
(6)具有CAN总线或以太网通信功能(两者中选择其中一个实现即可),将采集到的ADC的值,通过CAN总线或者以太网发送给上位机显示(如图2或图3所示)。
在这里插入图片描述

图2 CAN总线通信模式下 演示方法(串口调试助手能否收到开发板ADC数据即可)
在这里插入图片描述

图3 以太网通信模式下 演示方法(网口助手能否收到开发板ADC数据即可)

2 硬件设计

2.1 硬件组成

(1)ADC信号转化模块
本模块用到的硬件是ADC。STM32F4xx 系列一般都有 3 个 ADC,这些 ADC 可以独立使用,也可以使用双重/三重模式(提高采样率)。 STM32F4 的 ADC 是 12 位逐次逼近型的模拟数字转换器。它具有多达 19 个复用通道,可测量来自 16 个外部源、两个内部源和 VBAT 通道的信号。这些通道的 A/D 转换可在单次、连续、扫描或不连续采样模式下进行。 ADC 的结果存储在一个左对齐或右对齐的 16 位数据寄存器中。ADC 具有模拟看门狗特性,允许应用检测输入电压是否超过了用户自定义的阈值上限或下限。
ADC属于STM32F4内部资源,实际上我们只需要软件设置就可以正常工作,不过我们需要在外部连接其端口到被测电压上面。我们通过ADC1的通道5(PA5)、通道6(PA6)、通道7(PA7来读取外部电压值,探索者 STM32F4 开发板没有设计参考电压源在上面,但板上有几个可以提供测试的地方:1,3.3V电源。2,GND。3,后备电池。然后我们需要注意的是:这里不能接到板上5V 电源上去测试,这可能会烧坏ADC !
图2.1.1为整个数采装置硬件结构设计示意图,共使用37个MCU引脚,使用ADC、内部温度传感器、FSMC等内部资源,以及LCD、LED、KEY、BEEP、光敏传感器等外部硬件。
在这里插入图片描述
(2)LED报警模块
本模块硬件用到 LED(DS0 和 DS1)。其电路在 ALIENTEK 探索者 STM32F4 开发板上默认是已经连接好了的。DS0 接 PF9,DS1 接 PF10。所以在硬件上不需要动任何东西。其连接原理图如图2.1.2下:
在这里插入图片描述
(3)BEEP蜂鸣器报警模块
本模块用到的硬件是BEEP蜂鸣器。ALIENTEK 探索者 STM32F4 开发板板载了一个有源蜂鸣器,有源蜂鸣器是指自带了震荡电路的蜂鸣器,这种蜂鸣器一接上电就会自己震荡发声。而如果是无源蜂鸣器,则需要外加一定频率(2~5Khz)的驱动信号,才会发声。蜂鸣器在硬件上也是直接连接好了的,不需要经过任何设置,直接编写代码就可以了。蜂鸣器的驱动信号连接在STM32F4 的 PF8 上。如图2.1.3所示:
在这里插入图片描述
图中我们用到一个 NPN 三极管(S8050)来驱动蜂鸣器,R61 主要用于防止蜂鸣器的误发声。当 PF.8 输出高电平的时候,蜂鸣器将发声,当PF.8 输出低电平的时候,蜂鸣器停止发声。
(4)LCD显示屏报警模块
TFT-LCD(Thin Film Transistor)液晶显示屏是薄膜晶体管型液晶显示屏,也就是“真彩”(TFT)。TFT液晶为每个像素都设有一个半导体开关,每个像素都可以通过点脉冲直接控制,因而每个节点都相对独立,并可以连续控制,不仅提高了显示屏的反应速度,同时可以精确控制显示色阶,所以TFT液晶的色彩更真。特点是亮度好、对比度高、层次感强、颜色鲜艳,但也存在着比较耗电和成本过高的不足。本次实验使用的是分辨率为:800*480。ALIENTEK 探索者 STM32F4 开发板板载的 LCD 模块接口电路如图 2.1.4所示:在这里插入图片描述
LCD 接口连接在 STM32F407ZGT6的 FSMC 总线上面,可以显著提高 LCD 的刷屏速度。图中的 T_MISO/T_MOSI/T_PEN/T_CS/T_CS 用来实现对液晶触摸屏的控制(支持电阻屏和电容屏)。LCD_BL则控制 LCD 的背光。液晶复位信号 RESET 则是直接连接在开发板的复位按钮上,和 MCU 共用一个复位电路。
(5)CAN通信模块
CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO 国际标准化的串行通信协议。CAN 控制器根据两根线上的电位差来判断总线电平。总线电平分为显性电平和隐性电平二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。CAN 通信具有以下特点:多主控制、系统的柔软性、通信速度较快,通信距离远、具有错误检测、错误通知和错误恢复功能、故障封闭功能、连接节点多。
在这里插入图片描述

2.2 工作原理

本实验中分别使用了ADC模块、LED模块、BEEP模块、CAN模块、LCD模块。首先进行开机自检任务,其次ADC模块是将采集到的模拟信号转换为数字信号,然后再将采集到的ADC值发送到邮箱。LCD模块、LED模块、BEEP模块则分别接收来自邮箱的ADC值,再针对不同的值做出与其对应的响应与状态;与此同时,LCD模块还将实时显示ADC模块的采样值,上位机接收CAN模块传送的ADC值。

3 软件流程及架构设计

3.1系统总体构架和信息流

如图3.1所示,对主程序进行了一个详细说明,本次实验使用ucosⅡ系统,共创建7个任务,使用4个消息邮箱和1个消息队列来传递各任务所需要的信号。
七个任务的优先级与其功能如表3.1所示。
表3.1 系统任务介绍
任务 优先级 功能简介
ADC_TASK 4 获取外部电压值,通过adcMsg发送给lcd_task,对比电压值得到状态参数值,通过msg_alarm_led、msg_alarm_beep发给led任务和beep任务。
Self_check_TASK_ 5 接收定时器输出的值,实现不同状态页面的显示,达到自检的目的;同时发送不同状态对应的参数值给led任务和beep任务。
LCD_TASK 6 接收来自adc任务传递的电压值,通过TFT显示屏反馈对应状态的颜色块变换。
LED_TASK 7 接收来自adc任务和自检任务传递的参数值,反馈对应状态的响应。
BEEP_TASK 8 接收来自adc任务和自检任务传递的参数值,反馈对应状态的响应
CAN_TASK 9 接收来自adc任务传递的电压值,提取高低位,通过串口传输给上位机。
START_TASK 20 创建其他任务
在这里插入图片描述
在这里插入图片描述
图3.2 系统之间消息的传递
如图3.1、3.2所示,一共创建了七个任务。包括start_task、adc_task、led_task、beep_task、lcd_task、can_task、self_check_task,ADC将采集的数据通过邮箱发送给LED进行闪烁指示,BEEP进行鸣响指示,另外通过消息队列和邮箱发送给LCD进行采集数据的显示以及报警块的显示。具体实现过程如下:创建一个消息队OS_EVENT * msg_adc进行ADC采集数据与其他任务之间的通信,另外设计的报警优先级的思路是利用四个if判断语句,如果三路ADC满足的条件相同输出一个值,若不同输出的值自上而下更新,最新输出满足最下面的一条if语句的值,从而实现总报警块按优先级的报警指示。在四个界面通过按键传递邮箱与主任务进行通信,在主任务里面进行页面切换。自检任务是通过邮箱向lcd_task发送消息来控制不同自检时的界面显示,通过邮箱向led_task和beep_task任务发送消息实现不同自检时的灯和蜂鸣器控制。
3.2软件框架图及信息流
(1)初始任务START_TASK
START_TASK初始任务的优先级最低,在START_TASK初始任务里面创建了adc_task、led_task、beep_task、lcd_task、can_task、self_check_task,六个子任务,同时还创建了msg_adc消息队列,msg_alarm_beep、msg_alarm_led、msg_alarm_lcd、msg_state四个消息邮箱,最后将adc_task、lcd_task、can_task、start_task都挂起,让自检任务优先执行,如图3.3所示。
在这里插入图片描述
(2)自检任务
开机自检任务包括四个过程:正常工作自检、低限工作自检、高限工作自检、故障状态自检和退出界面。然后退出自检,显示工作界面,如图3.4所示。
①正常状态:从邮箱请求到的值为1或2,表示这是正常状态的页面,显示“normal state”,正常状态的字样和正常状态对应的绿色,然后列出正常的状态的上下限值,分别为1000和5。
②低限状态:从邮箱请求到的值为3,表示这是低限状态的页面,显示“low alarm state”,低限状态的字样和低限状态对应的黄色,然后列出低限的状态的上下限值,分别为2000和1000。
③高限状态:从邮箱请求到的值为4,表示这是高限状态的页面,显示“low alarm state”,高限状态的字样和高限状态对应的红色,然后列出高限的状态的上下限值,分别为3900和2000。
④故障状态:从邮箱请求到的值为5,表示这是故障状态的页面,显示“low alarm state”,故障状态的字样和故障状态对应的黑色,然后列出故障的状态的下限值,为3900。
⑤退出界面状态:从邮箱请求到的值为6,表示这是退出界面的页面,然后恢复adc惹任务、lcd任务、can任务,删除自检任务。
在这里插入图片描述
(3)ADC采样任务
如图3.5所示,ADC采样任务从通道PA5、PA6、PA7三个通道获取不同的电压值,这样可以避免一个通道的数据异常造成误判,三组数值更有参考性。首先将三组数值存入消息队列adcMsg然后发送给msgadc邮箱,方便后续的LCD任务和CAN通信任务请求数据。然后在对每一组数据进行比对,是否存在数值分别在51000之间、10002000之间、2000~3900之间或者3900以上,当满足以上四种情况的时候,分别给予状态参数alarm分别等于1、2、3、4,然后将alarm的数值发送给消息邮箱msg_alarm_led、msg_alarm_beep。在这里插入图片描述
(4)LCD显示任务
如图3.6所示,LCD显示任务先向从ADC任务传出的msgadc邮箱请求传参,然后再屏幕正上方显示对应的时分秒、年月日的时间,同时划线显示三个通道的ADC具体数值,接着判断每一通道的数值是在51000之间、10002000之间、20003900之间或者3900以上这四种状态的哪一种,则在屏幕上的具体数字后面画框显示对应状态的颜色,51000之间代表正常状态是绿色、10002000之间代表低限状态是黄色、20003900之间代表高限状态是红色、3900以上是故障状态是黑色。在这里插入图片描述
(5)LED任务
如图3.7所示,LED任务可以接受来自自检任务和ADC任务发来的数据,虽然ADC任务的优先级比自检任务的优先级更高,但是在START任务中,将ADC任务、LCD任务和CAN通信任务都挂起,所以LED任务先接受来自自荐任务发送的数据,这数据是对系统不同状态对应参数值,如果值为1,则让DS1的绿灯进行闪烁,DS0的红灯不亮;如果值为2,则让DS0的红灯以1HZ的频率进行闪烁,DS1的绿灯不亮;如果值为3,则让DS0的红灯以10HZ的频率进行闪烁,DS1的绿灯不亮;如果值为4,则让DS0、DS1的红灯、绿灯同时亮不熄灭。
当自检任务完成后,将自检任务挂起,同时恢复ADC任务,这时LED任务就接收来自ADC任务的数据,只不过led灯反馈情况与自检任务一样,如果值为1,则让DS1的绿灯进行闪烁,DS0的红灯不亮;如果值为2,则让DS0的红灯以1HZ的频率进行闪烁,DS1的绿灯不亮;如果值为3,则让DS0的红灯以10HZ的频率进行闪烁,DS1的绿灯不亮;如果值为4,则让DS0、DS1的红灯、绿灯同时亮不熄灭。
在这里插入图片描述

图3.7 LED任务流程图
(6)BEEP蜂鸣器任务
如图3.8所示,BEEP蜂鸣器任务同样可以接受来自自检任务和ADC任务发来的数据,虽然ADC任务的优先级比自检任务的优先级更高,但是在START任务中,将ADC任务、LCD任务和CAN通信任务都挂起,所以BEEP蜂鸣器任务先接受来自自荐任务发送的数据,这数据是对系统不同状态对应参数值,如果值为1,给予蜂鸣器低电平,蜂鸣器不响;如果值为2,给予蜂鸣器高电平,让蜂鸣器以1HZ的频率响;如果值为3,给予蜂鸣器高电平,让蜂鸣器以10HZ的频率响;如果值为4,给予蜂鸣器高电平,让蜂鸣器以100HZ的频率响;当自检任务完成后,将自检任务挂起,同时恢复ADC任务,这时LED任务就接收来自ADC任务的数据,只不过led灯反馈情况与自检任务一样,如果值为1,给予蜂鸣器低电平,蜂鸣器不响;如果值为2,给予蜂鸣器高电平,让蜂鸣器以1HZ的频率响;如果值为3,给予蜂鸣器高电平,让蜂鸣器以10HZ的频率响;如果值为4,给予蜂鸣器高电平,让蜂鸣器以100HZ的频率响。
在这里插入图片描述

图3.8 BEEP蜂鸣器任务流程图
(7)CAN通信任务
如图3.9所示,CAN通信任务先向msg_adc邮箱请求到ADC任务得到电压值,然后对电压值进行移位和提取,分为了高8位和低8位,然后将两个数据存入数组,利用循环将数组的数据发送出去,在上位机的串口助手就可看到CAN任务发出来的数据。
在这里插入图片描述

图3.9 CAN通信任务流程图

4 实验结果

上电后首先进入自检界面,共四个自检过程,每个自检历时1分钟;如图4.1所示,进入正常状态的自检,屏幕显示绿色的“normal state”,用绿色方块表示正常状态,然后DS1绿灯以10HZ频率闪烁,DS0红灯不亮,蜂鸣器不响,同时正常状态电压值的上下限为5~1000;如图4.2所示,进入低限状态的自检,屏幕显示黄色的“low alarm state”,用黄色方块表示低限状态,然后DS1绿灯不亮,DS0红灯以1HZ频率闪烁30s,蜂鸣器以1HZ的频率响30s,同时低限状态电压值的上下限为1000~2000;如图4.3所示,进入高限状态的自检,屏幕显示红色的“high alarm state”,用红色方块表示高限状态,然后DS1绿灯不亮,DS0红灯以10HZ频率闪烁30s,蜂鸣器以10HZ的频率响30s,同时高限状态电压值的上下限为20003900;如图4.4所示,进入故障状态的自检,屏幕显示黑色的“faulty_condition”,用黑色方块表示故障状态,然后DS1绿灯和DS0红灯常亮,蜂鸣器以100HZ的频率响,同时高限状态电压值的上下限为20003900;然后自检全部结束进入菜单主界面。

在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如图4.5所示,进入主界面后,界面左上角显示时钟右上角显示日期。接着画横线,LCD显示屏幕接着显示三个通道的ADC采样电通道,然后在其后面显示对应通道的电压值,当ADC采样值高于3900方块变为黑色,蜂鸣器100Hz鸣叫,LED常亮;ADC采样值在20003900之间,DS1绿灯不亮,DS0红灯以10HZ频率闪烁30s,蜂鸣器以10HZ的频率响,方块显示红色;ADC采样值在20003900之间,然后DS1绿灯不亮,DS0红灯以1HZ频率闪烁,蜂鸣器以1HZ的频率响,状态方块为黄色;ADC采样值在5~1000之间,然后DS1绿灯以10HZ闪烁,DS0红灯不亮,蜂鸣器不响,状态方块为绿色。
我选取了三个通道,当三个通道的电压值处于不同的电压区间,属于不同状态的时候,则取电压最大,状态最严重的电压值输送给蜂鸣器与LED灯,这样确保了数据的准确性,同时也更能起到警示作用。
在这里插入图片描述

#include "includes.h"   
#include "sys.h"
#include "delay.h"  
#include "usart.h"   
#include "led.h"
#include "lcd.h"
#include "key.h"         
#include "beep.h"     
#include "includes.h" 
#include "adc.h"
#include "rtc.h"
#include "usmart.h"
#include "24cxx.h"
#include "myiic.h"
#include "can.h"

// 定义初始任务///

//开始任务
#define START_TASK_PRIO      		    20
#define START_STK_SIZE  				    64	
OS_STK START_TASK_STK[START_STK_SIZE];
void start_task(void *pdata);	
 
 //ADC任务
#define ADC_TASK_PRIO       			  4
#define ADC_STK_SIZE  		    		  128
OS_STK ADC_TASK_STK[ADC_STK_SIZE];
void adc_task(void *pdata); 
 
//开机自检self-check
#define Self_check_TASK_PRIO        5
#define Self_check_STK_SIZE         128
OS_STK Self_check_TASK_STK[Self_check_STK_SIZE];
void self_check_task(void *pdata);

//LCD显示任务
#define LCD_TASK_PRIO               6
#define LCD_STK_SIZE                128
OS_STK LCD_TASK_STK[LCD_STK_SIZE];
void lcd_task(void *pdata);

//LED任务
#define LED_TASK_PRIO       			  7
#define LED_STK_SIZE  		    		  128
OS_STK LED_TASK_STK[LED_STK_SIZE];
void led_task(void *pdata);
 
//BEEP任务
#define BEEP_TASK_PRIO       			  8  
#define BEEP_STK_SIZE  		    		  128
OS_STK BEEP_TASK_STK[BEEP_STK_SIZE];
void beep_task(void *pdata);

//CAN通信任务
#define CAN_TASK_PRIO               9
#define CAN_STK_SIZE                128
OS_STK CAN_TASK_STK[CAN_STK_SIZE];
void can_task(void *pdata);


// 定义全部事件//
OS_EVENT * msg_adc;//ADC事件		  	        
OS_EVENT * msg_alarm_beep;//蜂鸣器    
OS_EVENT * msg_alarm_lcd;//lcd屏幕
OS_EVENT * msg_alarm_led;//led灯
OS_EVENT * mas_self_check;//开机自检
OS_EVENT * msg_state;
OS_TMR   * tmr;	//软件定时器
void * ADCGrp[256];//消息队列存储地址,最大支持256个消息

// main函数及全部的初始化//
int main(void)
{
    
	  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                    //设置系统中断优先级分组2
	  delay_init(168);                                                   //初始化延时函数
	  uart_init(115200);		                                             //初始化串口波特率为115200
    Adc_Init();                                                        //初始化ADC
	  LED_Init();					                                               //初始化LED 
	  LCD_Init();	   		                                                 //初始化LCD 
	  BEEP_Init();				                                               //蜂鸣器初始化	
	  LCD_Clear(WHITE);	                                                 //清屏                                                                             
	  OSInit();  	 				                                               //初始化UCOSII
    OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务 
	  OSStart();	    
}

创建起始任务/
void start_task(void *pdata)
{
   
  OS_CPU_SR cpu_sr=0;
	pdata = pdata;
	 //创建事件	
  msg_adc
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值