【保姆级教程】盘点STM32常用static、typedef、define、estern、ifdef条件编译、结构体等函数以及寄存器映射分析

目录

1.static 函数的作用

2.Typedef的用法

3.#define 宏定义关键词用法

3.#ifdef条件编译的用法

4.extern外部变量声明

5.构造结构体

3.MDK中寄存器地址名称映射分析


1.static 函数的作用

static是静止存储区,说白了就是有记忆功能;

举例:

           

     如上图所示:每次执行函数a时cont的都会被置0,所以cont的返回值结果为 1 1 1 1 1 ....

     如下图所示:每次执行函数b时cont只执行1次,第二次执行b函数的时候将会略过cont执行下面的,所以执行结果返回值为 1 2 3 4 .....

2.Typedef的用法

这个函数的作用就是把数据类型给他起一个新名字

例1:typedef unsigned char  u8      

 u8 size  就等同于 unsigned char  size

例2:typedef   int  *p     point 

同样的也可给指针命名

例3:struct  student 

        {   

                 int  age ;

                 char  name[110];

        } ;

Typedef  struct  student    ad ;

  ad.name[30]="adcd" ;

这里相当于typedef 给这个结构体命名了一个新的名字,用这个新的名字就可以访问结构体成员。

3.#define 宏定义关键词用法

1.语法格式:     #define     标识符         字符串 (字符串可以是表达式、常数、格式串)        

2.例:

#define   syscle_72M       72000000

也就是定义表示符syscle_72M的值为72000000

3.#ifdef条件编译的用法

在stm32开发过程中经常会遇到不同型号的设备,如何把不同设备共用一个程序,这样扩展性更好,可以减少不必要的麻烦!  这就用到ifdef条件编译了,当满足某条件时对一组语句进行编译,条件不满足时编译另一组语句。

1.格式

#ifdef    a    

程序段1

#else

程序段2

#endif

解释:如果定义了这个标识符a的话编译程序段1,否则编译程序段2;

2.例子:

#ifdef     STM32F10X_HD

芯片所需要的变量定义

#endif

解释:这就是我们为什么在keil软件里宏定义USE_STDPERIPH_DRIVER,STM32F10X_HD了因为我们用到时f10x系列芯片,编译的也是属于这个芯片的程序

小伙子们注意:是编译程序而不是执行程序!!!!!!

4.extern外部变量声明

说白了也就是两个c文件中,其中一个c文件定义了一个int a,而另一个c文件想用这个变量a,就得写上 estern  int a   即可

例子:

这里我们可能有个疑问  u8是什么意思???

我们上面介绍了typedef ,u8就是用typedef包装的一个名字而已。例如 typedef    unsigned   char     u8 

5.构造结构体

1.   格式:

struct   结构体名

{

  成员变量1;

  成员变量2;

}变量名列表;

3.MDK中寄存器地址名称映射分析

对MCU来说一切底层最终都是配置寄存器

1.首先在51单片机中的地址映射方法:

sfr  P1 =0x80 ;  //相当于 P1 映射到地址0x80

P1 =0x00; //往寄存器地址赋值0x00

2.那么在32中是怎么映射的呢:

例如:GPIOA —>ODR =0x00000000    

为什么0x00000000 就赋值给了 GPIOA的ODR寄存器了呢?

注:在stm32f10x系列所有的GPIOx(x为ABCD......)都有7个寄存器

 上图:手册中可以看出外设的基地址是0x4000 0000

上图:而GPIOA是挂载在APB2总线上,APB2的基地址从图中可以看出为0x4001 0000

我们的GPIOA的基地址为0x4001 0800

如何得到的GPIOA综合上述:外设的基地址经过偏移后—>APB2的基地址经过偏移后—>GPIOA的基地址。

GPIOA呢又有7个寄存器,经过偏移量后   GPIOA—>ODR(7个寄存器中的其中一个)

上图中:我们很多用过库函数的小伙伴都经常用这几个宏定义吧,其中重点是他把GPIOA的基地址转化成了结构体指针类型 相当于 GPIOA 是 GPIOA_BASE这个基地址,把这个基地址强制转化为结构体指针类型,相当于这个基地址存放的空间是结构体指针类型

注:指针和地址最大的区别是指针有类型,而地址没有类型,地址仅仅是地址编号;
  指针是由地址和类型组成,指针不仅记录了地址编号还记录了该地址空间的类型。

这里就是GPIOA的7个寄存器,把他放在结构体里面更容易管理,为什么转化成结构体指针类型呢,因为这7个寄存器都是指针类型命名的。

注意:任何的GPIOx都有7个寄存器,每个寄存器有32位,每个寄存器占用4个地址,每个地址占1个字节,一个字节等于8位,我们如果用ODR寄存器:GPIOA —>ODR(在GPIOA上偏移多少后得到ODR寄存器,箭头的意思是指向结构体的ORD这个成员,而ODR是封装好了的)

  • 16
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
typedef结构体函数的应用主要是为了简化代码和提高可读性。 在结构体中,typedef可以用来创建别名,使得结构体类型的定义更加简洁。通过typedef,我们可以给结构体类型起一个新的名字,方便在代码中使用。\[1\]例如,我们可以使用typedef来定义一个结构体类型,并给它起一个别名: typedef struct { int age; char name\[20\]; } Person; 这样,我们就可以使用Person作为这个结构体类型的别名,而不需要每次都写出完整的结构体类型名。 在函数中,typedef可以用来定义函数指针类型,使得函数指针的声明更加清晰。\[2\]通过typedef,我们可以给函数指针类型起一个新的名字,方便在代码中使用。例如,我们可以使用typedef来定义一个函数指针类型,并给它起一个别名: typedef int (*CalcFunc)(int, int); 这样,我们就可以使用CalcFunc作为这个函数指针类型的别名,而不需要每次都写出完整的函数指针类型名。 总结起来,typedef结构体函数的应用可以使代码更加简洁、可读性更高。通过给结构体类型和函数指针类型起别名,我们可以在代码中更方便地使用它们,提高代码的可维护性和可读性。\[3\] #### 引用[.reference_title] - *1* [C++:typedef结构体分别加指针、数组、函数的使用](https://blog.csdn.net/weixin_43991826/article/details/104370508)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [typedef在变量、函数结构体中的应用](https://blog.csdn.net/qq_43551976/article/details/102712490)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [typedef的4种常见用法](https://blog.csdn.net/qq_31073871/article/details/81258558)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星马嵌入式

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值