歡迎回到我們的RA系列FSP庫開發(fā)實戰(zhàn)指南頻道,下面我們將繼續(xù)講解“自己寫庫——構(gòu)建庫函數(shù)雛形”部分:
8.2.5定義IO初始化結(jié)構(gòu)體
由上述IOPORT相關(guān)功能的枚舉類型我們可以知道,在對IOPORT模塊進(jìn)行初始化時需要根據(jù)情況配置它們。因此我們定義一個IOPORT初始化的結(jié)構(gòu)體類型IOPORT_Init_t,它的成員包括了由上述所有枚舉類型所聲明的變量,因此該結(jié)構(gòu)體類型的變量可以包含IOPORT的相關(guān)功能配置。
列表5:代碼清單8-4:ra_ioport.h文件
左右滑動查看完整內(nèi)容
/* IOPORT 初始化結(jié)構(gòu)體類型定義 */
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操作函數(shù)
我們把IO操作函數(shù)的聲明和IO初始化函數(shù)的聲明都放在ra_ioport.h頭文件。
列表6:代碼清單8-5:ra_ioport.h文件
左右滑動查看完整內(nèi)容
/* IO 操作函數(shù)(調(diào)用一次只能操作一個 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 初始化函數(shù)(調(diào)用一次只能初始化一個 IO 引腳) */ voidIOPORT_Init(IOPORT_Init_t *ioport_init);
然后在ra_ioport.c源文件里面實現(xiàn)這些IO操作函數(shù)。
列表7:代碼清單8-6:ra6m5_ioport.c文件
左右滑動查看完整內(nèi)容
/* 讀引腳電平 */
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);
}
/* 翻轉(zhuǎn)引腳電平 */
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初始化函數(shù)
最后編寫IOPORT初始化函數(shù)。
列表8:代碼清單8-7:ra_ioport.c文件
左右滑動查看完整內(nèi)容
/* IOPORT 初始化函數(shù) */
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;?//設(shè)置輸入上拉
}
elseif(ioport_init->Dir==IO_DIR_OUTPUT)/* 用作輸出模式 */
{
pfs_bits |= (ioport_init->Dir) <2;?//設(shè)置為輸出
pfs_bits |= (ioport_init->Level) <0;?//設(shè)置輸出電平
pfs_bits |= (ioport_init->Mode) <6;?//設(shè)置輸出模式
pfs_bits |= (ioport_init->Drive) <10;?//設(shè)置輸出驅(qū)動能力
}
}
else
{
//我們不考慮引腳用作復(fù)用模式和模擬輸入輸出模式的情況
//也不考慮中斷的情況,僅考慮普通的 GPIO 輸入輸出功能
}
/* 寫入配置到寄存器 PmnPFS */
R_PFS->PORT[ioport_init->Port>>8].PIN[ioport_init->Pin].PmnPFS= pfs_
→bits;
}
8.2.8hal_entry入口函數(shù)
前一章節(jié)實驗里有講過,當(dāng)使用RTOS時,程序從main函數(shù)開始進(jìn)行線程調(diào)度;當(dāng)沒有使用RTOS時,C語言程序的入口函數(shù)main函數(shù)調(diào)用了hal_entry函數(shù)。本章節(jié)實驗的工程也是沒有選用RTOS的,因此,用戶程序是從hal_entry函數(shù)開始執(zhí)行。
打開“srchal_entry.c”文件,我們在“hal_entry.c”文件中添加對頭文件“ra_ioport.h”的包含,然后在hal_entry函數(shù)里面編寫我們的代碼。
以啟明6M5開發(fā)板為例,RA6M5工程的hal_entry數(shù)代碼如下所示。
注解
啟明4M2開發(fā)板和啟明2L1開發(fā)板的用戶可直接打開配套的“09_Register_MyLib”例程查看該代碼,限于篇幅,不在本章中貼出。
列表9:代碼清單8-8:hal_entry.c文件
左右滑動查看完整內(nèi)容
/* IOPORT 模塊頭文件 (自己寫庫——構(gòu)建庫函數(shù)雛形) */
#include"ioport/ra_ioport.h"
voidhal_entry(void)
{
/*TODO:add your own code here */
/* 調(diào)用取消寫保護(hù)函數(shù) */
IOPORT_PinAccessEnable();
/* 使用 IOPORT 初始化結(jié)構(gòu)體和調(diào)用初始化函數(shù)來配置 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 模式,而不是復(fù)用功能模式或其他
的
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);//調(diào)用初始化函數(shù),進(jìn)行 LED1 引腳初始化
led_io_init.Pin = IO_PIN_03;//更換引腳號
IOPORT_Init(&led_io_init);//結(jié)構(gòu)體其他屬性不變,再次調(diào)用初始化函數(shù),進(jìn)行 LED2 引
腳初始化
led_io_init.Pin = IO_PIN_04;//更換引腳號
IOPORT_Init(&led_io_init);//結(jié)構(gòu)體其他屬性不變,再次調(diào)用初始化函數(shù),進(jìn)行 LED3 引
腳初始化
/** 此時 3 個 LED 燈的引腳默認(rèn)輸出的是高電平,所以 3 個 LED 燈都會默認(rèn)不亮
* 我們先打開所有 LED 燈,然后在 while 循環(huán)里讓 LED1 閃爍:每秒鐘翻轉(zhuǎn)一次狀態(tài)
*/
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)
{
/* 使用函數(shù) IOPORT_PinToggle 翻轉(zhuǎn) 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下載驗證
編寫好上述代碼,然后將程序編譯并下載到開發(fā)板之后,按下復(fù)位按鍵來復(fù)位開發(fā)板,可以觀察到實驗現(xiàn)象與上一章的實驗現(xiàn)象相同:開發(fā)板上面除了電源指示燈之外的3個LED燈當(dāng)中有兩個燈常亮,還有一個燈在緩慢閃爍。閃爍著的LED燈為LED1,它每秒鐘(1000毫秒)便改變一次亮滅的狀態(tài)。
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4419瀏覽量
67687 -
開發(fā)板
+關(guān)注
關(guān)注
26文章
6334瀏覽量
119243 -
結(jié)構(gòu)體
+關(guān)注
關(guān)注
1文章
131瀏覽量
11400 -
FSP
+關(guān)注
關(guān)注
0文章
48瀏覽量
7767
發(fā)布評論請先 登錄
RT-Thread自動初始化詳解
自動初始化機(jī)制原理詳解
C語言結(jié)構(gòu)體使用
LED實驗中把結(jié)構(gòu)體定義放在時鐘初始化后出現(xiàn)報錯
C51的結(jié)構(gòu)體初始化編譯錯誤
定時器初始化結(jié)構(gòu)體定義
【原創(chuàng)分享】變量的初始化技巧
STM32f1單片機(jī)的HAL庫是如何去定義定時器相關(guān)的初始化結(jié)構(gòu)體的
利用結(jié)構(gòu)體數(shù)組方便地控制單片機(jī)IO相關(guān)資料推薦
USART初始化結(jié)構(gòu)體詳解
結(jié)構(gòu)體數(shù)組的初始化
結(jié)構(gòu)體的定義、初始化和賦值
STM32的IO口基本操作:初始化結(jié)構(gòu)體,設(shè)置系統(tǒng)時鐘,開啟外設(shè)時鐘資料下載
GraniStudio:IO初始化以及IO資源配置例程
定義IO初始化結(jié)構(gòu)體
評論