#define A (* (volatile unsigned long *) 详解

#define GPBDAT (*(volatile unsigned long *)0x56000014) #define GPBDAT      (*(volatile unsigned long *)0x56000014) 这一句话在网上一搜,应该有一片片的解释,不知道你们看了是什么感觉,我看了好几个都是那感觉没有理解。后来经过几天思索,有了些许理解。 请大家按照下面思路来: int  a; a=5;      //这句话无须解释 a=5.5;   //这句话不会报错,但是我在用keil的 阅读详情

一.

#define A    (* (volatile unsigned long *)   0x48 ) // 8位处理
#define A    (* (volatile unsigned long *)   0x48000000) // 32位处理器

对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射的。如果系统结构支持独立的IO地址空间,并且是端口映射,就必须使用汇编语言完成实际对设备的控制,因为C语言并没有提供真正的“端口”的概念。如果是内存映射,那就方便的多了。
    
举个例子,比如像寄存器A(地址假定为0x48000000)写入数据0x01,那么就可以这样设置了。
#define A (*(volatile unsigned long *) 0x48000000 )
...
     A = 0x01;
...
这实际上就是内存映射机制的方便性了。其中volatile关键字是嵌入式系统开发的一个重要特点。volatile(可变的)这个关键字说明这变量可能会被意想不到地改变,这样编译器就不会去假设这个变量的值了。这种“意想不到地改变”,不是由程序去改变,而是由硬件去改变。volatile 限定编译器不对这个指针的指向的存储单元进行优化, 即不用通用寄存器暂时代替这个指针的指向的存储单元,而是每次取值都直接到指针的指向的存储单元取值.

volatile 主要用于变量会异步改变的情况下,主要有三个方面:

1.cpu外设寄存器

2.中断和主循环都会用到的全局变量 

3.操作系统中的线程间都会用到的公共变量.

上述表达式拆开来分析,首先(volatile unsigned long *) 0x48000000的意思是把0x48000000强制转换成volatile unsigned long类型
的指针,即对指针的操作的范围是从0x48000000开始的4个字节(long型).暂记为p,那么就是
#define A   *p,即A为P指针指向位置的内容了。这里就是通过内存寻址访问到寄存器A,可以读/写操作!



二.
#define SREG (*(volatile unsigned char *)0x5F 的含义

以前看到#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;


在Unity3d使用yolov8的onnx模型 输出OUTPUTS是float32[1,35,8400],表示它会输出一个大小为[1, 35, 8400]的浮点数张量。这个输出张量的维度表示了检测到的目标的数量、每个目标的预测参数以及网格单元的数量。输出张量的第一个维度1表示检测到的目标数量。每个目标由35个值组成,表示目标的类别、置信度、边界框的坐标及10个特定点的位置。要取得8400个数据中置信度最高的数据,然后获取该数据其他channel的数据。运行结果:(蓝色是检测手的边框,红点是自定义的点),其中的四个数字分别表示不同的维度。 阅读详情

相关推荐

Mathtype公式下标深度调整技巧:解决固定行距下的显示不全问题

本文针对在Word等文档中设置固定行距时,Mathtype公式下标显示不全的问题,提供了专业解决方案。核心在于调整Mathtype软件内部的“下标深度”参数,通过修改单个公式或批量格式化全文,使公式完美适配固定行距,确保下标清晰完整,且不影响文档整体排版。

pepsi的博客 1503

c语言 #define A(...)是什么意思

c语言 #define A(...)是什么意思

wanjietiam的博客 5361

从零构建基于ZYNQ与AD9361的SDR信号源:FPGA逻辑与射频前端的协同设计

本文详细介绍了从零开始构建基于ZYNQ与AD9361的SDR信号源的完整流程。通过解析FPGA逻辑与射频前端的协同设计,重点阐述了如何利用FPGA生成基带信号,并通过ARM处理器配置AD9361,最终实现一个可编程的2.4GHz载波信号发生器。内容涵盖硬件选型、Vivado环境搭建、AXI总线通信、LVDS接口设计及软件驱动开发,为SDR开发者提供了实用的实战指南。

weixin_29200485的博客 214

#define a&&#define a 1

1.#define a 定义条件编译,相当于定义了一个条件 它的用法:一般用于条件编译,比如说有一段代码我在linux环境下是一种写法,在windows下又是一种写法。这个时候,我们就可以这样写 #define WINDOWS #if defined(WINDOWS) xxx //do something #else xxx #endif 从上面的例子可以看出,#define a

ltt305210390的专栏 1996

从数据校准到论文呈现:fsQCA与NCA方法融合的完整实证研究指南

本文详细介绍了fsQCA(模糊集定性比较分析)与NCA(必要条件分析)方法融合的完整实证研究流程,从数据校准到论文呈现。通过软件操作技巧、R语言NCA包高效使用及论文写作规范,帮助研究者避免常见误区,提升研究质量与可靠性。特别适合需要进行组态分析的研究生和学者参考。

weixin_29215391的博客 417

【STM32系统】基于STM32设计的锂电池电量/电压检测报警器系统

本设计旨在研究一个基于STM32F103C8T6微控制器的锂电池电量/电压检测报警器系统,应用于便携式电子设备电池管理。系统通过STM32的ADC模块对18650锂电池电压进行采集,利用LCD1602显示模块实时显示电池电压,当检测到电池电量不足或电压异常时,蜂鸣器报警模块会发出警报提醒用户。系统采用简单的硬件结构和优化的软件架构,通过对实际电池电压数据的检测、处理和显示,实现了低功耗、实时监测的锂电池管理功能。本文将介绍系统的设计原理、硬件电路、软件实现以及调试测试过程。

嵌入式阿齐Archie 1万+

C语言的 #define

目录#define1 #define 标识符## 和#的区别 #define 1 #define 标识符 📢基本含义 标识符 我们在c语言中 很多时候 会用到宏定义 也就是 #deifne 标识符1 标识符2 这样的基本框架形成了一个宏定义 标识符可以是数字 字符 字母。 会方便我在报错的时候 检查就省很多功夫 📢📣 语法 #define AA 123 #define DD 111 基本的框架 前面的代替 后面的 就比如上面的例子 1 AA 代替了 BB 2 DD代替了 111 也就是在

weixin_59349642的博客 1488

C++怎么学?零基础也可以,一份完整学习路线图助你搞定!

提供一条清晰、系统且实践导向的C++学习路径。从基础语法、面向对象、泛型编程、异常处理,逐步深入STL、智能指针、并发编程等现代C++高级特性。无论是新手还是希望提升,通过系统学习与项目实践,助您将理论知识转化为实际解决问题的能力。

Lion_Long的博客 4027

C语言中:#define宏的正确使用

                        C语言中:#define宏的正确使用 正确使用方式1: #define A(a,b) ((a)*(b)) 正确使用方式2: #define F(x) do{\ printf("This is a 111\n");\ printf("This is a 222\n");\ }while(0) 用do-while(0)方式定义宏,...

魏波 3463

基于Flink的流式数据降维实现方案

理解为何实时场景需要降维(解决维度灾难)掌握Flink流处理与降维算法的结合方式学会用Flink实现一个可落地的流式降维系统覆盖内容包括:Flink流处理基础、降维算法选择(侧重在线算法)、Flink与降维的集成方案、实战代码示例,以及工业级场景的应用经验。本文从“为什么需要流式降维”出发,用“快递分拣”的生活案例引出核心概念;接着拆解Flink流处理、数据降维的底层逻辑;然后重点讲解“在线PCA”这一适合流式场景的降维算法,并用Flink实现一个完整的流式降维管道;

AI 领航者的博客 567

ConvNeXt 改进 :ConvNeXt添加GnConv递归门控卷积,二次创新CNBlock结构 ,独家首发

视觉 Transformer 在多种任务中取得了显著的成功,这得益于基于点积自注意力的新空间建模机制。视觉 Transformer 中的关键因素——即输入自适应、长距离和高阶空间交互——也可以通过卷积框架高效实现。作者提出了递归门控卷积(Recursive Gated Convolution,简称 gnConv),通过门控卷积和递归设计执行高阶空间交互。该新操作具有高度的灵活性和可定制性,兼容各种卷积变体,并将自注意力中的二阶交互扩展到任意阶数,而不会引入显著的额外计算。

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 240

【c语言】详解宏定义#define 各种使用方法

一、宏替换格式 宏替换简称宏的格式: #define 宏替换名称 替换内容 差异: 1 #define执行的时点是预处理即编译前 typedef执行的时点是编译时 2 #define只是单纯的“查找替换”把源代码变成另外的样子,并没有创造新的类型名称。 3 typedef是定义的一个类型名,编译器把它当作一种新的类型来看待。所以定义类型常用typedef 表达式、函数也可以进行替换 三、替换一个函数或表达总结 宏的本质是:查找、替换! 宏的作用是:增强可读性、灵活性!

努力让自己的能力配得上梦想. 7235

ROS局部路径规划器插件teb_local_planner流程梳理(上)

在我之前的文章《ROS导航包Navigation中的 Movebase节点路径规划相关流程梳理》中已经介绍过Move_base节点调用局部路径规划器插件的接口函数是computeVelocityCommands,接下来,我们就从这个函数入手梳理一下teb_local_planner功能包的工作流程。

慕羽★的博客 5165

ARM特殊寄存器定义详解——#define A (* (volatile unsigned long *) 0x48000000

     今天在看S3C2440开发板的初始化代码时,对#define A (* (volatile unsigned long *) 0x48000000这种形式的定义方式有困惑,今天看了三篇文章,觉得对理解这个很有用:文章一:有关volatile unsigned long一些说明  对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射的。如果系统结构支持独立的IO地址空间,并且是端口映射,就必须使用汇编语言完成实际对设备的控制,因为C语言并没有提供真正的“端口”的概念。如果是内存映射,那就方

Heart_of_Eagle的专栏 1821

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

ARM特殊寄存器定义详解——#define A (* (volatile unsigned long *) 0x48000000(zz)

今天在看S3C2440开发板的初始化代码时,对#define A (* (volatile unsigned long *) 0x48000000这种形式的定义方式有困惑,于是求助GOOGLE大神,在网上搜到了一些文章,觉得以下三篇文章对理解这个有些作用: 文章一: 有关volatile unsigned long一些说明 ...

weixin_34161083的博客 177

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

C语言-(*(volatile_unsigned_long*))理解

本文详细解析了C语言中`*(volatile_unsigned_long*)`的含义,包括`(unsigned long *)`指针类型、volatile关键字的作用以及如何在内存中存储数值。通过实例代码展示了如何读取内存中的小数,并探讨了浮点数在内存中的存储结构。

让你爱上电路设计 3066

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

#define GPFCON *((volatile unsigned long *)0x56000050)具体含义

( unsigned long *)0x56000050 0x56000050只是个值,前面加(unsigned long *)表示 0x56000050是个地址,而且这个地址类型是unsigned long volatile,关键字volatile 确保本条指令不会因C 编译器的优化而被省略,且要求每次直接读值。 volatile的意思是告诉编译器,在编程源代码时,对这个变量不要使用优化。在一般...

JadyC的博客 1550

#define A (* (volatile unsigned *) 0x48000000 )

#define A    (* (volatile unsigned *)   0x48000000 )对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射。如果系统结构支持独立的IO地址空间,并且是端口映射,就必须使用汇编语言完成实际对设备的控制,因为C语言并没有提供真正的“端口”的概念。如果是内存映射,那就方便的多了。举个例子,比如向寄存器A(地址假定为0x48000

zhangjian的专栏 1203

对(volatile unsigned char *)分析

对于(volatile unsigned char *)0x20,它是由两部分组成: (unsigned char *)0x20,0x20只是个值,前面加(unsigned char *)表示0x20是个地址,而且这个地址类型是unsigned char , 意思是说读写这个地址时,要写进unsigned char 的值,读出也是unsigned char 。 volatile,关键字v...

Utotao的博客 2208

#define XXXX (*(volatile unsigned long *)0xxxxxxx)

在嵌入式编程中,#define XXXX   (*(volatile unsigned long *)0xxxxxxx) 宏定义常常遇到,这是宏定义寄存器名称常见的编程方式。        通过拆分,可以分析上述语法的应用:          1、(unsigned long *)变量,代表“变量”是一个unsigned long类型的指针;例如:(unsigned long *)i ,语句中

猪哥的专栏 3846

对#define GPBCON (*(volatile unsigned long*)0x56000010)的理解

#define GPBCON (*(volatile unsigned long*)0x56000010) 1:volatile   当计算机需要一个数值的时候,会先把内存中的值读取到寄存器,然后下次在使用该值的时候就直接读取寄存器中的值了。加上volatile之后,程序就会在每次需要该值的时候都读取一次内存。这是为了防止某些原因硬件会改变其值。 2:   (volat

王纯配的博客 2132
上一篇: volatile 简介
下一篇: 《如果让我重新读次研究生》——王泛森院士 [建议研究生看看]
_修_
博客等级 码龄16年 49粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值