第4章STM32最小系统与嵌入式C语言课件.pptx
《第4章STM32最小系统与嵌入式C语言课件.pptx》由会员分享,可在线阅读,更多相关《第4章STM32最小系统与嵌入式C语言课件.pptx(80页珍藏版)》请在三一办公上搜索。
1、,第4章,STM32最小系统 与嵌入式C语言,STM32,本章知识与能力要求,掌握STM32最小系统设计;理解和掌握嵌入式C语言的程序结构;掌握嵌入式C语言的数据类型、const、volatile和extern等关键字的使用;掌握嵌入式C语言的条件编译;掌握嵌入式C语言指针的应用;学会分析HAL库文件源码。,第4章 STM32最小系统与嵌入式C语言,4.1 STM32最小系统,4.1.1 电源电路,4.1.2 时钟电路(晶振电路),4.1.3 复位电路,4.1.4 调试和下载电路,03,04,01,02,用最少的元件组成单片机可以工作的系统,4.1.1 电源电路,微控制器工作电压,3.4V5.
2、5V或2.7V3.6V,为系统提供稳定可靠的供电,STM32F103系列:2.0V3.6V,电源电压,5V,AMS1117系列芯片,1.5V1.8V2.5V2.85V3.0V3.3V5.0V,供电,4.1.1 电源电路,C1、C3为输入电容,作用是防止断电后出现电压倒置C2、C4为输出滤波电容,作用是抑制自激振荡和稳定输出电压,AMS1117-3.3v降压电路图,电压转换电路提供3.3V电压供STM32主电源VDD使用,4.1.1 电源电路,STM32内部包含一个电压调节器,将外部3.3V电压转换为1.8V提供给Cortex-M3内核、内存以及外设使用。,STM32内部电源框图,内部有两个可选
3、电源选项:ADC模块所需的参考电压VREF+和VREF-。常采用独立的供电电源。备用电池电源VBAT。当主电源VDD掉电后,通过VBAT引脚为实时时钟和备份寄存器提供电源。通常选择备用电池作为该电源,电压范围为1.83.6V。若不使用备用电池供电,则VBAT引脚必须与主电源引脚VDD连接。,4.1.2 时钟电路(晶振电路),时钟系统产生供系统正常工作的稳定的脉冲信号.,单片机的一切指令的执行都依赖于晶振提供的时钟频率,时钟频率越高,单片机运行速度越快,功耗也就越大。,4.1.2 时钟电路(晶振电路),晶振,有源晶振(振荡器),无源晶振(晶体),内部包含晶体管和阻容元件一个完整的谐振振荡器只需要
4、给它供电不需要外接其他元件通常有四个引脚:VCC、GND、晶振输出引脚和一个悬空的引脚。,只有2个引脚的无极性元件需要借助外部电路起振精度上差一些价格便宜,4.1.2 时钟电路(晶振电路),使用低速晶振电路作为系统低速外部时钟源,频率为32.768kHz,主要用作RTC的时钟源,用于精准计时定时电路、万年历等。,使用外部高速晶振电路作为系统时钟源,一般称为高速外部时钟信号(HSE)。一般选择8MHz,方便倍频。,01,02,4.1.3 复位电路,复位电路将系统进行复位,STM32内部复位电路,STM32芯片复位管脚持续为低电平时复位,STM32的NRST引脚在内部已经连接了一个上拉电阻,数据手
5、册建议复位电路需外接一个对地电容,如果认为这个上拉电阻较小,用户也可以在复位电路中外接一个上拉电阻,4.1.3 复位电路,按键S1按下时,RESET和地连通,产生低电平,实现复位。,上电复位:,在上电瞬间,由于电容来两端电压不能突变,RESET出现短暂低电平,芯片自动复位,之后电容充电,充电时间由电阻和电容共同决定:,上电后约1ms左右系统完成复位,之后,单片机开始正常工作。,手动复位:,4.1.4 调试和下载电路,将编译好的程序下载到单片机中运行以及进行在线调试,STM32F103系列微控制器内核集成了SWD/JTAG调试端口(缩写为SWJ-DP)JTAG调试接口(5引脚的JTAG-DP)S
6、WD(Serial Wire Debug,串行单总线调试)( 2引脚的SW-DP),作用,STM32调试端口引脚功能,4.1.4 调试和下载电路,Cortex-M3内核有三种启动方式,可以通过BOOT0和BOOT1的电平组合进行选择。,内核的启动模式,在STM32F103系列微控制器中通过设置BOOT1:0引脚电平的高低选择三种不同启动模式,从而将STM32F103微控制器的存储空间起始地址0 x00000000映射到不同存储区域的起始地址。,4.1.4 调试和下载电路,保持BOOT1为“0”,当BOOT0=1时,STM32F103系列微控制器从系统存储器的起始地址0 x1FFFF000开始启
7、动;当BOOT0=0时,STM32F103系列微控制器从用户Flash的起始地址0 x80000000开始启动运行代码,这是STM32最常用的启动方式。若要从片内SRAM起始地址0 x20000000启动,则BOOT0、BOOT1均设为“1” 。,内核的启动模式,4.2 嵌入式C语言,4.2.1 STM32的数据类型,4.2.2 const 关键字,4.2.3 static 关键字,4.2.4 volatile 关键字,4.2.5 extern 关键字,4.2.8 typedef,4.2.9 #define,4.2.10 #ifdef、#if条件编译,4.2.11 指针,4.2.12 回调函数
8、,4.2.7 enum,4.2.6 struct结构体,4.2 嵌入式C语言,嵌入式开发中既有底层硬件的开发又涉及上层应用的开发,即涉及系统的硬件和软件,C语言既具有汇编语言操作底层的优势,又具有高级语言功能性强的特点。,1,程序总是从main函数开始执行;,2,3,4,5,函数是C语言的基本结构;,函数由两部分组成:函数说明部分和函数体。,一个C语言程序包含若干个源程序文件(.c文件)和头文件(.h文件)。,采用外设功能模块化设计方法,一个外设功能模块包括一个源文件(.c文件)和一个头文件(.h文件)。,4.2 嵌入式C语言,嵌入式系统开发多采用模块化、层次化的设计思想,系统层次架构清晰,便
9、于协同开发。,嵌入式系统软件结构框图,4.2.1 STM32的数据类型,数据是嵌入式C语言的基本操作对象。,数据类型是指数据在计算机内存中的存储方式。,嵌入式C语言的数据类型,4.2.1 STM32的数据类型,不同CPU所定义的数据类型的长度不一致,ST公司为开发人员提供了基于C语言的标准外设库,标准外设库中定义的数据类型的长度如下表所示。,4.2.1 STM32的数据类型,v3.5.0版本已不再使用旧的数据类型,为了兼容以前的版本,stm32f10 x.h头文件还对标准外设库之前版本所使用的数据类型进行了说明。,STM32开发中同一数据类型有多种表示方式。,无符号8位整型数据有unsigne
10、d char,uint8_t,u8三种表示方式。,例,最新的v3.5.0版本采用标准的C99标准,即uint8_t方式。,4.2.1 STM32的数据类型,_I、_O以及_IO为IO类型限定词,内核头文件core_cm3.h定义了标准外设库所使用的IO类型限定词。,数据类型和IO类型限定词结合在一起,在标准外设库中常用来定义寄存器和结构体变量:,4.2.1 STM32的数据类型,stm32f10 x.h头文件中常用的布尔类型的变量的定义,typedef enum DISABLE = 0, ENABLE = !DISABLE FunctionalState;,typedef enum RESET
11、 = 0, SET = !RESET FlagStatus, ITStatus;,typedef enum ERROR = 0, SUCCESS = !ERROR ErrorStatus;,RESET与SET,DISABLE与ENABLE,ERROR与SUCCESS,#define IS_FUNCTIONAL_STATE(STATE) (STATE) = DISABLE) | (STATE) = ENABLE),4.2.2 const关键字,作用,用于定义只读的变量,其值在编译时不能被改变,const 常量类型 常量名=常量表达式;,格式,为了在编译时防止变量的值被误修改,提高程序的安全性和可
12、靠性。,目的,要求,属性,const关键词修饰的变量在声明时必须初始化,在C标准中,const定义的变量是全局的。,4.2.3 static关键词,修饰变量或函数。修饰后的变量称为静态变量。,作用,在全局变量之前加上关键字static,则该全局变量被定义成为一个静态全局变量。,作用范围只在定义该变量的源文件内有效,其他源文件不能引用该全局变量,避免了在其他源文件中因引用相同名字的变量而引发错误,有利于模块化程序设计。,操作,目的,4.2.3 static关键词,#include stm32f1xx_hal.hstatic void DMA_SetConfig(DMA_HandleTypeDef
13、 *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength); HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength) HAL_StatusTypeDef status = HAL_OK; if(HAL_DMA_STATE_READY = hdma-State) DMA_SetConfig(hdma, SrcAddress, D
14、stAddress, DataLength); ,static编程要点1: 模块化的程序设计中,用static声明一个函数,则该函数只能被该模块内的其它函数调用。,解析:DMA_SetConfig()函数只能被stm32f1xx_hal_dma.c的其它函数调用,不能被其它模块的文件使用。,4.2.3 static关键词,void fun_count( ) static count_num = 0; / 声明一个静态局部变量,count_num用作计数器,初值为0。 count_num +; printf(%dn, count_num);int main(void) int i=0; for
15、(i = 0;i = 5;i+) fun_count( ); return 0;,static编程要点2: static除了用于静态全局变量,还用于定义静态局部变量,保证静态局部变量在调用过程中不被重新初始化。,解析:在main函数中每调用一次fun_count( )函数,则静态局部变量count_num加1,而不是每次都被初始化为初值0。,4.2.4 volatile关键字,一个类型修饰符,“易变的”。 volatile char i; 使用volatile关键字定义了一个字符型的变量i,指出i是随时可能发生变化的,每次使用的时候都必须从i的地址中读取。,使用volatile就是不让编译器进
16、行优化,即每次读取或者修改值的时候,都必须重新从内存中读取或者修改,而不是使用保存在寄存器里的备份。,中断服务程序中修改的供其他程序检测的变量需要使用volatile;多任务环境下各任务间共享的标志应添加volatile;存储器映射的硬件寄存器通常也要加volatile进行说明。,作用,使用方式,应用场合,4.2.5 extern关键词,extern int a;,指明此函数或变量的定义在别的文件中,提示编译器遇到此函数或变量时去其他模块中寻找其定义。,作用,使用extern是一个声明而不是重新定义,声明变量a,而不是在定义变量a,并未为a分配内存空间,声明函数funA( ),此函数已在其他文
17、件中定义。,extern C进行链接指定,告知编译器这是采用C语言定义的函数,extern int funA( );,4.2.5 extern关键词,#ifdef _cplusplusextern C#endif#ifdef _cplusplus#endif,解析:如果定义了_cplusplus(C+编译器中自定义的宏),则执行extern“C”语句。C+支持函数重载,而C语言不支持函数重载,在C+环境下使用C函数会出现链接时找不到对应函数的情况,这时需要使用extern “C”进行链接指定,告知编译器使用C语言的命名规则来处理函数。,#ifdef _cplusplusextern C#end
18、if/函数声明#ifdef _cplusplus#endif,当函数有可能被C语言或C+使用时,将函数声明放在extern “C”中以免出现编译错误。,4.2.5 extern关键词,为保证全局变量和功能函数的使用,extern一般用在.h头文件中对某个模块提供给其它模块调用的外部函数及变量进行声明,实际编程中只需要将该.h头文件包含进该模块对应的.c文件,即在该模块的.c文件中加入代码#include xxx.h。,4.2.6 struct结构体,举例,作用,格式,struct用于定义结构体类型,其作用是将不同数据类型的数据组合在一起,构造出一个新的数据类型。,struct一般用法为:str
19、uct 结构体名 类型标识符 成员名1; 类型标识符 成员名2; 结构体变量;,struct person char name8; int age; char sex8; char address20;person_liu;,4.2.6 struct结构体,struct person char name8; int age; char sex8; char address20;struct person person_liu,person_zhang;,结构体变量(如上例中的person_liu)可以不在定义结构体时定义,后续需要时再进行定义。,使用这种定义方式可以很方便地同时定义多个结构体变
20、量。,结构体变量的使用采用如下形式: 结构体变量名. 成员名如:person_liu.age=35;,struct 结构体名 结构体变量;,定义格式,4.2.7 enum关键词,enum Weekdays Monday = 1,Tuesday, Wednesday, Thursday, Friday,Saturday,Sunday Mydays,Olddays;,enum 枚举名 枚举成员1, 枚举成员2, 枚举变量;,用来将一个变量或对象的所有可能的值一一列出,变量取值只限于列举出来的值。,enum枚举类型的用法:,枚举成员的值是常量,不是变量,不能被赋值,但可以将枚举值赋给枚举变量。,枚举
21、类型具有自动编号的功能,第一个枚举成员其默认值为整型的0,后续枚举成员的值在前一个成员上加1。,可以自定义枚举成员的值,如果把第一个枚举元素的值定义为1,那么第二枚举成员的值就为2,以此类推,如上述例子中Friday的值为5。,4.2.8 typedef,给变量起一个容易记且意义明确的新名字;简化一些比较复杂的类型声明。,目的:,用来为复杂的声明定义一个简单的别名,方便记忆,作用:,不是一个真正意义上的新类型,用法一:typedef的基本应用,typedef 类型名 自定义的别名;,格式:,typedef signed char int8_t; /给数据类型signed char起个别名int
22、8_t typedef signed int int32_t; /给数据类型signed int起个别名int32_t,举例:,为已知的数据类型起一个简单的别名,4.2.8 typedef,typedef struct uint16_t GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; GPIO_InitTypeDef;,STM32标准外设库中stm32f10 x_gpio.h头文件中利用结构体别名GPIO_InitTypeDef,使用typedef为这个新建的结构体起了一个新的名字叫GPIO_InitTyp
23、eDef,则可以使用GPIO_InitTypeDef定义一个变量GPIO_InitStructure,从而调用GPIO_Mode。,GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;,用法二:与结构体struct结合使用,4.2.8 typedef,stm32f10 x_gpio.h头文件中的代码。typedef enum GPIO_Speed_10MHz = 1,GPIO_Speed_2MHz, GPIO_Speed_50MHzGPIOSpeed_TypeDef;,解析1:利
24、用typedef关键字将此枚举类型定义一个别名GPIOSpeed_TypeDef,这里省略了枚举类型的枚举名,只用typedef起了个别名。,用法三:与enum结合使用,解析2: enum枚举类型共三个成员,并将第一个枚举成员GPIO_Speed_10MHz赋值为1,enum枚举类型会将枚举成员的赋值在第一个枚举成员赋值的基础上加1,因此,GPIO_Speed_2MHz默认值为2。,4.2.9 #define,#define是C语言中的预处理命令,它用于宏定义,用来将一个标识符定义为一个字符串,该标识符称为宏名,被定义的字符串称为替换文本。,所谓预处理是指在编译之前所做的工作,由预处理程序负责
25、完成,编译时,系统将自动引用预处理程序对源程序中的预处理部分进行处理。,采用宏定义的目的主要是方便程序编写,一般放在源文件的前面,称为预处理部分。,typedef与#define的区别:typedef是在编译阶段处理的;#define是在预处理阶段处理的。,4.2.9 #define,用法一:无参数宏定义,例1:#define UINT8_MAX 255解析:定义宏名UINT8_MAX,代表255。例2:#define _ _IO volatile;解析:定义宏名_ _IO,表示volatile,以后程序中再需要用到volatile,就可以使用_ _IO。例3:#define RCC_AHBP
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- STM32 最小 系统 嵌入式 语言 课件

链接地址:https://www.31ppt.com/p-1488726.html