歡迎回到我們的RA系列FSP庫開發實戰指南頻道,下面我們將繼續講解“自己寫庫——構建庫函數雛形”部分:
8.2.5定義IO初始化結構體
由上述IOPORT相關功能的枚舉類型我們可以知道,在對IOPORT模塊進行初始化時需要根據情況配置它們。因此我們定義一個IOPORT初始化的結構體類型IOPORT_Init_t,它的成員包括了由上述所有枚舉類型所聲明的變量,因此該結構體類型的變量可以包含IOPORT的相關功能配置。
列表5:代碼清單8-4:ra_ioport.h文件
左右滑動查看完整內容
/* IOPORT 初始化結構體類型定義 */ typedefstruct { IO_Port_tPort; IO_Pin_tPin; IO_Mode_tMode; IO_Dir_tDir; IO_OType_tOType; IO_DriveCapability_tDrive; IO_Level_tLevel; IO_Pull_tPull; } IOPORT_Init_t;
8.2.6編寫IO操作函數
我們把IO操作函數的聲明和IO初始化函數的聲明都放在ra_ioport.h頭文件。
列表6:代碼清單8-5:ra_ioport.h文件
左右滑動查看完整內容
/* IO 操作函數(調用一次只能操作一個 IO 引腳) */ uint32_tIOPORT_PinRead(IO_Port_t port, IO_Pin_t pin); voidIOPORT_PinWrite(IO_Port_t port, IO_Pin_t pin, IO_Level_t? →level); voidIOPORT_PinToggle(IO_Port_t port, IO_Pin_t pin); voidIOPORT_PinAccessEnable(void); voidIOPORT_PinAccessDisable(void); /* IO 初始化函數(調用一次只能初始化一個 IO 引腳) */ voidIOPORT_Init(IOPORT_Init_t *ioport_init);
然后在ra_ioport.c源文件里面實現這些IO操作函數。
列表7:代碼清單8-6:ra6m5_ioport.c文件
左右滑動查看完整內容
/* 讀引腳電平 */ uint32_tIOPORT_PinRead(IO_Port_t port, IO_Pin_t pin) { /* Read pin level. */ returnR_PFS->PORT[port >>8].PIN[pin].PmnPFS_b.PIDR; } /* 寫引腳電平 */ voidIOPORT_PinWrite(IO_Port_t port, IO_Pin_t pin, IO_Level_t level) { uint32_t pfs_bits =R_PFS->PORT[port >>8].PIN[pin].PmnPFS;//讀寄存器? →PmnPFS pfs_bits &= ~(uint32_t)0x1;//清零 PODR 位 R_PFS->PORT[port >>8].PIN[pin].PmnPFS= (pfs_bits | level); } /* 翻轉引腳電平 */ voidIOPORT_PinToggle(IO_Port_t port, IO_Pin_t pin) { uint32_t pfs_bits =R_PFS->PORT[port >>8].PIN[pin].PmnPFS;//讀寄存器? →PmnPFS pfs_bits ^= (uint32_t)0x1;//取反 PODR 位 R_PFS->PORT[port >>8].PIN[pin].PmnPFS= pfs_bits; } /* 引腳訪問使能 */ voidIOPORT_PinAccessEnable(void) { R_PMISC->PWPR=0;///< Clear BOWI bit - writing to PFSWE bit? →enabled R_PMISC->PWPR= 1U << 6U;?///< Set PFSWE bit - writing to PFS register? →enabled } /* 引腳訪問禁止 */ voidIOPORT_PinAccessDisable(void) { R_PMISC->PWPR=0;///< Clear PFSWE bit - writing to PFS register? →disabled R_PMISC->PWPR= 1U << 7U;?///< Set BOWI bit - writing to PFSWE bit? →disabled }
8.2.7編寫IO初始化函數
最后編寫IOPORT初始化函數。
列表8:代碼清單8-7:ra_ioport.c文件
左右滑動查看完整內容
/* IOPORT 初始化函數 */ voidIOPORT_Init(IOPORT_Init_t *ioport_init) { uint32_t pfs_bits =0;//不讀取寄存器 PmnPFS if(ioport_init->Mode==IO_MODE_GPIO)//如果引腳用作普通 GPIO 功能 { if(ioport_init->Dir==IO_DIR_INPUT)/* 用作輸入模式 */ { pfs_bits |= (ioport_init->Pull) <4;?//設置輸入上拉 } elseif(ioport_init->Dir==IO_DIR_OUTPUT)/* 用作輸出模式 */ { pfs_bits |= (ioport_init->Dir) <2;?//設置為輸出 pfs_bits |= (ioport_init->Level) <0;?//設置輸出電平 pfs_bits |= (ioport_init->Mode) <6;?//設置輸出模式 pfs_bits |= (ioport_init->Drive) <10;?//設置輸出驅動能力 } } else { //我們不考慮引腳用作復用模式和模擬輸入輸出模式的情況 //也不考慮中斷的情況,僅考慮普通的 GPIO 輸入輸出功能 } /* 寫入配置到寄存器 PmnPFS */ R_PFS->PORT[ioport_init->Port>>8].PIN[ioport_init->Pin].PmnPFS= pfs_ →bits; }
8.2.8hal_entry入口函數
前一章節實驗里有講過,當使用RTOS時,程序從main函數開始進行線程調度;當沒有使用RTOS時,C語言程序的入口函數main函數調用了hal_entry函數。本章節實驗的工程也是沒有選用RTOS的,因此,用戶程序是從hal_entry函數開始執行。
打開“srchal_entry.c”文件,我們在“hal_entry.c”文件中添加對頭文件“ra_ioport.h”的包含,然后在hal_entry函數里面編寫我們的代碼。
以啟明6M5開發板為例,RA6M5工程的hal_entry數代碼如下所示。
注解
啟明4M2開發板和啟明2L1開發板的用戶可直接打開配套的“09_Register_MyLib”例程查看該代碼,限于篇幅,不在本章中貼出。
列表9:代碼清單8-8:hal_entry.c文件
左右滑動查看完整內容
/* IOPORT 模塊頭文件 (自己寫庫——構建庫函數雛形) */ #include"ioport/ra_ioport.h" voidhal_entry(void) { /*TODO:add your own code here */ /* 調用取消寫保護函數 */ IOPORT_PinAccessEnable(); /* 使用 IOPORT 初始化結構體和調用初始化函數來配置 PFS 寄存器 */ IOPORT_Init_t led_io_init; led_io_init.Port = IO_PORT_04; led_io_init.Pin = IO_PIN_00; led_io_init.Mode = IO_MODE_GPIO;//普通 GPIO 模式,而不是復用功能模式或其他 的 led_io_init.Dir = IO_DIR_OUTPUT; led_io_init.OType = IO_OTYPE_PP; led_io_init.Drive = IO_DRIVE_LOW; led_io_init.Level = IO_LEVEL_HIGH;//輸出高電平(LED 熄滅) //LED_IO_Init.Pull = IO_NO_PULL; //端口方向處于輸出模式下是用不了上拉的,所以這 個屬性沒意義 IOPORT_Init(&led_io_init);//調用初始化函數,進行 LED1 引腳初始化 led_io_init.Pin = IO_PIN_03;//更換引腳號 IOPORT_Init(&led_io_init);//結構體其他屬性不變,再次調用初始化函數,進行 LED2 引 腳初始化 led_io_init.Pin = IO_PIN_04;//更換引腳號 IOPORT_Init(&led_io_init);//結構體其他屬性不變,再次調用初始化函數,進行 LED3 引 腳初始化 /** 此時 3 個 LED 燈的引腳默認輸出的是高電平,所以 3 個 LED 燈都會默認不亮 * 我們先打開所有 LED 燈,然后在 while 循環里讓 LED1 閃爍:每秒鐘翻轉一次狀態 */ IOPORT_PinWrite(IO_PORT_04, IO_PIN_00, IO_LEVEL_LOW);//點亮 LED1 IOPORT_PinWrite(IO_PORT_04, IO_PIN_03, IO_LEVEL_LOW);//點亮 LED2 IOPORT_PinWrite(IO_PORT_04, IO_PIN_04, IO_LEVEL_LOW);//點亮 LED3 while(1) { /* 使用函數 IOPORT_PinToggle 翻轉 LED1 引腳電平 */ IOPORT_PinToggle(IO_PORT_04, IO_PIN_00); R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS); } #ifBSP_TZ_SECURE_BUILD /* Enter non-secure code */ R_BSP_NonSecureEnter(); #endif }
8.3下載驗證
編寫好上述代碼,然后將程序編譯并下載到開發板之后,按下復位按鍵來復位開發板,可以觀察到實驗現象與上一章的實驗現象相同:開發板上面除了電源指示燈之外的3個LED燈當中有兩個燈常亮,還有一個燈在緩慢閃爍。閃爍著的LED燈為LED1,它每秒鐘(1000毫秒)便改變一次亮滅的狀態。
-
函數
+關注
關注
3文章
4380瀏覽量
64848 -
開發板
+關注
關注
25文章
5679瀏覽量
104629 -
結構體
+關注
關注
1文章
131瀏覽量
11113 -
FSP
+關注
關注
0文章
44瀏覽量
7421
原文標題:定義IO初始化結構體——瑞薩RA系列FSP庫開發實戰指南(21)
文章出處:【微信號:瑞薩MCU小百科,微信公眾號:瑞薩MCU小百科】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
RT-Thread自動初始化詳解

LED實驗中把結構體定義放在時鐘初始化后出現報錯
定時器初始化結構體定義
【原創分享】變量的初始化技巧
STM32f1單片機的HAL庫是如何去定義定時器相關的初始化結構體的
利用結構體數組方便地控制單片機IO相關資料推薦
結構體數組的初始化
結構體的定義、初始化和賦值
STM32的IO口基本操作:初始化結構體,設置系統時鐘,開啟外設時鐘資料下載

C語言指定初始化器解析及其應用

評論