历史上的今天
今天是:2025年01月10日(星期五)
2021年01月10日 | STM32 初练总结(GPIO)
2021-01-10 来源:eefocus
最近有项目需要用到STM32,开始系统的学习一下STM32这块芯片,整理了一些初学的心得,以备以后忘记了可以回来再看。
管脚资源确认
首先确定所用的STM32型号对应的GPIO管脚资源,一般都会把GPIO管脚分成好几组,比如GPIOA、GPIOB、GPIOC、GPIOD~GPIOG等,一般管脚数越多,分的组也越多,有些管脚是GPIO和其他功能复用的,一些GPIO管脚已经默认了特定的功能,如果要重新自定义映射管脚,需要打开AFIO功能开启重映射。
STM32 库导入和确认
1、STM官网上有STM开发相关的组件资源和库文件,这个网上有很多资源可以利用,先下载然后解压,并按照keil的流程建立一个STM32工程。
2、STM库里面会包含了基本上所有涉及到的组件的底层函数(CMSIS和FWLIB),我们所做的开发就是利用这些底层函数来建立符合自己的应用(APP),所以建立好工程的第一步,就是确认下自己所需要的组件函数是否都能在库中找到,当然,如果对STM32硬件资源和寄存器很熟悉,也可以自己写底层驱动,作为新手,还是建议使用现成的库函数,会节省很多时间。
3、库资源一般由.h和.c两种文件组成,.h是头文件定义,里面定义了组件相关的各种宏定义,参数定义,函数声明等。.c文件是对应组件的底层函数的详细定义,包括初始化、寄存器配置、模式控制等与组件功能相关的底层函数,开发之前最好把这些函数的作用搞清楚 ,在开发APP的时候也可以返回来看。
4、有些组件的功能并不是单一的,可能会与其他组件的功能结合实现,比如UART,可能不但是UART协议的功能,还有GPIO的功能,还有可能管脚复用等,因此要结合相关组件的底层函数一起理解。
代码组成
1、首先是startup文件,工程里面需要添加startup_xxxx.s文件,这个文件和器件类型是相关的,要根据选择的器件类型来添加。startup文件里面定义了工程运行的入口,每次系统复位后,程序会进入到startup文件里面的一个systeminit的地方,从这里开始运行,其实就是初始化时钟和复位等基本的内核配置,让芯片底层功能跑起来,再跳转到main函数,执行用户定义的功能代码。这里有一个问题需要注意,就是代码编写的时候,变量声明需要注意是否会造成内存栈溢出,否则程序运行时会触发hardfalut_handler硬件错误中断,程序进入是循环。另一个可能会触发hardfalut_handler硬件错误中断的原因就是精度设置,这个我也不知道为什么,反正网上说的是在魔法棒里面勾上一个设置选项就没有了,不同版本的keil可能描述不一样,只能多试几次。
2、其次就是main函数,这个函数里面就是用户自定义的各种功能的函数调用了,其实一般各个组件的应用函数都会另起一组文件(.h,.c)来描述,main文件里面只是把各个组件的功能函数集中调用,按照一定的顺序,加上适当的判断和循环,得到想要的功能;main函数一般是一些组件的初始化和配置函数的调用,加上一个while(1)循环,在while(1)之前初始化各种组件的寄存器和变量,在循环里面实现用户想要实现的功能。
3、组件功能函数,就是实现各个组件初始化和配置的相关代码,有些是可以从库里面直接使用的,有些需要按照需要在底层函数的基础上重新搭建,网上有很多参考,大体上一般包括:
(1)时钟使能,首先确定时钟是属于哪个域的,AHBAPB1APB2等。当然还有一些专用的时钟域,要结合datasheet来控制。
(2)寄存器配置,包括一些寄存器的配置,库函数一般是会把相关组件的属性都打包成一个structure,用户只需要重新定义一个sturcture的类,然后再按照这个类的属性来配置就可以了。
(3)初始化,配置完成后,调用初始化函数来初始化对应组件。
(4)使能控制,有些组件配置完成寄存器以后,要想让模块工作,需要使能相应的控制寄存器,结合datasheet来使用。
比如这个ADC使用的pin管脚的初始化代码:
void ADC_Pin_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*----------------Solar_Current_Moniter-------------*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = CH1_Pin;
GPIO_Init(CH1_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = CH2_Pin;
GPIO_Init(CH2_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = CH3_Pin;
GPIO_Init(CH3_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = CH4_Pin;
GPIO_Init(CH4_Port, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Pin = ADC_Trigger_Pin;
GPIO_Init(ADC_Trigger_Port, &GPIO_InitStructure);
}
一个工程的基本组成就是这些,其他都是组件的扩展了,根据需要来扩展,后面再详细分析各个组件。
史海拾趣
|
signal AsynInput: std_logic; signal InputReg: std_logic; signal Delay: std_logic; signal SynInput: std_logic; process(SynInput, AsynInput) begin if SynInput=‘1’ then --此置位为寄存器信号,为同步设计,可行 Input ...… 查看全部问答> |
|
单片机实现软件复位(软复位)的方法及讨论。(转帖)加自己整理。 单片机实现软件复位(软复位)的方法及讨论(天堂雨林博客blog.sina.com.cn/acer收集整理)单片机软复位有什么好的方法?如从机收到复位命令(软件命令),程序怎么使机器复位?虽然要使软件始终处于可控状态,最好不要用\"复位\",因为复位是纯硬件过 ...… 查看全部问答> |
|
偶参加四月份北京车展,五月份京交会 ,都看到了一些德国MINI型轿车。大家如何看到一些德国MINI型轿车在大陆市场很走俏啊? http://weibo.com/vishaychina… 查看全部问答> |
|
麻烦大家看一下,我这边有一个交直流信号,信号频率20Hz左右,设置一个低通滤波器,截止频率为10HZ,仿真发现增益下降速率太小,一直无法滤去交流,得到想要的直流,怎么办才好呀? … 查看全部问答> |




