嵌入式通用const和volatile和static inline关键字 (volatile寄存器地址修饰必不可少)

news2024/11/18 10:48:53

const和volatile之间的合作

  • 【1】const修饰变量
  • 【2】const修饰数组
  • 【3】const修饰指针
  • 【4】const修饰函数
  • 【5】volatile的应用
  • 【6】volatile详解
  • 【7】const和volatile配合
  • 【8】AHB (高级高性能总线)
  • 【9】APB (高级外围总线)

在这里插入图片描述


在学习ADC之前掌握这些

#define __IO    volatile         //值可以被改变 每次必须从内存获取值 防止被编译器优化
#define __I     volatile const	  //值不希望被改变,保持这个值为只读常量
#define __STATIC_INLINE static inline   //内敛函数 适用代码短的函数
typedef void (*ADC_CallbackType)(void);							///< ADC回调函数指针
//静态函数指针数组 初始化函数指针类型的NULL
static ADC_CallbackType g_adcCallback[1] = {(ADC_CallbackType)NULL};
#if defined(__CC_ARM)
  #pragma anon_unions   //keil中默认是不支持匿名结构体的,需要编译指令#pragma anon_unions指名。
#elif defined(CCARM__)
  #pragma language=extended //IAR对所用语言(这里是C)做的一些扩展,也就是说这里可以用扩展的功能
#elif defined (__ICCARM__)
/* anonymous unions are enabled by default:默认启用匿名联合 */
#elif defined(__GNUC__)
/* anonymous unions are enabled by default */
#elif defined(__TMS470__)
/* anonymous unions are enabled by default */
#elif defined(__TASKING__)
  #pragma warning 586
#else
  #warning Not supported compiler type //警告不支持编译器类型
#endif

【1】const修饰变量

const修饰的变量为只读变量,不能给只读变量直接赋值(即const修饰的变量不能出现在等号左边)
但是可以通过指针访问这一块内存区域然后间接修改该值。

【2】const修饰数组

C中const修饰的数组是只读的,const修饰的数组空间不可被改变(即数组内存放的值),
但是又正如const常量一样,可以通过指针访问该内存区域进行间接修改。

#include < stdio.h >
int main()
{
    const int arr[3] = {0, 1, 2};
    //arr[2] = 0;   error:read-only 不能改变值
    //printf("%d\n", arr[2]);
    return 0 ;
}

【3】const修饰指针

(1)例如这种:const int* p; int const*p;
当const在*左侧时,const修饰的指针可以更改指针指向,不能通过指针修改指向的内存空间所存放的值。

int test1 = 10;
int test2 = 20;
const int *p = &test1; //int const* p = &test1;
//*p = 30; error 不可改变值
p = &test2;	    //可以改变指向

(2)例如这种:int* const p;
当const在*右侧时,const修饰的指针指向的地址不可改变, 但是指针指向的地址存放的内容可以进行修改。

int test1 = 10;
int test2 = 20;
int *const p = &test1;
//p = &test2;  error 不可改变指向
*p = 30;		   //可以改变值

【4】const修饰函数

(1)const修饰函数参数表示在函数体内不希望改变参数的值
(2)const修饰函数返回值表示返回值不可改变,多用于返回指针的情形

【5】volatile的应用

volatile用于告诉编译器必须每次去内存中取变量值

`
(1) 并行设备的硬件【寄存器】(如:状态寄存器)
(2) 一个【中断服务子程序】中会访问到的非自动变量
(2) 【多线程】应用中被几个任务共享的变量
`

【6】volatile详解

(1)volatile可理解为“编译器警告指示字”
(2)volatile用于告诉编译器必须每次去内存中取变量值
(3)volatile主要修饰可能被多个线程访问的变量
(4)volatile也可以修饰可能被未知因数更改的变量
int obj = 10; //volatile int obj = 10;
int a = 0;
int b = 0;
a = obj;
sleep(100);//发生中断 obj值被改变
b = obj;

【1】编译器在编译的时候发现obj没有被当做左值使用,因此会“聪明”的优化, 将obj替换成10,所以就把a和b都赋值为10。
【2】在上述程序中,在sleep的100s内如果发生了 硬件中断
(在这里我将其简单理解为外部突发的异常使得程序变量值发生突然改变,这种改变也可能在程序执行时),
可能obj的值突然变为了100,然而因为编译器的优化,b=obj;可以被编译器优化看成b=10;【实际是b=100才对】
那么当我们想要通过b获取obj在硬件中断后发生改变而产生的值时,却无法观察的到,所以可以将obj定义为volatile类型,
及告诉编译器不要做任何的优化,每次都老老实实的【去内存中取出该变量的值】。(在多线程中也会用到该关键字volatile)

【7】const和volatile配合

const和volatile可以同时修饰一个变量。

volatile const int a;
const volatile int a; //顺序无关紧要

只读的状态寄存器,它是volatile,因为它可能被意想不到地改变,
同时它又是const,因为程序不应该试图去修改它。volatile和const并不矛盾,
只是控制的范围不一样,一个在程序本身之外,另一个是程序本身。

1】#define __IO    volatile         //值可以被改变 每次必须从内存获取值 防止被编译器优化,可以初始化时赋值变量2】#define __I     volatile const   //值不希望被改变,每次必须从内存获取值 防止被编译器优化,只给这类变量赋值常量

【8】AHB (高级高性能总线)

AHB,Advanced High performance Bus,高级高性能总线,这是一种系统总线。
AHB主要用于高性能模块(如CPU、DMA和DSP等)之间的连接。
AHB 系统由主模块、从模块和基础结构(Infrastructure)3部分组成, 整个AHB总线上的传输都由主模块发出,由从模块负责回应


【9】APB (高级外围总线)

APB,Advanced Peripheral Bus,这是一种外围总线。
APB主要用于低带宽的周边外设之间的连接,例如UART1284等,它的总线架构不像 AHB支持多个主模块,
在APB里面唯一的主模块就是APB 桥
APB2负责AD,I/O,高级TIM,串口1;
APB1负责DA,USB,SPI,I2C,CAN,串口2345,普通TIM。


从图可以看出这些外设是如何和总线连接的,配置时钟时,就需要正确初始化
STM32参考图
在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/55022.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

iPayLinks艾贝盈上线委托换汇功能!

“8.11”汇改以来&#xff0c;人民币汇率市场化形成机制逐步完善&#xff0c;人民币汇率弹性不断增强&#xff0c;双向波动成为常态。 在市场化的汇率形成机制下&#xff0c;外贸人想要快、准、稳地选到合适汇率&#xff0c;降低汇损提高利润&#xff0c;仅靠自己难以实现。 …

模拟电路设计(36)---谐振型变换器

谐振型变换器 今天来介绍下谐振型变换器。脉宽调制型通过控制开关管的导通占空比来调节输出电源功率&#xff0c;而谐振型变换器以正弦形式处理功率开关管&#xff0c;使得开关管在零电流或者在零电压的情况下实现导通和关闭&#xff0c;从而降低开关功耗&#xff0c;提高变换…

这才是数字孪生污水处理厂该有的样子 | 智慧水务

近年来&#xff0c;智慧水务、数字水务成为水务行业的热点领域。对于污水处理领域&#xff0c;如何贯彻落实双碳战略&#xff0c;积极推进智慧水厂建设&#xff0c;显得尤为关键。 图扑软件依托自主研发的 HT for Web 产品&#xff0c;并结合视频融合、BIM、5G、物联网、云计算…

springMVC02,restful风格,请求转发和重定向

springMVC02,restful风格,请求转发和重定向restful风格restful简介restful 例子测试请求转发和重定向restful风格 restful简介 概念: Restful就是一个资源定位及资源操作的风格。不是标准也不是协议&#xff0c;只是一种风格。基于这个风格设计的软件可以更简洁&#xff0c;…

第10章Swagger自定义实现index.html页

1 初始化index.html页 复制原程序“index.html”页的内容到当前程序员“index.html”页。 注意&#xff1a;是内容复制&#xff0c;如果是页面替换复制&#xff0c;则必须重新把“index.html”页的属性中的“生成操作”设定为&#xff1a;“嵌入的资源”。 2 自定义SwaggerSet…

【数据结构】堆和优先级队列

目录 一、堆 1.1堆的特点 1.2如何构造一个最大堆 &#xff08;1&#xff09;最大堆的构造以及常用方法的实现 &#xff08;2&#xff09;添加操作 &#xff08;3&#xff09;删除操作 &#xff08;3&#xff09;将任意数组调整为堆 二、TopK问题 2.1使用优先级队列 &am…

jenkins 参数化构建发布到kubernetes集群不同的命名空间下

最终效果 在构建前可以选择参数,要拉取的Git分支、什么命名空间下、什么服务。 自由风格项目使用的jenkins agent镜像,请参考这个文章: 【DevOps】(2022.11更新)基于jenkins/jnlp-slave:4.13.3-1-jdk11镜像,加入kubectl、mvn命令_阳光很暖吧的博客-CSDN博客 1、自由风格项…

广告和电商应该怎么串联起来呢?我们可以从各大巨头的动作中发掘

电商广告是广告产业与电子商务模式联姻的时代产物&#xff0c;是把广告、传媒、营销推广产业链的各种产品和服务搬到网上&#xff0c;利用网络便捷的实现广告资源信息流通、在线交易和客户关系管理的一种商业模式&#xff0c;是广告业营销模式和渠道的创新。 电商平台从无到有…

一篇文章彻底理解自定义View

目录 一.View的基础 1.view的基础概念 2.view的位置和事件event几种表示法 3.view的滑动 ①.ScrollTo、ScrollBy: ②.布局位置(layout,offsetLeftAndRight,offsetTopAndBottom) ③.布局参数(LayoutParams) 4.view的弹性滑动 ①.ScrollercomputeScrollscrollTo ②.动画…

如何基于YAML设计接口自动化测试框架?看完秒会

在设计自动化测试框架的时候&#xff0c;我们会经常将测试数据保存在外部的文件&#xff08;如Excel、YAML、CSV&#xff09;或者数据库中&#xff0c;实现脚本与数据解耦&#xff0c;方便后期维护。目前非常多的自动化测试框架采用通过Excel或者YAML文件直接编写测试用例&…

部署高校房屋管理系统可以实现哪些目标?

数图互通房产管理 随着技术的不断进步和升级&#xff0c;以及高校房屋建筑物数量的不断扩充&#xff0c;建立房屋资产管理信息系统进行信息化、数字化、图形化房屋资产管理已经是势在必行。数图互通自主研发的FMCenterV5.0平台&#xff0c;是针对中国高校房产的管理特点和管…

工业数据与数据采集应用如何在ARM+FPGA异核架构的米尔MYC-JX8MMA7核心板应用

随着通信与网络技术、互联网的发展&#xff0c;工业管理数据化、网络化、智能化已成大势所趋&#xff0c;利用工业物联网完成工业控制是智慧工厂中必不可少的一部分。传统的控制与数据采集系统&#xff0c;主机一旦需要同时与多个数据采集设备保持高速通信&#xff0c;并要承担…

Golang【Web 入门】 07 路由 - http.ServeMux

阅读目录说明ServeMux 和 Handler重构&#xff1a;区分不同的 Handler查看 http.HandleFunc 源码重构&#xff1a;使用自定义的 ServeMuxhttp.ServeMux 的局限性URI 路径参数请求方法过滤不支持路由命名http.ServeMux 的优缺点标准库里的就是最好的&#xff1f;说明 goblog 需…

【运维心得】ApacheDirectory找不到java路径的解决方案

目录 ApacheDirectory是什么&#xff1f; 问题现象描述 解决步骤 总结 本文是因为没有在网上找到类似的问题和文章&#xff0c;只能依靠自己去解决&#xff0c;既然解决了&#xff0c;就应该分享一下&#xff0c;希望能帮到需要的朋友。 ApacheDirectory是什么&#xff1f…

火山引擎 DataTester 揭秘:字节如何用 A/B 测试,解决增长问题的?

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 上线六年&#xff0c;字节跳动的短视频产品——抖音已成为许多人记录美好生活的平台。除了抖音&#xff0c;字节跳动旗下还同时运营着数十款产品&#xff0c;从资讯…

人工智能在网络安全中的重要性

介绍&#xff1a; 人工智能&#xff08;AI&#xff09;是计算机科学的一个分支&#xff0c;基于某些独特的算法和相关数学计算&#xff0c;使机器能够拥有人类的决策能力。另一方面&#xff0c;网络安全包括保护虚拟世界免受网络攻击和威胁的安全措施。人工智能能够通过采取与…

第二十一章《万年历》第1节:万年历项目简介

万年历项目实现的是一款日历软件,它能够展示出任意年份的日历,除此之外,该软件还能以红色字体标出每个月的阳历节日。 21.1.1万年历功能简介 万年历软件的运行结果如图21-1所示。 图21-1万年历软件界面 为方便讲述,此处把这个万年历的界面分成了4个区域,每个区域当中都有…

【优化发电】基于matlab差分进化算法求解单库发电优化问题【含Matlab源码 2253期】

⛄一、差分进化算法简介 如同所有的优化算法一样, 差分进化算法基于种群的进化算法。差分进化算法主要的参数主要有种群规模NP, 解空间的维数D, 缩放因子F和交叉概率Cr。D维矢量XGi[xGi,1, xGi,2, …, xi, DG], i1, 2, …, Np, 表示G代第i个个体。变异和交叉操作在每一代中产生…

NIO-ServerSocketChannel和Tomcat

ServerSocketChannel 面向流的侦听套接字的可选通道。 通过调用此类的open方法创建服务器套接字通道。 无法为任意预先存在的ServerSocket创建通道。 新创建的服务器套接字通道已打开但尚未绑定。 尝试调用未绑定的服务器套接字通道的accept方法将导致抛出NotYetBoundExcepti…

达梦数据库通过作业实现自动备份功能

达梦数据库通过作业实现自动备份功能作业功能简介一、通过DM管理工具创建备份作业(图形化配置)1.创建代理环境2.创建作业二、命令行方式配置备份作业案例1.创建代理环境2.全量备份3.增量备份4.备份清理三、JOB 运行和日志查看作业功能简介 在管理员的工作中&#xff0c;有许多…