欢迎回到我们的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文章
4383浏览量
65020 -
开发板
+关注
关注
25文章
5707浏览量
105204 -
结构体
+关注
关注
1文章
131浏览量
11128 -
FSP
+关注
关注
0文章
45浏览量
7445
原文标题:定义IO初始化结构体——瑞萨RA系列FSP库开发实战指南(21)
文章出处:【微信号:瑞萨MCU小百科,微信公众号:瑞萨MCU小百科】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
RT-Thread自动初始化详解

LED实验中把结构体定义放在时钟初始化后出现报错
定时器初始化结构体定义
【原创分享】变量的初始化技巧
STM32f1单片机的HAL库是如何去定义定时器相关的初始化结构体的
利用结构体数组方便地控制单片机IO相关资料推荐
结构体数组的初始化
结构体的定义、初始化和赋值
STM32的IO口基本操作:初始化结构体,设置系统时钟,开启外设时钟资料下载

C语言指定初始化器解析及其应用

评论