自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一篇帶你了解C語言訪問存儲(chǔ)器的方法

開發(fā) 后端
在單片機(jī)中我們經(jīng)常需要訪問某個(gè)指定的寄存器或者到指定的RAM地址,在本文為簡(jiǎn)單描述,下文所說的存儲(chǔ)器可指:寄存器,RAM等。

[[425144]]

在單片機(jī)中我們經(jīng)常需要訪問某個(gè)指定的寄存器或者到指定的RAM地址,在本文為簡(jiǎn)單描述,下文所說的存儲(chǔ)器可指:寄存器,RAM等。

01宏定義:

定義一個(gè)宏,將地址值轉(zhuǎn)化為C指針,然后取這個(gè)指針指向的內(nèi)容,這樣就可以訪問存儲(chǔ)了,代碼如下:

  1. #define SDA_DIR_REG  *(__IO uint32_t *)SDA_MOD_OFFSET 

分析:

(__IOuint32_t *)SDA_MOD_OFFSE 是強(qiáng)制類型轉(zhuǎn)換強(qiáng)制轉(zhuǎn)換為指針*(__IOuint32_t *)SDA_MOD_OFFSET 取這個(gè)指針里內(nèi)容。這是一種很簡(jiǎn)單實(shí)用的方法,對(duì)于訪問某個(gè)寄存器是很長(zhǎng)好用的。舉例:

  1. *(__IOuint16_t *) (((uint32_t)0x60020000) ) 

(((uint32_t)0x60020000))是32位的IO地址(物理地址,硬件上設(shè)定的,不可修改) *(__IO uint16_t*)是讀取該地址的參數(shù)值,其值為16位參數(shù)。

實(shí)際上是讀取0x60020000寄存器的參數(shù),或者可以說是這個(gè)IO口現(xiàn)在的狀態(tài)。

02結(jié)構(gòu)體:

將存儲(chǔ)器定義為一種數(shù)據(jù)結(jié)構(gòu),然后定義一個(gè)指向結(jié)構(gòu)體的指針。

符合CMSIS的設(shè)備驅(qū)動(dòng)庫(kù)就是這樣做的

  1. typedef struct 
  2.   __IO uint32_t MODER;   /*!< GPIO port mode register,          Address offset: 0x00      */ 
  3.   __IO uint32_t OTYPER;  /*!< GPIO port output type register,        Address offset: 0x04      */ 
  4.   __IO uint32_t OSPEEDR; /*!< GPIO port output speed register,       Address offset: 0x08      */ 
  5.   __IO uint32_t PUPDR;   /*!< GPIO port pull-up/pull-down register,  Address offset: 0x0C      */ 
  6.   __IO uint32_t IDR;     /*!< GPIO port input data register,         Address offset: 0x10      */ 
  7.   __IO uint32_t ODR;     /*!< GPIO port output data register,        Address offset: 0x14      */ 
  8.   __IO uint16_t BSRRL;   /*!< GPIO port bit set/reset low register,  Address offset: 0x18      */ 
  9.   __IO uint16_t BSRRH;   /*!< GPIO port bit set/reset high register, Address offset: 0x1A      */ 
  10.   __IO uint32_t LCKR;    /*!< GPIO port configuration lock register, Address offset: 0x1C      */ 
  11.   __IO uint32_t AFR[2];  /*!< GPIO alternate function registers,     Address offset: 0x20-0x24 */ 
  12. } GPIO_TypeDef; 
  13.  
  14. #define PERIPH_BASE      ((uint32_t)0x40000000) 
  15. #define AHB1PERIPH_BASE  (PERIPH_BASE + 0x00020000) 
  16. #define GPIOC_BASE       (AHB1PERIPH_BASE + 0x0800) 
  17. #define GPIOC            ((GPIO_TypeDef *)GPIOC_BASE) 

大家看著上面的代碼應(yīng)該很熟悉,這就是我在ST給的標(biāo)準(zhǔn)外設(shè)庫(kù)中復(fù)制的,這也是CMSIS標(biāo)準(zhǔn)的驅(qū)動(dòng)發(fā)方式。

我在《STM32驅(qū)動(dòng)LCD實(shí)戰(zhàn)》文中就是使用這種方式驅(qū)動(dòng)操作LCD。代碼如下。

  1. typedef struct 
  2.     uint8 LCD_CMD;//用于LCD命令操作 
  3.     uint8 LCD_DATA;//用于LCD數(shù)據(jù)操作 
  4. } LCD_TypeDef; 
  5. #define LCD_BASE        ((uint32_t)(0x60000000 | 0x0000FFFF)) 
  6. #define LCD             ((LCD_TypeDef *) LCD_BASE) 

詳解如下:

LCD->LCD_CMD :是地址((uint32_t)(0x60000000| 0x0000FFFF))上的數(shù)據(jù)LCD->LCD_DATA:是地址((uint32_t)(0x60000000| 0x00010000))上的數(shù)據(jù)這種驅(qū)動(dòng)方式更加簡(jiǎn)潔,代碼結(jié)構(gòu)化。個(gè)人也更喜歡這種方式。03對(duì)比

方法1:簡(jiǎn)單,但是生成代碼效率低,因?yàn)榧拇嫫鞯牡刂分刀紩?huì)被存儲(chǔ)為常量,代碼體積會(huì)變大。由于需要訪問的更多寄存器來設(shè)置地址值,運(yùn)行速度會(huì)更低。不過,若外設(shè)控制代碼值操作1個(gè)寄存器,效率就和方法2相同了方法2:允許外設(shè)中的多個(gè)寄存器共用一個(gè)常量作為基地址。訪問每個(gè)寄存器時(shí)可以用立即數(shù)偏移尋址模式。

本文轉(zhuǎn)載自微信公眾號(hào)「知曉編程」

 

責(zé)任編輯:姜華 來源: 知曉編程
相關(guān)推薦

2021-04-15 05:53:35

C# 索引器對(duì)象

2021-05-20 06:57:16

RabbitMQ開源消息

2021-08-11 07:02:21

npm包管理器工具

2022-01-15 10:02:03

Java Hashtable類 Java 基礎(chǔ)

2022-05-05 07:40:07

maskCSS

2022-02-18 08:54:21

docker操作系統(tǒng)Linux

2020-11-20 08:53:35

JavaScript

2023-05-12 08:19:12

Netty程序框架

2021-06-30 00:20:12

Hangfire.NET平臺(tái)

2021-07-28 10:02:54

建造者模式代碼

2021-07-14 08:24:23

TCPIP 通信協(xié)議

2020-10-27 10:05:32

JavaScript 數(shù)組迭代

2023-09-01 16:32:36

JavaScript

2023-10-10 15:29:36

JavaScript開發(fā)

2021-08-02 06:34:55

Redis刪除策略開源

2021-11-08 08:42:44

CentOS Supervisor運(yùn)維

2021-11-24 08:51:32

Node.js監(jiān)聽函數(shù)

2021-12-15 11:52:34

GPLLinuxGNU

2020-11-17 11:10:21

CSS選擇器HTML

2020-11-05 09:58:16

Go語言Map
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)