您当前位置:首页 > 新闻中心 新闻中心

关于学习STM32至今的心得体会

 一、 心得体会

 
经历了一段时间的学习后,我的STM32单片机也算是勉强入门了,前段时间,参加了电赛,做了一个智能小车的工程,也看过B站的一些大佬做的一些项目,这使我能更加清楚对自己的水平进行一个定位。虽然看似学了不少东西,但是自己却清楚自己对单片机的应用及理解,仅仅局限在正点原子和江协科技的标准库例程,同时自己也知道仅仅是学习库函数例程,是无法深入到单片机的实质的(即芯片架构)。我学习单片机的目标,不仅仅是学会使用STM32,如果不能了解芯片的架构问题,一旦脱离了STM32,就什么都干不了。所以接下来的这段时间里,我准备将之前做过的实验用寄存器再次还原一遍。
 
并且最近一段时间我正在重新学习一遍C语言。原因有三,其一便是因为C语言是与嵌入式最为亲近的一门语言,想要端稳这碗饭,C语言的水准肯定要跟的上。
 
二来,是因为我的C语言的水准确实有待提高,我的C语言水准虽然对付一些简单的工程是够用的,但是对付稍微上些难度的工程就显得心有余而力不足了,比方说,我经常会去B站上去白嫖一些UP主的开源代码,有时候代码拿来了,能用是能用,但是若是想移植代码到别的工程里面就有些异想天开了,一个个的我闻所未闻将所未见的语法或算法总是会将我的设想打击的体无完肤,
 
最后也是最主要的原因,通过各方面的了解,我深深意识到了脱离驱动层去写算法的重要性,驱动层的可代替性强,想要在信工专业守好饭碗,就必须掌握上层的算法,降低自己的可替代性,而想要学好数据结构与算法,就必须打好C语言的底子,只有把底子打好,才能在算法路上走的更远。
 
至于更远的计划就不提了,再说就显得有些纸上谈兵了,下面就谈一谈我这段时间对STM32的某些常用寄存器的使用总结吧。
 
 
 
二、 关于STM32常用寄存器的使用总结
 
 
 
1.时钟有关寄存器
 
时钟有HSE(高速外部时钟信号),HSI(高速内部时钟),PLL(对前后两种时钟做倍频),LSE(低速外部时钟信号),LSI(低速内部时钟信号),SYSCLK(系统时钟),
 
看门狗时钟,RTC时钟几大类
 
相应的GPIO端口寄存器必须被配置为相应功能。以下8个时钟信号可被选作MCO时钟:
 
●SYSCLK
 
●HIS
 
●HSE
 
●除2的PLL时钟
 
●PLL2时钟
 
●PLL3时钟除以2
 
●XT1外部3~25MHz振荡器(用于以太网)\
 
●PLL3时钟(用于以太网)
 
在MCO上输出的时钟必须小于50MHz(这是I/O端口的最大速度)。
 
时钟的选择由时钟配置寄存器(RCC_CFGR)中的MCO[3:0]位控制。
 
时钟控制寄存器(RCC_CR)
 
时钟配置寄存器(RCC_CFGR)
 
时钟中断寄存器(RCC_CIR)
 
外设时钟使能寄存器(RCC_APB2ENR)
 
外设时钟使能寄存器(RCC_APB1ENR)
 
 
 
 
 
 
 
 
 
2.I/O口有关寄存器
 
        STM32的每个IO端口都有7个寄存器控制,分别为:
 
        2个32位端口配置寄存器CRL、CRH;
 
        2个32位的数据寄存器IDR、ODR;
 
1个32位的复位/置为寄存器BSRR;
 
1个16位的复位寄存器BRR;
 
1个32位的锁存寄存器LCKR;
 
常用寄存器为:CRL,CRH,IDR,ODR。
 
 
 
 
 
2.1端口配置寄存器CRL、CRH:
 
(1)CRL配置低8位的IO口,CRH配置高8位的IO口。
 
(2)MODEy:配置IO口输出速度
 
(3)CNCFy:配置IO口输出模式
 
 
 
 
 
在固件库开发中,操作寄存器 CRH 和 CRL 来配置 IO 口的模式和速度是通过 GPIO 初始化函数完成:
 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
 
通过初始化结构体初始化 GPIO 的常用格式是:
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;               //LED0-->PB.5 端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;            //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //速度 50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure);                  //根据设定参数配置 GPIO
 
 
 
 
 
2.2数据寄存器IDR、ODR:
 
2.2.1 IDR:
 
(1)读取某个IO口的电平。
 
(2)低16位分别代表一组中16个不同的IO口。
 
 
 
 
 
在固件库中操作 IDR 寄存器读取 IO 端口数据是通过 GPIO_ReadInputDataBit 函数实现的:
  uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
比如我要读 GPIOA.5 的电平状态,那么方法是:
  GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_5);
 
 
 
 
 
2.2.2 ODR:
 
(1)该寄存器为可读写。
 
(2)低16位分别代表一组中16个不同的IO口。
 
(3)可一次性设值GPIO多个端口。
 
 
 
在固件库中设置 ODR 寄存器的值来控制 IO 口的输出状态是通过函数 GPIO_Write 来实现
的:
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
该函数一般用来往一次性一个 GPIO 的多个端口设值。
 
 
 
 
 
2.3剩下四个不常用寄存器就不做过多赘述了。
 
 
 
上面便是我目前对某些寄存器的理解,此外学习寄存器的过程明显比一开始刚接触32时快很多,在了解了大致的原理过程后我需要完成的仅仅是从参考手册中找到对应的寄存器位以及设置方法。还有就是我发现寄存器的代码编写非常简洁不容易出错,而且非常容易找出错误所在,只要去观察寄存器状态在哪里出错,一次就可以找出错误所在。避免了一遍一遍的改代码试错。至于实验工程之类的我就不多说了,接下来要做的就是好好学习,将自己的嵌入式技术继续进行升级。