会员登录 - 用户注册 - 设为首页 - 加入收藏 - 网站地图 如何用C言语操作寄存器——瑞萨RA系列FSP库开发实战攻略(10)!

如何用C言语操作寄存器——瑞萨RA系列FSP库开发实战攻略(10)

时间:2025-05-23 12:46:53 来源:锐评时讯 作者:新闻 阅读:294次

3.4。

如何用。C言语。操作。寄存器。

3.4.1。

C言语对寄存器的封装。

前面的一切关于存储器映射的内容,终究都是为咱们更好地了解如何用C言语操控读写外设寄存器做准备,因而此处是本章的要点内容。

3.4.1.1。

外设模块基地址界说。

在。编程。上为了便利了解和回忆,咱们要把外设模块基地址以相应的宏界说起来,外设基地址都以它们的姓名作为宏名的组成部分。以下是IO。端口。外设基地址的宏界说。

列表1:代码清单3‑1 IOPORT外设基地址宏界说。

左右滑动检查完好内容。

/* 外设基地址 */#defineR_PORT0_BASE 0x40080000#defineR_PORT1_BASE 0x40080020#defineR_PORT2_BASE 0x40080040#defineR_PORT3_BASE 0x40080060#defineR_PORT4_BASE 0x40080080#defineR_PORT5_BASE 0x400800A0#defineR_PORT6_BASE 0x400800C0#defineR_PORT7_BASE 0x400800E0#defineR_PORT8_BASE 0x40080100#defineR_PORT9_BASE 0x40080120#defineR_PORT10_BASE 0x40080140#defineR_PORT11_BASE 0x40080160#defineR_PFS_BASE 0x40080800#defineR_PMISC_BASE 0x40080D00。

3.4.1.2。

寄存器结构体界说。

因为寄存器的数量是十分之多的,假如每个寄存器都用像*((uint32_t*)(0x40080000+0x0020*1))这样的办法去拜访的话,会显得很繁琐、很费事。为了更便利地拜访寄存器,咱们会凭借C言语结构体的特性去界说寄存器和寄存器位域,这是通用的做法。

列表2:代码清单3‑2运用结构体封装外设寄存器。

左右滑动检查完好内容。

// 注:关于输入输出端口的声明/* C 言语: IO defini。ti。ons (。ac。cess restrictions to peripheral registe。rs。) *///#define __I volatile const /*!< Defines 'read only'␣,→permissions *///#define __O volatile /*!< Defines 'write only'␣,→permissions *///#define __IO volatile /*!< Defines 'read / write'␣,→permissions *//* 下面的宏界说用于结构体成员 *//* following defines should be used for structure members *///#define __IM volatile const /*! Defines 'read only'␣,→structure member permissions *///#define __OM volatile /*! Defines 'write only'␣,→structure member permissions *///#define __IOM volatile /*! Defines 'read / write'␣,→structure member permissions *///typedef unsigned char uint8_t;//typedef unsigned short int uint16_t; /* 无符号 16 位整型变量 *///typedef unsigned int uint32_t; /* 无符号 32 位整型变量 *//*** brief I/O Ports (R_PORT0)*/typedefstruct /*!< ( 0x40040000) R_PORT0␣,→Structure */{union{union{__IOM uint32_t PCNTR1; /*!< ( 0x00000000) Port Control␣,→Register 1 */struct{__IOM uint32_t PDR : 16; /*!< [15..0] Pmn Direction(引脚Pmn 方向)*/__IOM uint32_t PODR : 16; /*!< [31..16] Pmn Output Data(引脚Pmn 输出数据)*/} PCNTR1_b;};/* ... 代码过长省掉 ... */};union{union{__IM uint32_t PCNTR2; /*!< ( 0x00000004) Port Control␣,→Register 2 */struct{__IM uint32_t PIDR : 16; /*!< [15..0] Pmn Input Data(引脚Pmn 输入数据)*/__IM uint32_t EIDR : 16; /*!< [31..16] Pmn Event Input Data(引脚 Pmn 事情输入数据)*/} PCNTR2_b;};/* ... 代码过长省掉 ... */};union{union{__OM uint32_t PCNTR3; /*!< ( 0x00000008) Port Control␣,→Register 3 */struct{__OM uint32_t POSR : 16; /*!< [15..0] Pmn Output Set(引脚Pmn 输出置位)*/__OM uint32_t PORR : 16; /*!< [31..16] Pmn Output Reset(引脚Pmn 输出复位)*/} PCNTR3_b;};/* ... 代码过长省掉 ... */};union{union{__IOM uint32_t PCNTR4; /*!< ( 0x0000000C) Port Control␣,→Register 4 */struct{__IOM uint32_t EOSR : 16; /*!< [15..0] Pmn Event Output Set(引脚 Pmn 事情输出置位)*/__IOM uint32_t EORR : 16; /*!< [31..16] Pmn Event Output␣→Reset(引脚 Pmn 事情输出复位)*/} PCNTR4_b;};/* ... 代码过长省掉 ... */};} R_PORT0_Type; /*!< Size = 16 (0x10) */。< Defines 'read only'␣,→permissions *///#define __O volatile /*!< Defines 'write only'␣,→permissions *///#define __IO volatile /*!< Defines 'read / write'␣,→permissions *//* 下面的宏定义用于结构体成员 *//* following defines should be used for structure members *///#define __IM volatile const /*! Defines 'read only'␣,→structure member permissions *///#define __OM volatile /*! Defines 'write only'␣,→structure member permissions *///#define __IOM volatile /*! Defines 'read / write'␣,→structure member permissions *///typedef unsigned char uint8_t;//typedef unsigned short int uint16_t; /* 无符号 16 位整型变量 *///typedef unsigned int uint32_t; /* 无符号 32 位整型变量 *//*** @brief I/O Ports (R_PORT0)*/typedefstruct /*!< (@ 0x40040000) R_PORT0␣,→Structure */{union{union{__IOM uint32_t PCNTR1; /*!< (@ 0x00000000) Port Control␣,→Register 1 */struct{__IOM uint32_t PDR : 16; /*!< [15..0] Pmn Direction(引脚Pmn 方向)*/__IOM uint32_t PODR : 16; /*!< [31..16] Pmn Output Data(引脚Pmn 输出数据)*/} PCNTR1_b;};/* ... 代码过长省略 ... */};union{union{__IM uint32_t PCNTR2; /*!< (@ 0x00000004) Port Control␣,→Register 2 */struct{__IM uint32_t PIDR : 16; /*!< [15..0] Pmn Input Data(引脚Pmn 输入数据)*/__IM uint32_t EIDR : 16; /*!< [31..16] Pmn Event Input Data(引脚 Pmn 事件输入数据)*/} PCNTR2_b;};/* ... 代码过长省略 ... */};union{union{__OM uint32_t PCNTR3; /*!< (@ 0x00000008) Port Control␣,→Register 3 */struct{__OM uint32_t POSR : 16; /*!< [15..0] Pmn Output Set(引脚Pmn 输出置位)*/__OM uint32_t PORR : 16; /*!< [31..16] Pmn Output Reset(引脚Pmn 输出复位)*/} PCNTR3_b;};/* ... 代码过长省略 ... */};union{union{__IOM uint32_t PCNTR4; /*!< (@ 0x0000000C) Port Control␣,→Register 4 */struct{__IOM uint32_t EOSR : 16; /*!< [15..0] Pmn Event Output Set(引脚 Pmn 事件输出置位)*/__IOM uint32_t EORR : 16; /*!< [31..16] Pmn Event Output␣→Reset(引脚 Pmn 事件输出复位)*/} PCNTR4_b;};/* ... 代码过长省略 ... */};} R_PORT0_Type; /*!< Size = 16 (0x10) */

3.4.1.3。

外设模块寄存器界说。

咱们在上一步现已界说好了R_PORT0_Type类型的结构体,它包含了IOPORT的寄存器界说。接下来运用宏界说来表明结构体指针,指针指向IOPORT外设的每个端口的寄存器首地址。

列表3:代码清单3‑3寄存器界说。

#defineR_PORT0 ((R_PORT0_Type *) R_PORT0_BASE)#defineR_PORT1 ((R_PORT0_Type *) R_PORT1_BASE)#defineR_PORT2 ((R_PORT0_Type *) R_PORT2_BASE)#defineR_PORT3 ((R_PORT0_Type *) R_PORT3_BASE)#defineR_PORT4 ((R_PORT0_Type *) R_PORT4_BASE)#defineR_PORT5 ((R_PORT0_Type *) R_PORT5_BASE)#defineR_PORT6 ((R_PORT0_Type *) R_PORT6_BASE)#defineR_PORT7 ((R_PORT0_Type *) R_PORT7_BASE)#defineR_PORT8 ((R_PORT0_Type *) R_PORT8_BASE)#defineR_PORT9 ((R_PORT0_Type *) R_PORT9_BASE)#defineR_PORT10 ((R_PORT0_Type *) R_PORT10_BASE)
。这样便功德圆满了,咱们就能够运用这些宏来拜访各个IO端口的每一个寄存器了。3.4.2。

修正寄存器操作的实质:读-改-写。

有了以上的对IOPORT这个外设模块的寄存器的界说,咱们便完成了“C言语对寄存器的封装”这个过程,接下来咱们便能够运用C言语对寄存器进行各种操作了。对寄存器进行操作可所以疏忽寄存器本来的值,而直接掩盖写入新的值;可是更为一般的操作是。

依据本来的寄存器值进行修正。,即:先读出寄存器本来的值,然后修正该值,最终从头写入到寄存器里边,让新的值收效。

接下来将介绍修正寄存器的几种通用办法。3.4.2.1。

清零寄存器上的某N个位。

运用C言语的按位与“&”运算符能够将位进行清零。

列表4:代码清单3‑4位清零:按位与&。

//清零某个位R_PORT0->PODR &= ~(1u。
PODR &= ~(1u。<<0); //清零 PODR 寄存器的第 0 位R_PORT0->PODR &= ~(3u。<<6); //清零 PODR 寄存器的第 6 位//清零多个位R_PORT0->PODR &= ~(3u。<<0); //清零 PODR 寄存器的第 0,1 位R_PORT0-><<6); //清零 PODR 寄存器的第 6,7 位
3.4.2.2。

对寄存器上的某N个位进行置位。

运用C言语的按位或“|”运算符能够将位进行置一。

列表5:代码清单3‑5方位位:按位或|。

//置位某个位R_PORT0->PODR |= 1u。
PODR |= 1u。<<0; //PODR 寄存器的第 0 位置 1R_PORT0->PODR |= 3u。<<6; //PODR 寄存器的第 6 位置 1//置位多个位R_PORT0->PODR |= 3u。<<0; //PODR 寄存器的第 0,1 位置 1R_PORT0-><<6; //PODR 寄存器的第 6,7 位置 1
3.4.2.3。

对寄存器上的某N个位进行取反。

运用C言语的按位异或“^”运算符能够将位进行取反。

列表6:代码清单3‑6位取反:按位异或^。

//取反某个位R_PORT0->PODR ^= 1u。
PODR ^= 1u。<<0; //取反 PODR 寄存器的第 0 位R_PORT0->PODR ^= 3u。<<6; //取反 PODR 寄存器的第 6 位//取反多个位R_PORT0->PODR ^= 3u。<<0; //取反 PODR 寄存器的第 0,1 位R_PORT0->

内容来源:https://nlsngoisaoviet.com/app-1/phần mềm hack tài xỉu trên điện thoại,http://chatbotjud-teste.saude.mg.gov.br/app-1/win-757-bet

(责任编辑:新闻)

    系统发生错误

    系统发生错误

    您可以选择 [ 重试 ] [ 返回 ] 或者 [ 回到首页 ]

    [ 错误信息 ]

    页面发生异常错误,系统设置开启调试模式后,刷新本页查看具体错误!