0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

采用标准C的强制转换和指针的概念来实现访问MCU的寄存器

GReq_mcu168 来源:玩转单片机 2020-08-04 16:44 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

单片机的特殊功能寄存器SFR,是SRAM地址已经确定的SRAM单元,在C语言环境下对其访问归纳起来有两种方法。

1

采用标准C的强制类型转换和指针来实现

采用标准C的强制转换和指针的概念来实现访问MCU的寄存器,例如:

#define DDRB (*(volatile unsigned char *)0x25)

分析如下:

这样读/写以0x25为地址的SRAM单元,直接书写DDRB即可,即DDRB为变量,只不过变量的地址固定为0x25。例如:

DDRB = 0xff;

这样比直接采用指针变量的方法直观和方便的多,例如:

unsigned char *p, i;

p = 0x25;

i = *p; //把地址为0x25单元中的数据读出送入i变量

*p = 0; //向地址为0x25的单元中写入0

总结一下,就是(*(volatile unsigned char *)0x25)可以看作是一个普通变量,这个变量哟固定的地址,指向0x25。而0x25只是个常量,不是指针,更不是变量。

2

对C编译器进行语法扩充

对C编译器进行语法扩充。例如MCS51系列KeilC中扩充sfr关键字,举例如下:

sfr P0 = 0x80;

这样操作0x80单元直接写P0即可。

下面对AVR的歌C编译器对访问MCU寄存器的方法进行简介。

A:采用标准C的强制类型转换和指针来实现访问MCU的寄存器,每一个C编译器都支持,原因很简单,这是标准C。

B:ICCAVR和GCCAVR没有定义新的数据类型,只能采用标准C的强制类型转换和指针来实现访问MCU的寄存器。而IAR和CodeVisionAVR编译器对ANSI C进行了扩充,都定义了新的数据类型,是C语言可以直接访问MCU的有关寄存器,例如,IAR中:

SFR_B(DDRB, 0x28)

CodeVisionAVR中:

sfrb DDRB = 0x28

这样,PORTB=0xff;等同于(*(volatile unsigned char *)0x05) = 0xff;而0x25正好是寄存器PORTB在器件ATmega48/88/168中的地址。

GCCAVR每个AVR器件在头文件不采用直接定义特殊功能寄存器宏,例如在iomx8.h文件中一个定义如下:

#define PORTB _SFR_IO8(0x25)

而在sfr_defs.h中可以找到如下两个宏定义:

#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr)+0x20)

#define _MMIO_BYTE(mem_addr) (*(volatile unit8_t *)(mem_addr))

实质上与直接的强制类型转换和指针定义是一样的。

另外,GCCAVR中宏_BV(bit)是操作I/O寄存器是频繁用到的,avr-libc建议使用这一宏进行寄存器的位操作,他在文件sfr_defs.h中定义如下:

#define _BV(bit)

以下是他的使用示例:

DDRB = _BV(PB0) | _BV(PB1); //器件头文件中已经定义PB0代表0,PB1代表1

他等同于“DDRB=0x03;”,这样写的目的是为了提供程序的可读性。不要担心它会生成比“DDRB=0x03;”更大的代码,编译器会处理这种事情,最终会输出与“DDRB=0x03;”同样的结果。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    31

    文章

    5589

    浏览量

    129073
  • C语言
    +关注

    关注

    183

    文章

    7642

    浏览量

    144625
  • 变量
    +关注

    关注

    0

    文章

    615

    浏览量

    29371

原文标题:两种方式实现C语言访问MCU寄存器

文章出处:【微信号:mcu168,微信公众号:硬件攻城狮】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    嵌入式系统必懂的 20 个寄存器

    嵌入式开发看起来很复杂,但很多操作其实都离不开寄存器寄存器就是MCU内部的存储单元,它们控制着处理和外设的行为。熟悉这些寄存器,你就能更
    的头像 发表于 11-14 10:28 652次阅读
    嵌入式系统必懂的 20 个<b class='flag-5'>寄存器</b>

    蜂鸟内核中DMA的硬件实现——寄存器配置

    DMA,Direct Memory Access,直接内存访问,是一种不经过CPU而直接从内存存取数据的数据交换模式。在DMA模式下,CPU只需要向DMA控制下达指令(配置DMA寄存器),传输数据
    发表于 10-24 08:46

    SN74LV594A:2-5.5V带输出寄存器的8位移位寄存器技术解析

    AEC-Q100标准采用可湿性侧翼QFN (WBQB) 封装。TI SN74LV594A/-Q1可在移位寄存器和存储寄存器上进行独立直接覆盖清零
    的头像 发表于 09-02 09:42 605次阅读
    SN74LV594A:2-5.5V带输出<b class='flag-5'>寄存器</b>的8位移位<b class='flag-5'>寄存器</b>技术解析

    ‌TLC6C5912 12通道移位寄存器LED驱动技术文档总结

    该TLC6C5912是一款单片、中压、低电流功率 12 位移位寄存器 设计用于需要相对中等负载功率的系统,例如 LED。 该器件包含一个 12 位串行输入并行输出移位寄存器,可为 12 位馈电
    的头像 发表于 08-26 14:16 762次阅读
    ‌TLC6<b class='flag-5'>C</b>5912 12通道移位<b class='flag-5'>寄存器</b>LED驱动<b class='flag-5'>器</b>技术文档总结

    ‌TLC6C5816-Q1 16位移位寄存器LED驱动技术文档总结

    TLC6C5816-Q1 器件是一款 16 位移位寄存器 LED 驱动,旨在支持汽车 LED 应用。内置LED开路和LED短路诊断机制,提供增强的安全保护。该器件包含 16 个通道,带有
    的头像 发表于 08-25 18:13 781次阅读
    ‌TLC6<b class='flag-5'>C</b>5816-Q1 16位移位<b class='flag-5'>寄存器</b>LED驱动<b class='flag-5'>器</b>技术文档总结

    SN74LV595B-EP低噪声8位移位寄存器技术解析与应用指南

    Texas Instruments SN74LV595B-EP低噪声8位移位寄存器包含一个8位串行输入、并行输出移位寄存器,可为8位D类存储寄存器馈送信号。存储寄存器具有并行 3 状态
    的头像 发表于 08-15 09:28 852次阅读
    SN74LV595B-EP低噪声8位移位<b class='flag-5'>寄存器</b>技术解析与应用指南

    使用寄存器点亮LED灯

    学习本章时,配合以上芯片手册中的“19. I/O Ports”章节一起阅读,效果会更佳,特别是涉及到寄存器说明的部分。本章内容涉及到较多寄存器方面的深入内容,对于初学者而言这些内容丰富也较难理解,但非常有必要细读研究、夯实基础。
    的头像 发表于 05-28 17:37 1041次阅读
    使用<b class='flag-5'>寄存器</b>点亮LED灯

    CYPD3120 上是否有允许从外部 MCU 访问读/写寄存器的可访问接口?

    TUSB564),MCU 需要知道 USB-C 电缆何时翻转,才能直接翻转 DP 接收端的通道极性。 CYPD3120 上是否有允许从外部 MCU 访问读/写
    发表于 05-27 07:51

    第四章 什么是寄存器

    本篇文章我们讲解了寄存器概念、地址映射和寄存器操作等内容,内容比较干,大家有个概念即可,不要求全部熟记掌握,有需要时可重复查阅观看。下一篇我们将开始进行实操内容,通过控制单片机的GP
    的头像 发表于 05-21 14:23 1141次阅读
    第四章 什么是<b class='flag-5'>寄存器</b>

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

    由于寄存器的数量是非常之多的,如果每个寄存器都用像*((uint32_t*)(0x40080000+0x0020*1))这样的方式去访问的话,会显得很繁琐、很麻烦。为了更方便地访问
    的头像 发表于 04-22 15:30 1664次阅读
    如何用<b class='flag-5'>C</b>语言操作<b class='flag-5'>寄存器</b>——瑞萨RA系列FSP库开发实战指南(10)

    AG32 MCU中CPLD使用基础(二)

    读写数据到cpld; 在地址设计中,cpld的地址区间是:0x60000000 ~ 0x7FFFFFFF 当mcu对这个区间内的地址访问时,相当于访问了cpld的“寄存器”。
    发表于 04-07 09:25

    XILINX FPGA CLB单元之移位寄存器

    一、移位寄存器 SLICEM函数发生也可以配置为32位移位寄存器,而无需使用slice中可用的触发。以这种方式使用,每个LUT可以将串行数据延迟1到32个时钟周期。 移入D(DI1
    的头像 发表于 01-16 17:45 1466次阅读
    XILINX FPGA CLB单元之移位<b class='flag-5'>寄存器</b>

    将LDC1000配置了0X0B寄存器,各寄存器的值都变成了相应寄存器的Deffault值,为什么?

    我将LDC1000各寄存器配置后,当不配置0X0B,即传感处于待机状态时,单片机读回来各寄存器的值是正常的,但当配置了0X0B寄存器,即传感
    发表于 01-02 07:41

    TPS80032寄存器手册

    电子发烧友网站提供《TPS80032寄存器手册.pdf》资料免费下载
    发表于 12-21 09:08 0次下载
    TPS80032<b class='flag-5'>寄存器</b>手册

    怎么才能访问DP83869HM的寄存器

    我们的主控芯片(CPU+MAC)的寄存器访问只支持5bit. [4:0] REG_ADDR PHY器件内部的寄存器地址。 请问要怎么才能访问DP83869HM的
    发表于 12-09 07:33