一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何用C語言操作寄存器——瑞薩RA系列FSP庫開發(fā)實戰(zhàn)指南(10)

瑞薩MCU小百科 ? 來源:瑞薩MCU小百科 ? 2025-04-22 15:30 ? 次閱讀

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

寄存器結構體定義

由于寄存器的數(shù)量是非常之多的,如果每個寄存器都用像*((uint32_t*)(0x40080000+0x0020*1))這樣的方式去訪問的話,會顯得很繁瑣、很麻煩。為了更方便地訪問寄存器,我們會借助C語言結構體的特性去定義寄存器和寄存器位域,這是通用的做法。

列表2:代碼清單3?2使用結構體封裝外設寄存器

左右滑動查看完整內容

// 注:關于輸入輸出端口的聲明
/* C 語言: IO definitions (access restrictions to peripheral registers) */
//#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 輸出數(shù)據)*/
} 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 輸入數(shù)據)*/
__IM?uint32_t?EIDR :?16;?/*!< [31..16] Pmn Event Input Data
(引腳 Pmn 事件輸入數(shù)據)*/
} 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<<0); //清零 PODR 寄存器的第 0?位
R_PORT0->PODR &= ~(1u<<6); //清零 PODR 寄存器的第 6?位


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

3.4.2.2

對寄存器上的某N個位進行置位

使用C語言的按位或“|”運算符可以將位進行置一。

列表5:代碼清單3?5位置位:按位或|

//置位某個位
R_PORT0->PODR |= 1u<<0; //PODR 寄存器的第 0?位置 1
R_PORT0->PODR |= 1u<<6; //PODR 寄存器的第 6?位置 1


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

3.4.2.3

對寄存器上的某N個位進行取反

使用C語言的按位異或“^”運算符可以將位進行取反。

列表6:代碼清單3?6位取反:按位異或^

//取反某個位
R_PORT0->PODR ^= 1u<<0; //取反 PODR 寄存器的第 0?位
R_PORT0->PODR ^= 1u<<6; //取反 PODR 寄存器的第 6?位


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

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • mcu
    mcu
    +關注

    關注

    146

    文章

    17718

    瀏覽量

    358182
  • 寄存器
    +關注

    關注

    31

    文章

    5401

    瀏覽量

    122779
  • 瑞薩
    +關注

    關注

    36

    文章

    22356

    瀏覽量

    87579
  • C語言
    +關注

    關注

    180

    文章

    7628

    瀏覽量

    139683
  • FSP
    FSP
    +關注

    關注

    0

    文章

    39

    瀏覽量

    7306

原文標題:如何用C語言操作寄存器——瑞薩RA系列FSP庫開發(fā)實戰(zhàn)指南(10)

文章出處:【微信號:瑞薩MCU小百科,微信公眾號:瑞薩MCU小百科】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    RA系列MCU FSP開發(fā)實戰(zhàn)指南(09)存儲映射

    3.3 存儲映射 前文所述,寄存器與RAM、FLASH一樣都是芯片內部的一種存儲設備。那么,當我們需要訪問它們的時候,我們需要知道它們的存儲地址。 3.3.1 存儲映射表 如下圖所示為RA
    的頭像 發(fā)表于 04-16 15:52 ?508次閱讀
    <b class='flag-5'>瑞</b><b class='flag-5'>薩</b><b class='flag-5'>RA</b><b class='flag-5'>系列</b>MCU <b class='flag-5'>FSP</b><b class='flag-5'>庫</b><b class='flag-5'>開發(fā)</b><b class='flag-5'>實戰(zhàn)</b><b class='flag-5'>指南</b>(09)存儲<b class='flag-5'>器</b>映射

    e2studio(1)----芯片之搭建FSP環(huán)境

    視頻教學 樣品申請 請勿添加外鏈 e2studio軟件 e2studio是的集成開發(fā)環(huán)境,FSP 提供了眾多可提高效率的工具,用于開發(fā)
    發(fā)表于 09-30 15:28

    RA2L1入門學習】RA2L1開發(fā)環(huán)境搭建

    e2 studio 和 FSP 的下載、安裝及使用指南 1. 什么是 e2 studio 和 FSP? e2 studio 是電子(Re
    發(fā)表于 03-07 11:33

    RA2系列開發(fā)板體驗】RA2L1試用筆記

    前言??早聽說過這個芯片品牌,好像是電賽的贊助商。有機會申請到了RA2L1 的開發(fā)板試用,因為工作上會用到CAN通信所以專門選了帶CAN通信接口的那款
    發(fā)表于 12-14 15:15

    RA4系列開發(fā)板體驗】開發(fā)環(huán)境搭建和新手點燈指南

    RA4系列開發(fā)板體驗】開發(fā)環(huán)境搭建和新手點燈指南
    發(fā)表于 11-24 22:54

    RA4系列開發(fā)板體驗】Keil開發(fā)環(huán)境搭建+初探IO操作

    前言: 非常感謝電子發(fā)燒友和生態(tài)工作室能夠給這次試用開發(fā)板的機會,后續(xù)根據生RA態(tài)工作室提供的資料進行功能測試。此篇根據RA Smart
    發(fā)表于 11-29 14:50

    RA4系列開發(fā)板體驗】10. 我的試用總結

    之前發(fā)帖:【RA4系列開發(fā)板體驗】1. 新建工程+按鍵控制LED【
    發(fā)表于 12-10 22:34

    RA4系列開發(fā)板體驗】體驗過程

    、使用 RASC 生成 Keil 工程+點亮LED參照“ 【RA4系列開發(fā)板體驗】2. 使用RASC 生成 Keil 工程+點亮LED
    發(fā)表于 12-18 16:20

    【野火啟明6M5開發(fā)板體驗】開箱+認識開發(fā)板+資料

    按鍵檢測29. WiFi——模塊通訊板尺寸:3、資料:*附件:[野火EmbedFire]《RA系列FSP
    發(fā)表于 12-20 23:28

    基于RA4M2的表盤設計

    :Renesas RA Smart Configurator 4.2.0,單片機不想STM32 傳統(tǒng)的庫函數(shù)直接驅動,自己有個FSP-Renesas Flexible Softwa
    發(fā)表于 03-22 19:31

    C語言寄存器操作

    C語言寄存器操作
    發(fā)表于 01-13 12:56 ?6次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>:<b class='flag-5'>寄存器</b><b class='flag-5'>操作</b>

    C語言操作寄存器的常見手法

    使用C語言寄存器賦值時,常常需要用到C語言的位操作方法。把
    的頭像 發(fā)表于 03-12 09:06 ?3618次閱讀

    【有獎直播預報名】電子RA系列產品開發(fā)工具之FSP4.0.0新特性介紹

    為使用電子RA系列ARM微控制的嵌入式系統(tǒng)設計提供簡單易用且可擴展的高質量軟件。 直播主題
    的頭像 發(fā)表于 11-22 12:20 ?861次閱讀

    【視頻教程】RA單片機FSP開發(fā)(3)FSP架構-解釋Blinky架構[上]

    干貨分享 前篇回顧 【視頻教程】RA單片機FSP開發(fā)(1)環(huán)境搭建(帶RASC) 【視頻教程】
    的頭像 發(fā)表于 12-06 12:15 ?1075次閱讀

    使用e2 studio FSP基于RA2E1定時配置PWM輸出

    使用e2 studio FSP基于RA2E1定時配置PWM輸出
    的頭像 發(fā)表于 08-01 00:13 ?1037次閱讀
    使用<b class='flag-5'>瑞</b><b class='flag-5'>薩</b>e2 studio <b class='flag-5'>FSP</b>基于<b class='flag-5'>RA</b>2E1定時<b class='flag-5'>器</b>配置PWM輸出