目录
一些C知识点
1、#define和typedef的区别
2、结构体struct
3、结构体中.和->的区别
4、.c文件和.h文件的关系
5、防止重复引用
一、寄存器结构体定义
1、定义结构体变量指针
2、寄存器赋值
二、端口置位函数
1、端口置位.c文件
2、端口置位.h文件
3、调用
遇到的问题
参考
一些C知识点
1、#define和typedef的区别
#define为一宏定义语句,通常用它来定义常量(包括无参量与带参量)或者公式,在预处理之后的.i文件中就完成替换。定义在前,原文本在后。
typedef为关键字,可以使用它为变量取别名,但仅限为类型定义名称,由编译器执行解释。类型在前,别名在后。与define不同,typedef后需要加引号。此外如本文,typedef也可定义结构变量。
#define Max 255
#define Add(a,b) ((a)+(b))
typedef unsigned int uint32_t;
2、结构体struct
结构体声明格式:Book为结构体名称,book为结构体变量名。
struct Book
{
char title[128];
char author[40];
}book;
3、结构体中.和->的区别
->:用在结构体指针的后面;
. :用在结构体后面(".“这个运算符可以理解为中文里"的”);
(*a).b 等价于a->b
4、.c文件和.h文件的关系
一般来说二者没有本质区别,.h文件是头文件,内含函数声明、宏定义、结构体定义等内容;.c文件是程序文件,内含函数实现,变量定义等内容。
func.h里声明函数,在func.h同一目录下建立func.c ,func.c里定义了这个函数的内容。如果在main函数所在.c文件里#include这个func.h 后,main函数运行时就会直接找到func.c的函数并运行。
5、防止重复引用
为防止重复引用,习惯在每个头文件里用条件指示符#ifndef。
#ifndef _STM32F10X_H
#define _STM32F10X_H
//text
#endif
一、寄存器结构体定义
1、定义结构体变量指针
如图1所示,GPIO的七个寄存器从每个GPIO的基地址开始,按每32位即每4个字节一个寄存器排列,因此可以使用结构体为GPIO的寄存器分配一块连续内存,结构体内有七个成员对应七个寄存器,以此方便对各个寄存器的配置操作。
图1 GPIO寄存器地址映像和复位值
如下代码所示,结构体变量为GPIO_TypeDef,所有GPIO内部的寄存器都是这种结构,都可以使用这种结构体去操作内部成员寄存器。因此,如果使用GPIOB,则需要将GPIOB_BASE基地址转化为这种结构体类型的指针,并宏定义为GPIOB。
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef struct
{
uint32_t CRL;
uint32_t CRH;
uint32_t IDR;
uint32_t ODR;
uint32_t BSRR;
uint32_t BRR;
uint32_t LCKR;
}GPIO_TypeDef;
#define GPIOB ((GPIO_TypeDef*)GPIOB_BASE) //GPIOB定义为GPIO_TypeDef类型的指针
2、寄存器赋值
通过以上定义,要操作GPIOB的CRL寄存器,代码对比如下:
GPIOB_CRL |= ((1)<<(4*0));
GPIOB->CRL |= ((1)<<(4*0));
//二者作用相同
二、端口置位函数
在对端口置位、复位时,与使用移位等位操作相比,写好端口操作函数直接调用来的更方便。
1、端口置位.c文件
形参为结构变量类型的指针,和端口位。
/********** stm32f10x_gpio.c **********/
#include "stm32f10x_gpio.h"
void GPIO_SetBits(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
{
GPIOx ->BSRR |= GPIO_Pin;
}
2、端口置位.h文件
对于置位函数,要设置端口的某一位为1,在BSRR寄存器中,低16位为置位功能,即0不影响,1则置位1。因此,可以使用宏定义,若要将寄存器首位置位,则定义GPIO_Pin_0为0x0001,GPIO_Pin_1为0x0002,GPIO_Pin_2为0x0004,以此类推。同时别忘了在头文件中声明函数。
/********** stm32f10x_gpio.h **********/
#ifndef _STM32F10X_GPIO_H
#define _STM32F10X_GPIO_H
#include "stm32f10x.h"
#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< 选择Pin0 */ //(00000000 00000001)b
#define GPIO_Pin_1 ((uint16_t)0x0002) /*!< 选择Pin1 */ //(00000000 00000010)b
#define GPIO_Pin_2 ((uint16_t)0x0004) /*!< 选择Pin2 */ //(00000000 00000100)b
#define GPIO_Pin_3 ((uint16_t)0x0008) /*!< 选择Pin3 */ //(00000000 00001000)b
#define GPIO_Pin_4 ((uint16_t)0x0010) /*!< 选择Pin4 */ //(00000000 00010000)b
#define GPIO_Pin_5 ((uint16_t)0x0020) /*!< 选择Pin5 */ //(00000000 00100000)b
#define GPIO_Pin_6 ((uint16_t)0x0040) /*!< 选择Pin6 */ //(00000000 01000000)b
#define GPIO_Pin_7 ((uint16_t)0x0080) /*!< 选择Pin7 */ //(00000000 10000000)b
#define GPIO_Pin_8 ((uint16_t)0x0100) /*!< 选择Pin8 */ //(00000001 00000000)b
#define GPIO_Pin_9 ((uint16_t)0x0200) /*!< 选择Pin9 */ //(00000010 00000000)b
#define GPIO_Pin_10 ((uint16_t)0x0400) /*!< 选择Pin10 */ //(00000100 00000000)b
#define GPIO_Pin_11 ((uint16_t)0x0800) /*!< 选择Pin11 */ //(00001000 00000000)b
#define GPIO_Pin_12 ((uint16_t)0x1000) /*!< 选择Pin12 */ //(00010000 00000000)b
#define GPIO_Pin_13 ((uint16_t)0x2000) /*!< 选择Pin13 */ //(00100000 00000000)b
#define GPIO_Pin_14 ((uint16_t)0x4000) /*!< 选择Pin14 */ //(01000000 00000000)b
#define GPIO_Pin_15 ((uint16_t)0x8000) /*!< 选择Pin15 */ //(10000000 00000000)b
#define GPIO_Pin_All ((uint16_t)0xFFFF) /*!< 选择全部引脚*/ //(11111111 11111111)b
void GPIO_SetBits(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin);
#endif /*_STM32F10X_GPIO_H*/
3、调用
使用时,在主程序中调用即可。GBIOB已经被定义为GPIO_TypeDef类型的指针,GPIO_Pin_0已经被定义为0x0001。
GPIO_SetBits(GPIOB,GPIO_Pin_0);
遇到的问题
让LED闪烁,程序看不出问题,但只要是在while里的程序就不会执行,led只会常亮或者常灭,百度这个问题,有优化等级的原因,原来是O1,改成O0不优化就没有问题了,具体为什么不优化就可以运行,暂时不清楚。
int main(void)
{
RCC_APB2ENR |= (1<<3);
//控制RCC寄存器打开时钟,RCC偏移0x18为APB2时钟,寄存器第三位为PB使能
GPIOB_CRL &= ~((0x0F)<<(4*0));
//初始化,低4位为一组,全部置0
GPIOB->CRL |= ((1)<<(4*0));
//控制GPIOB_CRL低位配置寄存器,GPIOB偏移0x00,PB0通用推挽输出00,模式为输出01
while(1)
{
GPIOB->ODR &= ~(1<<0);
Delay_ms(500);
GPIOB->ODR |= (1<<0);
Delay_ms(500);
}
}
参考
https://doc.embedfire.com/mcu/stm32/f103zhinanzhe/std/zh/latest/index.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)