理解(*(volatile unsigned char *)0x5F[转]

STC32G.H中文注释 STC32单片机 阅读详情

理解#define SREG    (*(volatile unsigned char *)0x5F)
这样的定义,总是感觉很奇怪,不知道为什么,今天终于有了一点点心得,请大虾们多多批砖~~~

   嵌入式系统编程,要求程序员能够利用C语言访问固定的内存地址。既然是个地址,那么按照C语言的语法规则,这个表示地址的量应该是指针类型。所以,知道要访问的内存地址后,比如0x5F,
   第一步是要把它强制转换为指针类型
(unsigned char *)0x5F,AVR的SREG是八位寄存器,所以0x5F强制转换为指向
unsigned char类型。
   volatile(可变的)这个关键字说明这变量可能会被意想不到地改变,这样编译器就不会去假设这个变量的值了。这种“意想不到地改变”,不是由程序去改变,而是由硬件去改变——意想不到。
   第二步,对指针变量解引用,就能操作指针所指向的地址的内容了
   *(volatile unsigned char *)0x5F
   第三步,小心地把#define宏中的参数用括号括起来,这是一个很好的习惯,所以#define SREG    (*(volatile unsigned char *)0x5F)

    类似的,如果使用一个32位处理器,要对一个32位的内存地址进行访问,可以这样定义#define RAM_ADDR     (*(volatile unsigned long  *)0x0000555F)
    然后就可以用C语言对这个内存地址进行读写操作了
    读:tmp = RAM_ADDR;
    写:RAM_ADDR = 0x55;
zhiwei 发表于 2005-4-30 18:59 AVR 单片机

定义未volatile是因为它的值可能会改变,大家都知道为什么改变了;
如果在一个循环操作中需要不停地判断一个内存数据,例如要等待SREG的I标志位置位,因为SREG也是映射在SRAM空间,为了加快速度,编译器可能会编译出这样的代码:把SREG读取到Register中,然后不停地判断Register相应位。而不会再读取SREG,这样当然是不行了,因为程序或其它事件(中断等)会改变SREG,结果很可能是一个死循环出不来了。如果定义成volatile型变量,编译的代码是这样的:每次要操作一个变量的时候都从内存中读取一次。
#define SREG (*(volatile unsigned char *)0x5F) 之后,可以进行如下基本操作,
unsigned char temp,*ptr;
temp=SREG;把SREG值保存到temp中
SREG=temp;把temp的值赋给SREG
ptr = & SREG; 不知对否,大家试一下。

 
(*(volatile unsigned long *))的理解 最近在学习Nand Flash驱动程序设计时,涉及到(*(volatile unsigned long *)),通过查阅部分网络文章,对其用法和指针有了进一步理解,遂作此笔记。本文参考了yueleilei的文章--ARM定义特殊寄存器(*(volatile unsigned long *))的理解点击打开链接,在此感谢。 一、对 #define SREG (*(volatile unsigned 阅读详情

相关推荐

Spring Boot版本兼容性实战:Java、Maven/Gradle与容器选型指南

在Java企业级应用开发中,版本兼容性是保障项目稳定运行和长期可维护性的基石。其核心原理在于不同技术组件(如JDK、构建工具、框架)之间的API与字节码规范必须相互匹配,否则会导致编译失败、运行时异常或性能问题。掌握版本兼容性对于提升开发效率、确保团队协作一致性以及实现平滑的技术栈升级具有重要价值,尤其在微服务架构和持续集成/持续部署(CI/CD)场景下更为关键。本文聚焦于Spring Boot这一主流Java框架,深入解析其与Java运行时、Maven/Gradle构建工具以及内嵌Servlet容器(如T

weixin_30911451的博客 651

字符编码小结

前言 i 数字编码 在计算机的世界中,只有0和1,计算机如何能表示无穷无尽的数值呢?人们约定,以8个bit作为一个字节,以4个字节作为一组,用于标识int,这样一来,int就可以表示具有32位0,1组成的二进制数字了,计算机在处理数字的过程中,以每32个bit(4个字节)为一组进行解析,得到一个二进制数字,在需要供人阅读时,在将二进制换为10进制,这样计算机就能表示我们熟悉的10进制数字了。 这...

你可知外面的世界多大 859

Ollama最新快速上手指南:从安装到精通本地AI模型部署

想让Ollama跑你的"私房模型"?三种主流格式全支持,总有一款适合你!GGUF格式(推荐新手首选)创建Modelfile文件:执行创建命令:运行你的专属模型:PyTorch/Safetensors格式(适合进阶玩家)先用库测试模型能否正常加载确保模型结构完整后再导入Ollama官方文档有详细换指南专业小贴士GGUF格式最轻量,PyTorch最灵活,Safetensors最安全遇到问题?试试用llama.cpp进行格式换7B参数模型推荐使用q4_0量化级别想让AI用马里奥。

全世界的博客 2250

数学之美:平方根倒数速算法中的神奇数字 0x5f3759df

http://blog.jobbole.com/105295/?ref=myread 本文由 伯乐在线 - JLee 翻译,黄利民 校稿 英文出处:Christian Plesner Hansen。 【伯乐在线导读】:在伯乐小组的这个讨论帖《你见过或写过的最复杂的 C 语言程序是?》中,就提到了「平方根倒数速算法」中的神奇数字 0x5f3759df。Chris

zdy0_2004的专栏 1万+

字母大小写化(位运算)

#include<bits/stdc++.h> using namespace std; char smallToBig(char c) { return c & 0x5f; } char bigToSmall(char c) { return c ^ 0x20; } int main() { for (int i = 0; i < 10; ++i) { char small = 'a' + i; char big = smallToBig(small);

weixin_43918473的博客 445

java位运算

位运算表达式:由操作数和位运算符组成,实现对整数类型的二进制数进行位运算。位运算符分为逻辑运算符(包括非~、按位与&、或|和按位异或^) ~:化为二进制数按位取反+2 &:化为二进制数按位与(1&1=1,1&0=0,0&0=0) |:化为二进制数按位或(1|1=1,1|0=1,0|0=0) ^:化为二进制数按位异或(1^1=1,1^0=0,0^0=1)移位运算符(包括>>、<<和>>>)一.

YABAJ的专栏 807

理解#define SREG (*(volatile unsigned char *)0x5F)

C/C++自习室 1493

C语言(*(volatile unsigned CHAR *)addr)理解

嵌入式中C语言操作寄存器看ARM程序时,会看到类似如下的代码:#define SREG (*(volatile unsigned CHAR *)0x5F)在嵌入式系统编程中,一般要求程序员能够利用C语言访问固定的内存地址。按C语言的语法来看,这个地址应该由指针类型来表示,所以在操作某个内存地址,比如0x5c时,其步骤如下: 将地址强制换为指针类型 ->(unsigned CHAR * )

Welljia的专栏 1万+

(*(volatile unsigned long *))

以前老是对ARM程序中(*(volatile unsigned long *))不理解,今天看了两篇文章,觉得对理解这个很有用,当然这个不止在定义内部特殊寄存器有用,在用到外部总线时,根据具体情况,定义外部器件的地址也可以用。 下面是文章一 终于理解了#define SREG (*(volatile unsigned CHAR *)0x5F) 以前看到#define SREG   &nb...

qq_45763093的博客 282

如何理解 #define SREG (*(volatile unsigned char *)0x5F

   #define SREG    (*(volatile unsigned char *)0x5F)   嵌入式系统编程,要求程序员能够利用C语言访问固定的内存地址。既然是个地址,那么按照C语言的语法规则,这个表示地址的量应该是指针类型。所以,知道要访问的内存地址后,比如0x5F,   第一步是要把它强制换为指针类型(unsigned char *)0x5F,AVR的SREG是八位寄存器,所

Welcom to Daniel's Home 1257

*(volatile unsigned *)0x4F000000理解

    *(volatile unsigned *)0x4F000000 的疑问? *(*)N //先强制类型换,换为指针,再对指针进行间接访问 volatile unsigned *ptr;ptr=(volatile unsigned *)0x4F000000; 对Ptr间接访问: *Ptr // *(volatile unsigned *)0x4F000000

jldream110的专栏 1312

iar c语言语法,终于搞明白了 IAR C 的位操作了,很方便!

在IAR的iomacro.h里面有这样一段说明:#define SFR_B_N(_ADDR, _NAME, _B7, _B6, _B5, _B4, _B3, _B2, _B1, _B0) \SFR_B_BITS_N(_NAME, _ADDR, \Bit0,Bit1,Bit2,Bit3,Bit4,Bit5,Bit6,Bit7, \_B0,_B1,_B2,_B3,_B4,_B5,_B6,_B7)/*S...

weixin_30461129的博客 950

volatile__unsigned__char详解

标签: *(volatile  unsigned  char  *)   (*(volatile unsigned char *)0x56000010)      以前看到#define SREG    (*(volatile unsigned char *)0x5F)这样的定义,总是感觉很奇怪,不知道为什么,今天终于有了一点点心得,请大虾们多多批砖~~~      嵌入式系统编程,要求程

lufeiop02的专栏 3240

(*(volatile unsigned char *)0x20)用法

嵌入式的C程序中,我们经常看到类似如下的定义: #define AAA (*(volatile unsigned char *)0x20) #define BBB (*(volatile unsigned char *)0x4B000020) ...... 那么如何对这条语句进行理解呢? 首先,我们来分析define语句后面的内容: (*(volatile unsigned char

零阶简正波的博客 2327

NL2SQL实践系列(1):深入解析Prompt工程在text2sql中的应用技巧

NL2SQL实践系列(1):深入解析Prompt工程在text2sql中的应用技巧

丨汀、的博客 4304

斑马线制作工具.zip

3dmax斑马线制作插件,有需要的小伙伴赶紧来下载吧!!!!

上一篇: μC/OSII中的时钟中断技术研究
下一篇: 为什么必须要在OC门输出的IO口上加上拉电阻?
silenceee
博客等级 码龄20年 43粉丝 50原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值