1.E53_SF1擴展板及其驅動
關於E53標准接口
E53接口標准的E取自擴展(Expansion)的英文首字母,板子的尺寸為5×3cm,故采用E53作為前綴來命名尺寸為 5cm*3cm 類型的案例擴展板,任何一款滿足標准設計的開發板均可直接適配E53擴展板。
E53擴展板是根據不同的應用場景來設計的,以最大的程度在擴展板上還原真實應用場景,不同案例的擴展板根據不同的應用場景來命名后綴。例如:E53_SC1,SC是智慧城市(Smart City)的縮寫,SC1表示的是智慧城市中的智慧路燈,再比如SC2則表示的是智慧城市中的智慧井蓋。
E53擴展接口在電氣特性上,包含了常用的物聯網感知層傳感器通信接口,比如5V、3.3V、GND、SPI、UART、IIC、ADC、DAC等等,可以適配各種傳感器,還留有4個普通GPIO,如圖:
E53_SF1智慧消防擴展板
E53_SF1擴展板采用了E53標准接口,包含了一個可燃氣體傳感器MQ-2,一個無源蜂鳴器,一個LED,其中無源蜂鳴器使用定時器輸出PWM信號控制,LED使用普通GPIO控制,可燃氣體傳感器的數據使用ADC讀取。
2. 移植E53_SF1驅動到LiteOS
復制裸機驅動文件到LiteOS工程
本文中所使用的驅動文件,直接將用於產生PWM的定時器TIM16初始化配置代碼和ADC初始化配置代碼,所以無需復制其它底層文件。
IoT-Studio中提供的默認工程已經包含了該驅動文件,無需再次添加,如圖:
添加驅動文件路徑
因為 LiteOS 的整個項目工程使用 make 構建,所以復制驅動文件之后,需要添加驅動文件的路徑到 makefile 中,加入編譯。
之前我們都是在project.mk
中直接添加,這里我們使用一種更加簡便有效的方法,直接在user_demo.mk
中配置,只有當開啟了該demo后,才會添加這些驅動文件路徑,不會造成沖突:
在user_demo.mk中添加如下代碼:
#example for e53_sf1_driver_demo
ifeq ($(CONFIG_USER_DEMO), "e53_sf1_driver_demo")
user_hardware_src = ${wildcard $(TOP_DIR)/targets/STM32L431_BearPi/Hardware/E53_SF1/*.c}
user_hardware_inc = -I ${wildcard $(TOP_DIR)/targets/STM32L431_BearPi/Hardware/E53_SF1}
endif
添加位置如下:
至此,復制文件到LiteOS工程中,並將新復制的文件路徑添加到makefile中,如果開啟了該demo,則加入工程編譯,就完成了驅動的移植。
3. E53_SF1裸機驅動的使用
初始化E53_SF1擴展板
在第一篇文章中詳細的講述了在LiteOS中初始化設備的兩種方式:
- 在系統啟動調度之前初始化:設備在系統中隨時可被任意任務使用
- 在任務中初始化:設備一般只在該任務中被使用
本文中移植的 E53_SF1 擴展板驅動,不需要多個任務去操作,只需要傳感器數據采集任務操作即可,所以初始化放在數據采集任務中。
操作E53_SF1擴展板
接下來首先創建一個文件夾(如果已有,不用再次創建),用於存放本系列教程實驗的代碼:
在該文件夾中創建一個文件:
編寫代碼:
#include <osal.h>
#include "lcd.h"
#include "E53_SF1.h"
/* 存放E53_SF1擴展板傳感器數據,可在E53_SF1.h中查看定義 */
E53_SF1_Data_TypeDef E53_SF1_Data;
/* 用於數據采集和數據處理任務間同步的信號量 */
osal_semp_t sync_semp;
/* 數據采集任務-低優先級 */
static int data_collect_task_entry()
{
/* 初始化擴展板 */
Init_E53_SF1();
while (1)
{
/* 讀取擴展板板載數據,存到數據結構體E53_SF1_Data中 */
E53_SF1_Read_Data();
/* 數據讀取完畢,釋放信號量,喚醒數據處理任務 */
osal_semp_post(sync_semp);
/* 任務睡眠2s */
osal_task_sleep(2*1000);
}
}
/* 數據處理任務-高優先級 */
static int data_deal_task_entry()
{
/* smoke_value- 當次數據,old-smoke_value-上次數據 */
int smoke_value = 0, old_smoke_value = 0;
/* LCD清屏,防止干擾顯示 */
LCD_Clear(WHITE);
while (1)
{
/* 等待信號量,未等到說明數據還未采集,阻塞等待 */
osal_semp_pend(sync_semp, cn_osal_timeout_forever);
/* 信號量等待,被喚醒,開始處理數據 */
old_smoke_value = smoke_value;
smoke_value = (int)E53_SF1_Data.Smoke_Value;
printf("Smoke Value is %d\r\n", smoke_value);
LCD_ShowString(10, 100, 200, 16, 16, "Smoke Value is:");
LCD_ShowNum(140, 100, smoke_value, 5, 16);
/* 閾值為100,自動打開或關閉LED或蜂鳴器 */
if(old_smoke_value < 100 && smoke_value > 100)
{
E53_SF1_LED_StatusSet(ON);
E53_SF1_Beep_StatusSet(ON);
printf("Beep and Light ON!\r\n");
}
else if(old_smoke_value > 100 && smoke_value < 100)
{
E53_SF1_LED_StatusSet(OFF);
E53_SF1_Beep_StatusSet(OFF);
printf("Beep and Light OFF!\r\n");
}
}
}
/* 標准demo啟動函數,函數名不要修改,否則會影響下一步實驗 */
int standard_app_demo_main()
{
/* 創建信號量 */
osal_semp_create(&sync_semp, 1, 0);
/* 數據處理任務的優先級應高於數據采集任務 */
osal_task_create("data_collect",data_collect_task_entry,NULL,0x400,NULL,3);
osal_task_create("data_deal",data_deal_task_entry,NULL,0x400,NULL,2);
return 0;
}
然后按照之前的方法,在 user_demo.mk 中將e53_sf1_driver_demo.c
文件添加到makefile中,加入編譯:
最后在.sdkconfig
中配置開啟宏定義:
編譯,燒錄,即可看到實驗現象。
LCD屏幕上顯示當前傳感器采集的煙感值,並且每2s更新一次。
當煙感值高於100時,E53_SF1擴展板的LED燈自動點亮,蜂鳴器開始鳴叫:
當煙感值低於100時,E53_SF1擴展板的LED燈自動熄滅,蜂鳴器關閉鳴叫:
另外,打開IoT-Studio自帶的串口終端,可以查看到串口輸出的工作信息:
linkmain:V1.2.1 AT 09:31:53 ON Dec 8 2019
Smoke Value is 0
WELCOME TO IOT_LINK SHELL
LiteOS:/>Smoke Value is 0
Smoke Value is 0
Smoke Value is 0
Smoke Value is 0
Smoke Value is 279
Beep and Light ON!
Smoke Value is 103
Smoke Value is 88
Beep and Light OFF!
Smoke Value is 0
Smoke Value is 278
Beep and Light ON!
Smoke Value is 27
Beep and Light OFF!
……