【新技能get】开发板一起学起来 (第一部分)
本教程作者为ICkey网友@HelloWii ,回帖参与讨论、提问、分享,就能赢取超多丰厚奖励哦~
@HelloWii 也将随时和大家交流学习中的问题。(PS:本教程未经允许谢绝转载)
学教程,送奖励,活动说明详见:
【新技能get√】开发板STM32F429I Discovery技术一起学起来
关键字:IAR第一个项目、数据手册、GPIO、固件库、Blink
LED
单片机和开发板等,都是一些工具,既然是工具就要看说明书(数据手册)。如果你的英文很好,那真是太好了,稍加练习读者英文文档也是很无压力。就算英文不是很好,也要尽量的多去看一看英文的原版的东西,因为任何东西都是从不会到会的一个过程。作为四六级都没过的我,看着英文文档开心的也是快要哭了。
关于STM32F429,有时间还是要多参考参考 《Reference
Manual RM0090》 这个官方的数据手册,市面上的书随意翻看基本就会发现,大多都是参考数据手册写的。
由于帖子的内容的过长,就把帖子拆分成了不同的帖子,下面附上链接,点击直达。。。
1. 【新技能get】开发板一起学起来——IAR第一个demo
简介: IAR就不多介绍了关于安装和下载以及如何get 到免(破)费(解)版本的,请度娘吧。我安装的是IAR7.30,里面是可以找到评估板F429的芯片选型,IAR6.30就没了。上面的这篇帖子,就介绍了IAR7.30如何新建一个教程。
下面主要讲的是IAR建立第一个STM32F429的项目程序、以及blink
led。由于篇幅有限,关于IAR免(破)费(解)版的安装就不讲详细过程了,这个度娘会告诉你们的。本人安装的是IAR7.30版本的。
IAR全称是IAR
Embedded Workbench IDE一个很优秀的集成开发环境(详细的内容可以参考官网:https://www.iar.com/)。
一、Firmware package 简介
准备:已经下载去官网Firmware
package(固件库),本人使用的是STM32F429I-Discovery_FW_V1.0.1这个版本的。
解压开固件库的大致内容如下:
图1-1-1:固件库构成
(注:上图是从手册中copy过来的,可能细节与实际有点出入,但是大体是一样的。)
从上图可以看出,固件库中的资源还是蛮多的。
具体的可以查看下fjjjnk1234的补充哦,,感谢fjjjnk1234(http://bbs.ickey.cn/group-topic-id-49104-page-1#3)
我们知道STM32F429I
Discovery预先已经烧录了一个demo程序。我们就用IAR来打开看一下这个demo程序。Demo的路径如下图所示:
图1-1-2:demo程序路径
打开完成之后,编译下载即可在开发板上演示,是不是开心的不行呢。
我们就先学习一下这个例程的配置,再来创建一个我们自己的例程。具体参考参数在工程的右键,查看属性。具体如下所示:
图1-1-3:项目属性
这个属性卡里配置了项目的一些东西,可以详细查看下,这里就不多说了,以下的内容就是参考这个配置做的。
由上面的那么多的学习,这里慢慢新建一个项目。
二、准备文件
首先建立一个文件夹demo,在文件夹里建立
inc、usr、sys三个文件夹如下所示:
图1-1-4:新建文件夹
1.将STM32F429I-Discovery_FW_V1.0.1ProjectsDemonstrationEWARMstm32f4xx_flash.icf 这个文件copy到我们新建的demo目录下。
2.将 STM32F429I-Discovery_FW_V1.0.1LibrariesCMSISInclude 目录下的core_cm4.h
、core_cm4_simd.h、core_cmFunc.h、core_cmInstr.h
复制到 我们建立的目录的demo/inc/文件夹下。
3.将 STM32F429I-Discovery_FW_V1.0.1LibrariesCMSISDeviceSTSTM32F4xxInclude 下的stm32f4xx.h、system_stm32f4xx.h 复制到demo/inc/文件夹下。
inc目录内如如下:
图1-1-5:inc目录内容
4.将 STM32F429I-Discovery_FW_V1.0.1LibrariesCMSISDeviceSTSTM32F4xxSourceTemplates 目录下的system_stm32f4xx.c复制到demo/sys/目录下。
5.将 STM32F429I-Discovery_FW_V1.0.1LibrariesCMSISDeviceSTSTM32F4xxSourceTemplatesiar目录下的startup_stm32f429_439xx.s 复制到 demo/sys/目录下。
三、新建demo
完成了那么多准备工作可以打开IAR新建项目了。
1.打开IAR
7.30新建一个项目
图1-1-6:新建IAR项目
2.将位置保存在我们刚建立的demo文件夹的位置
图1-1-7:保存项目
3.如下图所示,在项目名上右键,添加group
图1-1-8:添加用户组
如下所示:
图1-1-9:添加用户组
4.新建一个main.c的文件,内容如下
#include
int main()
{
while(1);
return 0;
}
为每个组中,添加相应的文件,鼠标在项目名右键-添加-文件。结果如下:
图1-1-10:添加文件
5.配置工程选项
在项目名称上右键点开属性(options),按如下步骤配置:
图1-1-11:单片机选型
图1-1-12:配置compiler
点选我们前面复制的stm32f4xx_flash.icf这个文件。
图1-1-13:配置Linker
配置Debugger
选择ST-Link
图1-1-14:配置Debugger
勾选Use
flash loader(s)
图1-15:配置flash下载
选择SWD模式
图1-1-16:ST-LINK配置
至此点击编译工程如下图所示,没有错误,证明已经建立OK了工程。
图1-1-17:编译工程
2.【新技能get】开发板一起学起来——寄存器点亮LED
简介:点灯,大概是每个单片机开发者,拿到一款新的单片机必用的技能。好,我们也来点个LED,用寄存器来配置一个点灯的程序。
一、硬件连接
STM32F429I Discovery评估板上有两个LED(一个绿色、一个红色),下面的帖子的任务就是点亮这两颗LED,使用的是寄存器来点亮LED。有下面的原理图,可以看到两颗LED与PG13和PG14连接,通过高电平点亮,低电平熄灭。
图1-2-1:LED 电路图
二、时钟
时钟,这个是一个单片机中相当重要的部分。在数字电路中,时钟起到至关重要的作用,正是因为它,才能让这个系统有序的运行。我们来小窥一下STM32F4的时钟树,这是只是简单的介绍,具体还需要自己多去看数据手册研读。直接上图,来看看这棵树:
图1-2-2:时钟树
STM32有5个时钟源:HIS、HSE、MainPLL、LSI、LSE
三个主时钟可以驱动系统
HSI oscillator clock
HSE oscillator clock
Main PLL (PLL) clock
两个第二时钟源
32 kHz 低速内部RC时钟 (LSI RC)
32.768 kHz 低速外部晶振 (LSE crystal)
三、GPIO(Gneral-Purpose Input Output)
将main函数中的内容更改如下:
#include
void main ()
{
RCC->AHB1ENR |= 0x00000040; //使能 GPIOG 时钟
GPIOG->MODER &= 0xc3FFFFFF; //配置PG13 PG14 为输出模式
GPIOG->MODER |= 0x14000000;
GPIOG->ODR=0xffff4000; // 设置PG14输出高电平
while(1);
}
点击编译无措,下载程序到开发板中,就可以看到PG14(RED)被点亮,PG13熄灭
GPIO是算法世界和现实世界的一个桥梁。将你的算法通过IO口和外部交互。IO口 的多少以及功能的多少也是MCU一个重要的因素。
STM32F4xx Family 每一IO口都具有
四个32-bit配置寄存器:GPIOx_MODER、
GPIOx_OTYPER、
GPIOx_OSPEEDR 、GPIOx_PUPDR
两个32-bit
数据寄存器:GPIOx_IDR、GPIOx_ODR
一个 32-bit 复位/置位寄存器:GPIOx_BSRR
一个32-bit 锁存寄存器:GPIOx_LCKR
两个32-bit 功能需选择寄存器:GPIOx_AFRH、GPIOx_AFRL
具体的功能要查看《Reference Manual
RM0090》。
stm32f4xx.h这个就相当于reg52.h里面都是STM32F3的寄存器变量。
RCC->AHB1ENR 学过C的都是都知道 -> 这个是指向的意思,RCC是一个结构体。AHB1ENR是它的一个成员。
具体的我们可以产看stm32f4xx.h文件里面的内容。
在RCC右键,goto 定义的地方,如下图所示:
图1-2-3:goto
define RCC
即可跳转到RCC定义的地方,RCC是RCC_TypeDef 类型的,具体可以查看RCC_TypeDef,会发现AHB1ENR是他的成员变量,如下图所示:
图1-2-4:RCC
图1-2-5:AHB1ENR
AHB1ENR寄存器
图1-2-6:AHB1ENR寄存器
MODER寄存器
图1-2-7:MODER寄存器
端口模式控制寄存器
00:输入(复位模式)
01:通用输入输出功能
10:复用模式
11:模拟模式
ODR寄存器
图1-2-8:ODR寄存器
这个就是数据输出寄存器,,其中[31:16]
为系统保存,[0:15]对应数据的输出。
通过给PG13和PG14 给一个低电平,即可点亮LED。
当然STM32F4功能如此强大,这里只是抛砖引玉的简单的介绍三个寄存器。后面的OTYPER、OSPEEDR、BSRRH、等可以实现上拉下拉输入输出补偿等的一些寄存器,具体可以详细查看数据手册。。。
以上有些内容只是简单的介绍,后面的内容会详细介绍一些上面简单提到的东西。
倘若有什么问题,很高兴你可以跟帖回复,大家一起讨论。。。
后面会详细讲一下时钟树以及SysTick和固件库。由于这几天要出去几天,所以,要等到周六再更新了。
大家有什么问题可以跟帖提问哦。欢迎大家多多来讨论。
3. 【新技能get】开发板一起学起来——固件库点点灯
上一节中,使用了寄存器点灯。简单的介绍了一下寄存器,下面用一个更简单的方法来点灯。
一、固件库添加
首先在以前的文件夹下建立一个stdlib文件夹,将STM32F429I-Discovery_FW_V1.0.1LibrariesSTM32F4xx_StdPeriph_Driver文件夹下的内容复制到 stdlib 文件夹下。在工程文件夹中建立相应的group,然后将刚才添加的文件,添加进来。
如下图所示:
图1-3-1:添加固件库
固件库就是一些API,通过函数可以调用,不像配置寄存器那么麻烦了,但是得掌握和习惯ST公司的函数的书写和命名规则。使用了某个系列的ST公司的单片机的固件库之后,再迁移到ST其它系列的时候,会上手快一些,固件库的命名和功能都是一样或相似的。
如下图可以从文件名就可以相应的功能。
图1-3-1:标准外设固件库
二、时钟简介和配置
SystemInit是system_stm32f4xx.c中的函数。主要的作用是负责系统各种时钟的初始化(系统时钟源选择、PLL倍频和分频、AHB/APB分频器等)。
时钟参数的设置和公式如下:
上面的公式可以表示为:
SYSCLK = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N / PLL_P
HSE_VALUE = 8000000
由上面的宏定义可以配置得到 系统时钟SYSCLK = 168MHz
SystemCoreClockUpdate这个函数根据SystemCoreClock变量的值来更新时钟寄存器。
具体的内容还是参考数据手册的时钟树。
下面为一些默认的设置
HSE_VALUE便是外部时钟的输入值,在stm32f4xx.h定义,可以根据实际修改。
stm32f4xx_rcc.c 这个文件中包含了时钟的配置。
RCC(Reset and clock control)
void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);
void RCC_RTCCLKCmd(FunctionalState NewState);
void RCC_BackupResetCmd(FunctionalState NewState);
void RCC_I2SCLKConfig(uint32_t RCC_I2SCLKSource);
void RCC_SAIPLLI2SClkDivConfig(uint32_t RCC_PLLI2SDivQ);
void RCC_SAIPLLSAIClkDivConfig(uint32_t RCC_PLLSAIDivQ);
void RCC_SAIBlockACLKConfig(uint32_t RCC_SAIBlockACLKSource);
void RCC_SAIBlockBCLKConfig(uint32_t RCC_SAIBlockBCLKSource);
void RCC_LTDCCLKDivConfig(uint32_t RCC_PLLSAIDivR);
void RCC_TIMCLKPresConfig(uint32_t RCC_TIMCLKPrescaler);
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
void RCC_AHB1PeriphClockLPModeCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
void RCC_AHB2PeriphClockLPModeCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
void RCC_AHB3PeriphClockLPModeCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState);
void RCC_APB1PeriphClockLPModeCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
void RCC_APB2PeriphClockLPModeCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE); 来使能外设GPIOG的时钟。详细的请查看User manual的时钟树。
#include
int main()
{
GPIO_InitTypeDef GPIO_Structure;
GPIO_Structure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;
GPIO_Structure.GPIO_Mode = GPIO_Mode_OUT;
SystemInit();
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE); // enable GPIOG clock
GPIO_Init(GPIOG,&GPIO_Structure);
GPIO_ResetBits(GPIOG,GPIO_Pin_13); // 输出低电平
GPIO_SetBits(GPIOG,GPIO_Pin_14); //输出高电平 点亮红色LED
while(1);
}
对应相应的固件库,API的调用虽然ST没有给一本关于API的的说明性PDF。
但是每个 对应 .c 文件都是介绍的相当详细,比如stm32f4xx_gpio.c,中就介绍了IO口的使用方法(不过是英文的),如下:
学习MCU,尽量多去参考官方的资料,别人讲的东西,其实也是参考官方的资料的。
至此便用了固件库来点亮了LED,相比较寄存器来说还是简单了一些。使用固件库呢还是寄存器呢,这个就看个人的习惯和爱好了。
4. 【新技能get】开发板一起学起来——BLINK LED
讲了那么多了,好吧,现在我们来一起闪烁一下LED吧。
给一个灯不停的通高低电平即可以实现LED的闪烁。
最简单的一种方法就是使用延时,让CPU在哪里不停的做一些无用功,可以实现延时,让LED闪烁,程序如下所示:
#include
void delay_ms(unsigned int m)
{
unsigned int i,j;
while(m--)
{
i=168;
while(i--)
{
j=100;
while(j--);
}
}
}
int main()
{
GPIO_InitTypeDef GPIO_Structure;
GPIO_Structure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;
GPIO_Structure.GPIO_Mode = GPIO_Mode_OUT;
SystemInit();
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE); // enable GPIOG clock
GPIO_Init(GPIOG,&GPIO_Structure);
while(1)
{
delay_ms(500);
GPIO_ResetBits(GPIOG,GPIO_Pin_13); //low
delay_ms(500);
GPIO_SetBits(GPIOG,GPIO_Pin_13); // high
}
return 0;
}
以上代码便可以实现简单的LED闪烁。
当然这种方法并不是很好,因为CPU在不停的做减法,做一些无用的功,白白的牺牲了CPU 资源。
下面就介绍一个SyStick。
SysTick是一个24-bit 的系统自减定时器,它是集成在Cortex-M 内核的内部的,并不是片内外设。可以用来产生一些定时中断,一般用作操作系统的时钟节拍。
图1-4-1:SyStick寄存器
图1-4-2:Systick 寄存器描述
CTRL: 控制寄存器, 默认0x0000004
LOAD: 重载寄存器, 默认0x0000000
VAL: 当前值寄存器, 默认0x0000000
CALIB: 校准值寄存器, 默认0x0002328
图1-4-3:向量优先级
#include
unsigned int Ts_Gb;
void delay_ms(uint32_t m)
{
Ts_Gb = m;
while(Ts_Gb != 0);
}
void SysTick_Handler(void)
{
if (Ts_Gb != 0x00)
{
Ts_Gb--;
}
}
int main()
{
GPIO_InitTypeDef GPIO_Structure;
GPIO_Structure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;
GPIO_Structure.GPIO_Mode = GPIO_Mode_OUT;
SystemInit();
SysTick_Config(SystemCoreClock/1000);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG,ENABLE); // enable GPIOG clock
RCC_AHB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE); //enable SYSCFG CLock
GPIO_Init(GPIOG,&GPIO_Structure);
while(1)
{
delay_ms(500);
GPIO_ResetBits(GPIOG,GPIO_Pin_13); //low
delay_ms(500);
GPIO_SetBits(GPIOG,GPIO_Pin_13); // high
}
return 0;
}
以上便可以实现通过中断来实现延时。
SysTick_Config(SystemCoreClock/1000);
RCC_AHB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE); //enable SYSCFG CLock
设置为时钟的千分之一。使能时钟。
SysTick_Handler()每一秒被执行一千次,从而通过delay_ms()来实现间接的延时。
下载到开发板中,既可以看到开发板LED闪烁。
其他内容:
【新技能get】开发板一起学起来——STM32F429 Discovery简介
|