瑞薩RA0單片機(jī)連載之基于面向?qū)ο蟮腖ED燈
在我試用了好幾十種單片機(jī)后,發(fā)現(xiàn),每個(gè)單片機(jī)都需要重復(fù)造輪子,感覺(jué)非常的累,比如OLED屏,每次都需要去重寫(xiě)他的驅(qū)動(dòng),這樣非常耗時(shí)耗精力,在看到《百問(wèn)網(wǎng)》的RA0E1 系列的單片機(jī),希望能第一次搭建自己的http://m.butianyuan.cn/article/202410/463707.htm
1 創(chuàng)建工程
此次創(chuàng)建工程,我采用RASC+MDK 來(lái)開(kāi)發(fā)。
1.打開(kāi)FSP for RASC,創(chuàng)建基礎(chǔ)的工程:
2.選擇生成MDK5 的工程,芯片選擇對(duì)象的型號(hào):
3.選擇非RTOS
4.選擇生成最小系統(tǒng)的工程:
5.打開(kāi)原理圖,查看開(kāi)發(fā)板給用戶(hù)可以使用的LED燈,有兩個(gè)LED 是可以提供給我們用戶(hù)的,分別為P103、P104:
6.配置這兩個(gè)IO 為輸出模式:
7.配置好后,生成工程,并打用MDK 打開(kāi)工程:
8.在工程中,我添加applications、devices、include、libs、drivers。這四個(gè)文件夾是學(xué)習(xí)百問(wèn)網(wǎng)的
其中他的功能如下:
1)應(yīng)用程序位于applications 目錄下,用于存放業(yè)務(wù)相關(guān)的代碼,它們可能是多個(gè)模塊對(duì)象的聯(lián)調(diào),也可能是數(shù)據(jù)的處理。比如“根據(jù)按鍵操作LED”,這就屬于應(yīng)用層的代碼。按鍵和LED 的操作函數(shù),不屬于應(yīng)用層,而是屬于底下的設(shè)備層。這一層需要和底層驅(qū)動(dòng)完全解耦合:這一層的代碼移植到其它平臺(tái)時(shí),無(wú)需修改代碼。
2)頭文件位于include 目錄下,主要存放error.h 和confi g.h,前者用于統(tǒng)一錯(cuò)誤代碼,后者用于配置整個(gè)工程。
3)設(shè)備層位于devices目錄。簡(jiǎn)單設(shè)備的文件直接放在devices目錄里;對(duì)于模塊,在devices 目錄下根據(jù)模塊名字創(chuàng)建一個(gè)子目錄,用來(lái)存放模塊的文件。在dev_xxx.h 中根據(jù)設(shè)備的特性定義一些結(jié)構(gòu)體,在dev_xxx.c 里實(shí)現(xiàn)了這些結(jié)構(gòu)體,并使用鏈表來(lái)管理同類(lèi)設(shè)備。上層代碼獲取這些結(jié)構(gòu)體后,就可以直接調(diào)用結(jié)構(gòu)的函數(shù)指針來(lái)操作設(shè)備。
4)驅(qū)動(dòng)層位于drivers目錄,存放的平臺(tái)相關(guān)的驅(qū)動(dòng)源代碼。drivers.h:根據(jù)confi g.h 中的宏開(kāi)關(guān),包含drv_xxx.h。drv_xxx.h:接口,供外部代碼調(diào)用。drv_xxx.h:驅(qū)動(dòng)代碼,一般用來(lái)實(shí)現(xiàn)并注冊(cè)dev_xxx.h 中聲明的結(jié)構(gòu)體,會(huì)調(diào)用平臺(tái)提供的HAL 庫(kù)。
【注】以上4 點(diǎn)說(shuō)明引用《百問(wèn)網(wǎng)》的內(nèi)容,如有侵權(quán)請(qǐng)聯(lián)系刪除。
在devices 文件夾中添加一個(gè)LED 文件夾,創(chuàng)建led.h/c。
led.h 中定義結(jié)構(gòu)體來(lái)定義LED 的init、on、off 方法。
view plaincopy to clipboardprint?
1. #ifndef __LED_H__
2. #defi ne __LED_H__
3.
4. typedef struct LedDev{
5. int (*Init)(struct LedDev *ptdev);
6. void (*On)(void);
7. void (*Off )(void);
8. }LedDevice;
9.
10. struct LedDev *LedGetDevice(void);
11.
12. #endif
Led.c 中實(shí)例化LED 對(duì)象代碼如下:
view plaincopy to clipboardprint?
1. #include “devices.h”
2. #include “hal_data.h”
3. #include <libs.h>
4. #include <errno.h>
5. #include <stdio.h>
6. #include “l(fā)ed.h”
7.
8. static void LedON(void);
9. static void LedOFF(void);
10. static int LedDevInit(struct LedDev *ptdev);
11.
12. static struct LedDev gDevice = {
13. .Init = LedDevInit,
14. .On = LedON,
15. .Off = LedOFF,
16. };
17.
18. static IODevice *gLedDevice;
19.
20. struct LedDev *LedGetDevice(void)
21. {
22. return &gDevice;
23. }
24.
25.
26. static int LedDevInit(struct LedDev *ptdev)
27. {
28. if(NULL == ptdev) return -EINVAL;
29. gLedDevice = IODeviceFind(“LED”);
30. if(NULL == gLedDevice)
31. {
32. printf(“Failed to fi nd LED!rn”);
33. return -ENXIO;
34. }
35. if(ESUCCESS != gLedDevice->Init(gLedDevice))
36. {
37. printf(“Failed to init GPIO!rn”);
38. return -EIO;
39.
40. }
41. return ESUCCESS;
42.
43. }
44.
45. static void LedON(void)
46. {
47. gLedDevice->Write(gLedDevice,1);
48. }
49.
50. static void LedOFF(void)
51. {
52. gLedDevice->Write(gLedDevice,0);
53. }
在app.c 中初始化LED 并添加測(cè)試函數(shù):
view plaincopy to clipboardprint?
1. void led_blink(void)
2. {
3. UartDevicesRegister();
4. IODevicesRegister();
5. LedDevice *pDevice = LedGetDevice();
6. if(NULL == pDevice)
7. {
8. printf(“Error. There is no LED device!rn”);
9. return;
10. }
11. pDevice->Init(pDevice);
12. printf(“startrn”);
13. while(1)
14. {
15. printf(“startrn”);
16. pDevice->On();
17. R_BSP_SoftwareDelay(1,BSP_DELAY_UNITS_
SECONDS);
18. pDevice->Off();
19. R_BSP_SoftwareDelay(1,BSP_DELAY_UNITS_
SECONDS);
20. }
21. }
至此面向?qū)ο蟮腖ED 就完成了,初始化多個(gè)LED只需要需要添加實(shí)例化的LED 就行了,移植到其他芯片,只需要重新定義一下dev_gpio 中的IO 就行了。
(本文來(lái)源于《EEPW》202410)
評(píng)論