历史上的今天
今天是:2024年09月13日(星期五)
2018年09月13日 | STM32固件库文件编程结构思想的理解
2018-09-13 来源:eefocus
STM32的固件库文件功能相当完善,提供的API完全能满足一般的项目需要。刚从51单片机转到STM32的人,肯定会被这么庞大的东东吓到,51单片机上对IO口操作,简简单单几行代码就搞定了,一个C源文件就搞定。假如用STM32,对IO口进行简单操作,远不是几行代码能搞定的。(其实直接操作寄存器也能搞定)。
废话不多说,这就带你解剖固件库文件,包你看完之后豁然开朗。
首先,请看一段简单的C语言代码
#include
#define base 0x0012ff60
#define flash ((TestType *)base)
typedef struct
{
int i;
int j;
int k;
}TestType;
void main()
{
flash->i = 0;
flash->j = 1;
flash->k = 2;
printf( "%x \n", flash->i);
printf( "%x", &(flash->i));
}
有人会问了这段代码有什么用?我告诉你ST的固件库都是按照这种方式编写的
上面程序打印出来结果为 0
0x0012ff60
把上面的程序分析几分钟后,我再给你揭晓。就拿GPIOA口来说吧,你看stm32f10x.h中能看到
#define PERIPH_BASE ((uint32_t)0x40000000)
#define APB1PERIPH_BASE PERIPH_BASE
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
小学学的加减法就能把GPIOA_BASE 算出来,为什么是这么多呢?看ST的手册,人家就是要规定这样,没办法。
有了地址之后,GPIOA的各个寄存器怎么办涅,它们是控制IO的关键所在。GPIO的各个寄存器都是连续排列的,为什么要连续排呢,方便找啊,用结构体就能很好搞定了
在stm32f10x.h中
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
} GPIO_TypeDef;
每个寄存器都是32位的,所以很方便用结构体寻找每个寄存器,准备工作都做好了,接下来就要开始针对GPIOA设置了
在core_cm3.c中
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
把地址强制转换成结构体指针,这样就能很方便对寄存器操作。
寄存器搞定了,接下来就真对用户操作了,要很好的让用户使用,就得人性话点,所以用enum枚举变量就能实现,你就再也不用为想输入的值去烦恼了,直接输入名称就行了,拿IO口的输出速度来说
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
要说人性化,ST还有一点不得不提,那就是位带操作,改变了 写地址-取地址数据-位操作-数据写入地址的操作,直接改为写地址-数据写入
,直接位操作。
ST的编程结构是很值得借鉴的,使得编程序时结构很清晰,脉络很清楚。至于如何去发挥,得看个人水平了
上一篇:菜鸟初识STM32固件库文件夹
史海拾趣
|
VS2005中没有ClassWizard,而是使用属性窗口添加事件处理函数,但我写一个MFC本地应用程序时,在程序中使用工具栏ToolBar,在工具栏中新建了一项,却不知如何添加处理函数,属性窗口中没有可处理的消息列表呀。 … 查看全部问答> |
|
欢迎大家讨论:GPIO的 2-mA, 4-mA和8-mA端口驱动问题 GPIO的 2-mA, 4-mA和8-mA端口驱动中2,4,8-mA GPIO所承受的最大电流???还是其他意思?? 这方面的资料比较少,希望大家讨论下,加深对mA的了解,也为了以后编程时遇到这方面的问题。 [ 本帖最后由 fxw451 于 2010-11-12 08:2 ...… 查看全部问答> |
|
// systick中断处理函数//----------------------------------------------------------------------------- void SysTickHandler(void) { // 调用lwip定时处理函数 lwIPTimer(SYSTICKMS); } //这是一个回调函数,当有UDP数据收 ...… 查看全部问答> |
|
我从网上看到的资料中学会了如何把在VMware上运行起. 但我把同样的东东到core 2CPU, 945GME上就只能出现++++++++++++++++++++++ 我了解到IA-32(X86)的CPU都有向前相容性,这个++++++++++++表示bootrom的代码都不能正常运行,什么原因, 有能人解释 ...… 查看全部问答> |




