C语言设计之STM32,在这里轻松学习嵌入式编程

开发板实物图

上图是我购买的一块STM32的开发板,大家可以发现这块开发板是由一块STM32主芯片和很多个外部设备组成的,有大家熟悉的USB、SD卡电源接口等,等还有大家以前没有了解过的一些外设。也就是我以前和大家讲过的大脑和手脚,这样才能形成一个体系,如果只有MCU,那么它如何去执行任务呢?如果只有外设,那么谁去控制它们执行呢?管理者和执行者缺一不可。

在学习编程之前,让我们先来了解一下STM32的内部结构。

STM32晶振

每一款芯片都有晶振,晶振又称为是MCU的“心脏”,不是通上电MCU就可以正常运行了,是晶振推动程序的执行的,这一点大家要注意,STM32不响51单片机只有一个晶振,我选的这一款芯片有5个时钟源,为什么它需要这么多时钟源呢?是为了适应自带的一些设备,有的设备需要高频的时钟,而有些低频的就可以满足它们的使用要求了,如果都使用高频的,那么就会浪费大量的能量,做过产品的同学肯定知道一个产品的功效是很严格的,特别是出口产品,如果功效不达标,也就是造成能源的浪费是无法进行销售的,这会造城很大的损失。所以这也是STM32在控制领域火爆的原因,它能很好地控制功效,也就是所谓的低功耗。

STM32功能选择

我一开始学习的时候就有一个疑问,开发板的引脚就那么多,为什么能实现那么多功能呢?之后我才明白,STM32自带了很多强大的功能,但是引脚的数量有限,所以很多时候它们都是共用一些引脚,但是里面有个功能选择器,我们想使用哪个功能时,就设置功能选择器,这时他就会打通相应通道,并且关闭其他通道。这样就实现了功能的多样性。

还是要推荐下小编的C/C++游戏编程学习裙:六二六八七一九一六,不管你是小白还是大牛,小编我都欢迎,不定期分享干货,包括小编自己整理的一份2018最新的C/C++游戏编程和0基础入门教程,欢迎初学和进阶中的小伙伴。

每天晚上20:00我都会开直播给大家分享C/C++游戏编程知识和路线方法,裙里会不定期更新最新的教程和学习方法(进裙送2018C/C++游戏编程学习教程),大家都是学习C/C++游戏编程的,或是转行,或是大学生,还有工作中想提升自己能力的C/C++党,如果你是正在学习C/C++游戏编程的小伙伴可以加入学习。最后祝所有程序员都能够走上人生巅峰,让代码将梦想照进现实,非常适合新手学习,有不懂的问题可以随时问我,工作不忙的时候希望可以给大家解惑。

前一段时间和大家讲过了,MCU是如何控制这些功能的,MCU中有很多地址,它是通过控制这些地址所对的数据从而实现控制设备的,这些地址对应的就是功能,这些地址所对应的内容也被称为寄存器。但是如果直接去控制寄存器步骤会很繁琐,每实现一个功能就要配置很多寄存器,量大而且容易配置出错,所以这些芯片的的厂家为了方便大家编程,封装了很多库函数,库函数实现了很多功能初始化的分装,我们只要简单调用他们就能配置好所要使用的寄存器了,但是寄存器还是建议大家学习一下的,因为那样才能真正了解芯片的工作原理。给大家实现一个简单的程序,点亮一个LED灯,这个真的是嵌入式中最简单的程序了,就好比你伸手去开个灯那么简单。我用寄存器和库函数各实现一下个大家看看。

C

寄存器版本:

#define LED PFout(8) // 定义LED为相应的管脚

void LED_Init(void) //初始化函数

{

RCC->AHB1ENR|=1

GPIO_Set(GPIOF,PIN8,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PD); //配置管脚功能

LED=0;//关闭LED灯 ,LED做过宏定义,要自己去定义LED代表管脚

}

int main(void) //主函数

{

Stm32_Clock_Init(336,8,2,7); //配置时钟

LED_Init(); //初始化LED

LED=1; //点亮LED

}

库函数版本:

void LED_Init(void) //初始化函数

{

GPIO_InitTypeDef GPIO_InitStructure; //定义管脚

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//打开管脚时钟

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //选择是第几号管脚

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //配置管脚为输出

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //配置管脚为推挽方式

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //配置管脚输入输出频率为100MHz

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //配置管脚为下拉电阻

GPIO_Init(GPIOF, &GPIO_InitStructure); //初始化管脚,按照上述配置

GPIO_ResetBits(GPIOF,GPIO_Pin_8); //·将输出置为0,关闭LED灯

}

int main(void) //主函数

{

LED_Init(); //初始化LED

GPIO_SetBits(GPIOF,GPIO_Pin_8); //将输出置为1,打开LED灯

}

看了上述方式,很多人就说库函数配置那么复杂,明明就是寄存器版本好,其实用过之后你就会发现,库函数配置都是有规律的,而寄存器的的配置都是没有章法可循的,因为设备的多样性,要配置的也是千差万别。但是寄存器执行要比库函数执行效率高,你要问我为什么?因为库函数等于多了一个步骤,你是调用人家的函数,人家的函数是对寄存器的配置,所以速度显而易见,当然一般是感觉不出来的,除非是一丁点时间都不容易许浪费的设备。

STM32

好了今天就介绍到这里,从今天开始,我们也正式开始学习STM32了,以后的日子还望大家一起努力,觉得写的还行的帮忙点个赞呗,不好的还望提出意见和批评,谢谢大家了。

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180123A0ELA200?refer=cp_1026

扫码关注云+社区