07_STM32常用C语言和寄存器地址名称映射详解

STM32常用C语言和寄存器地址名称映射详解

 6种操作运算符:

 

按位与&:bit位相同的时候,同1为1,其中有一个不为1,则0。

举例:

                   1001 1100

                & 1010 1010

等于            1000 1000

常用方法:GPIOB->CRL&=0xFFF0;   将低4位清0

按位或|:bit位相同的时候,有1则为1,全是零则0。

举例:

           1001 1100

          |1010 1010

等于    1010 1110

常用方法:GPIOB->CRL|=0x000F;   将低4位置1,不改变其他位的值

按位异或^:bit位相同的时候,相同位1,不同为0。

           1001 1100

         ^1010 1010

等于    0011 0110

按位取反~:bit位相同的时候,相同位1,不同为0。

          ~1001 1100

等于     0110 0011

常用方法:GPIOB->CRL=0x0F;   答案会是0xF0

右移运算>>:

举例:  0x0F>>1 转换成二进制0x0000 1111>>1答案等于0x07  转换成二进制0x0000 0111相当于数据整体的右移了一位,高位补0;

左移运算<<:

举例:  0x01<<3 转换成二进制0x0000 0001<<3答案等于0x08  转换成二进制0x0000 1000相当于数据整体的左移了3位,低位补0;

Define是C语言中的预处理命令,在编译的时候会代替我们写的宏定义。

格式:

#define 标识符 字符串

“标识符”是所定义的宏名字,”字符串”可以是常数,表达式,格式串。


#define  N  100
定义了标识符 N的值位100  




#define add(a,b)  a+b
uint8_t C = add(1,2);
定义标识符add有2个参数,内容是a+b,C的答案会是3。





#define A 1
#define B A+1
可以嵌套宏定义




#define PIN1 int*
PIN1 a;等价于int* a;
PIN1定义成指针




#ifndef  _UART_H_
#define  _UART_H_
#endif 
表示如果没定义_UART_H_ 那就定义,如果定义了就不会在定义,避免重复定义






#define test(x,y) do \
{				 \
Uint8_t a = x;  \
Uint8_t b =y;  \
Printf(“%d”,a); \
}while(0)			 \
类似于函数一样的宏定义\表示后面还有代码。





#define PI 3.14159

Int main(){
//code 
}

#undef PI
Void func(){
//code
}
表示在PI只在#undef之前有效在main函数有效,在#undef之后无效 func函数无效






ifdef条件编译


#ifdef 标识符
程序段1
#else
程序段2
#endif
表示如果定义了标识符就编译程序段1,否则编译程序段2







#ifdef 标识符1
代码段1
#elif 标识符2
代码段2
#elif 标识符3
代码段3
#else 
代码段4
#endif
表示如果定义了标识符1就编译程序段1,如果没有就继续找#elif看下剩下的有被定义么,如果都没被定义那就编译代码段4。相当于C语言的if (){}elseif();





ifndef条件编译

#ifndef 标识符
程序段1
#else
程序段2
#endif
表示如果没有定义了标识符就编译程序段1,否则编译程序段2

 寄存器地址名称映射

对于MCU,一切底层配置,最终都是配置寄存器

51中的映射方法

Sft P0 = 0x80;//P0映射到地址0x80

P0 = 0X00;//给0x80地址里面赋值0x00

 STM32中的映射方法

以GPIOA为例:

先定义了一个结构体,从命名为GPIO_TypeDef,这个__IO是指静态 volatile uint32_t 是指32位的无符号整形变量uint32_t 是指32位的无符号整形变量,volatile 类型是这样的,其数据确实可能在未知的情况下发生变化。

Typedef struct{
__IO uint 32_t CRL;
__IO uint 32_t CRH;
__IO uint 32_t IDR;
__IO uint 32_t ODR;
__IO uint 32_t BSRR;
__IO uint 32_t BRR;
__IO uint 32_t LCKR;
}GPIO_TypeDef



#define PERIPH_BASE  ((uint32_t)0x40000000)
定义一个外设基地址,可以看手册,这是出厂就被定死了的。


#define APB2PERIPH_BASE (PERIPH_BASE+0x10000)
在定义APB2的偏移地址,基于外设基地址的偏移找到APB2的起始地址。


#define GPIOA_BASE (APB2PERIPH_BASE + 0X0800)
查看手册,由因为GPIOA是在APB2上的,以APB2的基地址在偏移找到GPIOA的地址。


#define GPIOA  ((GPIO_TypeDef*)GPIOA_BASE)
最后定义了一个GPIOA,强制转换为(GPIO_TypeDef*)的结构体指针类型,
相当于从GPIOA_BASE开始是以GPIO_TypeDef结构体变量的大小顺序存放,
因为是结构体指针所以我们可以直接用GOIOA->CRL,
相当于直接访问GPIOA基地址加结构体成员变量CRL的偏移地址。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值