STM32堆栈分析

STM32堆栈分析
STM32堆栈分析

三、STM32堆栈区

预备知识:

一个由C/C++编译的程序占用的内存分为以下几个部分:

●栈区(stack):编译器自动分配释放,存放函数的参数值,局部变量的值等。操作方式

类似于数据结构中的栈。

●堆区(heap):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。

注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。

●全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局

变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。

●文字常量区—常量字符串就是放在这里的。程序结束后由系统释放

●程序代码区—存放函数体的二进制代码

编译后,各个区存储内容举例说明如下:

//main.cpp

int a = 0; 全局初始化区

char *p1; 全局未初始化区

main()

{

int b; 栈

char s[] = “abc”; 栈

char *p2; 栈

char *p3 = “123456”; 123456\0在常量区,p3在栈上

static int c =0;全局(静态)初始化区

p1 = (char *)malloc(10);

p2 = (char *)malloc(20);

分配得来得10和20字节的区域就在堆区。

strcpy(p1, "123456"); 123456\0放在常量区,编译器可能会将它与p3所指向的"123456"

优化成一个地方。

}

STM32的分区

STM32的分区从0x2000 0000(0x2000 0000是SRAM的起始地址,由此可知,堆栈等都是在RAM中的)开始。静态区,堆,栈。所有的全局变量,包括静态变量之类的,全部存储在静态存储区。紧跟静态存储区之后的,是堆区(如没用到malloc,则没有该区),之后是栈区,栈在程序中存储局部变量。

先看启动文件startup_stm32f10x_md.s的定义:

; Amount of memory (in bytes) allocated for Stack

; Tailor this value to your application needs

; Stack Configuration

; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>

;

Stack_Size EQU 0x00000400

AREA STACK, NOINIT, READWRITE, ALIGN=3

Stack_Mem SPACE Stack_Size

__initial_sp

; Heap Configuration

; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>

;

Heap_Size EQU 0x00000200

AREA HEAP, NOINIT, READWRITE, ALIGN=3

__heap_base

Heap_Mem SPACE Heap_Size

__heap_limit

这里定义了堆栈各自大小,堆:512bytes 栈1k;

所以栈区大小有限制,我们在局部变量中不要定义大数组否则容易溢出。

再看下code ro rw zi

●Code指存储到flash【Rom】中的程序代码。

●ZI英语是zero initial,就是程序中用到的变量并且被系统初始化为0的变量的字节

数,keil编译器默认是把你没有初始化的变量都赋值一个0,这些变量在程序运行

时是保存在RAM中的。

●RW是可读可写变量,就是初始化时候就已经赋值了的,RW + ZI就是你的程序总

共使用的RAM字节数。

●RO是程序中的指令和常量,这些值是被保存到Rom中的。

●Total ROM Size (Code + RO Data + RW Data)这样所写的程序占用的ROM的字节总

数,也就是说程序所下载到ROM flash 中的大小。为什么Rom中还要存RW,因

为掉电后RAM中所有数据都丢失了,每次上电RAM中的数据是被重新赋值的,每次这些固定的值就是存储在Rom中的,为什么不包含ZI段呢,是因为ZI数据

都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包

含进去反而浪费存储空间。

实际上,ROM中的指令至少应该有这样的功能:

1. 将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。

2. 将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中。

1,首先来看:栈(STACK)的问题.

函数的局部变量,都是存放在“栈”里面,栈的英文是:STACK。STACK的大小,我们可以在stm32的启动文件里面设置,在startup_stm32f10x_hd.s里面,开头就有:

Stack_Size EQU 0x00000800

表示栈大小是0X800,也就是2048字节,这样,CPU处理任务的时候,函数局部变量过多可占用的大小就是:2048字节。注意:是所有在处理的函数,包括函数嵌套,递归,等等,都是从这个“栈”里面,来分配的。

所以,如果一个函数的局部变量过多,比如在函数里面定义一个u8 buf[512],这一下就占了1/4的栈大小了,再在其他函数里面来搞两下,程序崩溃是很容易的事情,这时候,一般你会进入到hardfault....

这是初学者非常容易犯的一个错误.切记不要在函数里面放N多局部变量,尤其有大数组的时候!

对于栈区,一般栈顶,也就是MSP,在程序刚运行的时候,指向程序所占用内存的最高地址。比如附件里面的这个程序序,内存占用如下图:

图中,我们可以看到,程序总共占用内存:20+2348字节=2368=0X940

那么程序刚开始运行的时候:MSP=0X2000 0000+0X940=0X2000 0940.

事实上,也是如此,如图:

图中,MSP就是:0X2000 0940,程序运行后,MSP就是从这个地址开始,往下给函数的局部变量分配地址。再说说栈的增长方向,我们可以用如下代码测试:

//保存栈增长方向

//0,向下增长;1,向上增长

static u8 stack_dir;

//查找栈增长方向,结果保存在stack_dir里面

void find_stack_direction(void)

{

static u8 *addr=NULL; //用于存放第一个dummy的地址。

u8 dummy; //用于获取栈地址

if(addr==NULL) //第一次进入

{

addr=&dummy; //保存dummy的地址

find_stack_direction (); //递归

}

else //第二次进入

{

if(&dummy>addr)stack_dir=1; //第二次dummy的地址大于第一次dummy,那么说明栈增长方向是向上的.

else stack_dir=0; //第二次dummy的地址小于第一次dummy,那么说明栈增长方向是向下的. }

}

这个代码不是我写的,网上抄来的,思路很巧妙,利用递归,判断两次分配给dummy的地址,来比较栈是向下生长,还是向上生长。如果你在STM32测试这个函数,你会发现,STM32的栈,是向下生长的。事实上,一般CPU的栈增长方向,都是向下的。

2,再来说说,堆(HEAP)的问题.

全局变量,静态变量,以及内存管理所用的内存,都是属于“堆"区”,英文名:“HEAP”,与栈区不同,堆区,则从内存区域的起始地址开始分配给各个全局变量和静态变量。

堆的生长方向,都是向上的。在程序里面,所有的内存分为:堆+栈,只是他们各自的起始地址和增长方向不同,他们没有一个固定的界限,所以一旦堆栈冲突,系统就到了崩溃的时候了。同样,我们用附件里面的例程测试:

stack_dir的地址是0X2000 0004,也就是STM32的内存起始端的地址。

这里本来应该是从0X2000 0000开始分配的,但是,我仿真发现0X2000 0000总是存放:0X2000 0398,这个值,貌似是MSP,但是又不变化,还请高手帮忙解释下。其他的,全局变量,则依次递增,地址肯定大于0X20000004,比如cpu_endian的地址就是0X20000005。这就是STM32内部堆的分配规则.

3,再说说,大小端的问题.

大端模式:低位字节存在高地址上,高位字节存在低地址上

小端模式:高位字节存在高地址上,低位字节存在低地址上

STM32属于小端模式,简单的说,比如u32 temp=0X12345678;

假设temp地址在0X2000 0010.

那么在内存里面,存放就变成了:

地址| HEX |

0X2000 0010 | 78 56 43 12 |

CPU到底是大端还是小端,可以通过如下代码测试:

//CPU大小端

//0,小端模式;1,大端模式.

static u8 cpu_endian;

//获取CPU大小端模式,结果保存在cpu_endian里面

void find_cpu_endian(void)

{

int x=1;

if(*(char*)&x==1)cpu_endian=0; //小端模式

else cpu_endian=1; //大端模式

}

以上测试,在STM32上,你会得到cpu_endian=0,也就是小端模式.

3,最后说说,STM32内存的问题.

还是以附件工程为例,在前面第一个图,程序总共占用内存:20+2348字节,这么多内存,到底是怎么得来的呢?

我们可以双击Project侧边栏的:Targt1,会弹出test.map,在这个里面,我们就可以清楚的知道这些内存到底是怎么来的了.在这个test.map最后,Image 部分有:

============================================================================== Image component sizes

Code (inc. data) RO Data RW Data ZI Data Debug Object Name

172 10 0 4 0 995 delay.o//delay.c里面,fac_us和fac_ms,共占用4字节

112 12 0 0 0 427 led.o

72 26 304 0 2048 828 startup_stm32f10x_hd.o //启动文件,里面定义了Stack_Size为0X800,所以这里是2048.

712 52 0 0 0 2715 sys.o

348 154 0 6 0 208720 test.o//test.c里面,stack_dir和cpu_endian 以及*addr ,占用6字节.

384 24 0 8 200 3050 usart.o//usart.c定义了一个串口接收数组buffer,占用200字节.

----------------------------------------------------------------------

1800 278 336 20 2248 216735 Object Totals //总共2248+20字节

0 0 32 0 0 0 (incl. Generated)

0 0 0 2 0 0 (incl. Padding)//2字节用于对其

----------------------------------------------------------------------

Code (inc. data) RO Data RW Data ZI Data Debug Library Member Name

8 0 0 0 0 68 __main.o

104 0 0 0 0 84 __printf.o

52 8 0 0 0 0 __scatter.o

26 0 0 0 0 0 __scatter_copy.o

28 0 0 0 0 0 __scatter_zi.o

48 6 0 0 0 96 _printf_char_common.o

36 4 0 0 0 80 _printf_char_file.o

92 4 40 0 0 88 _printf_hex_int.o

184 0 0 0 0 88 _printf_intcommon.o

0 0 0 0 0 0 _printf_percent.o

4 0 0 0 0 0 _printf_percent_end.o

6 0 0 0 0 0 _printf_x.o

12 0 0 0 0 72 exit.o

8 0 0 0 0 68 ferror.o

6 0 0 0 0 152 heapauxi.o

2 0 0 0 0 0 libinit.o

2 0 0 0 0 0 libinit2.o

2 0 0 0 0 0 libshutdown.o

2 0 0 0 0 0 libshutdown2.o

8 4 0 0 96 68 libspace.o //库文件(printf使用),占用了96字节

24 4 0 0 0 84 noretval__2printf.o

0 0 0 0 0 0 rtentry.o

12 0 0 0 0 0 rtentry2.o

6 0 0 0 0 0 rtentry4.o

2 0 0 0 0 0 rtexit.o

10 0 0 0 0 0 rtexit2.o

74 0 0 0 0 80 sys_stackheap_outer.o

2 0 0 0 0 68 use_no_semi.o

2 0 0 0 0 68 use_no_semi_2.o

450 8 0 0 0 236 faddsub_clz.o

388 76 0 0 0 96 fdiv.o

62 4 0 0 0 84 ffixu.o

38 0 0 0 0 68 fflt_clz.o

258 4 0 0 0 84 fmul.o

140 4 0 0 0 84 fnaninf.o

10 0 0 0 0 68 fretinf.o

0 0 0 0 0 0 usenofp.o

----------------------------------------------------------------------

2118 126 42 0 100 1884 Library Totals //调用的库用了100字节.

10 0 2 0 4 0 (incl. Padding) //用于对其多占用了4个字节

----------------------------------------------------------------------

Code (inc. data) RO Data RW Data ZI Data Debug Library Name

762 30 40 0 96 1164 c_w.l

1346 96 0 0 0 720 fz_ws.l

----------------------------------------------------------------------

2118 126 42 0 100 1884 Library Totals

----------------------------------------------------------------------

==============================================================================

Code (inc. data) RO Data RW Data ZI Data Debug

3918 404 378 20 2348 217111 Grand Totals

3918 404 378 20 2348 217111 ELF Image Totals

3918 404 378 20 0 0 ROM Totals

============================================================================== Total RO Size (Code + RO Data) 4296 ( 4.20kB)

Total RW Size (RW Data + ZI Data) 2368 ( 2.31kB) //总共占用:2248+20+100=2368.

Total ROM Size (Code + RO Data + RW Data) 4316 ( 4.21kB)

==============================================================================通过这个文件,我们就可以分析整个内存,是怎么被占用的,具体到每个文件,占用多少.一目了然了.

(完整版)STM32F103xx系列单片机介绍

STM32F103xx系列单片机介绍 STM32F103xx增强型系列由意法半导体集团设计,使用高性能的ARMCortex-M332位的RISC 内核,工作频率为72MHz,内置高速存储器(高达128K字节的闪存和20K字节的SRAM),丰富的增强I/O端口和联接到两条APB总线的外设。所有型号的器件都包含2个12位的ADC、3个通用16位定时器和一个PWM定时器,还包含标准和先进的通信接口:多达2个I2C和SPI、3个USART、一个USB和一个CAN。 1、结构与功能 ■内核:ARM32位的Cortex?-M3CPU ?72MHz,1.25DMips/MHz(Dhrystone2.1),0等待周期的存储器 ?支持单周期乘法和硬件除法 ■存储器 ?从32K字节至512K字节的闪存程序存储器(STM32F103xx中的第二个x表示FLASH容量,其中:“4”=16K,“6”=32K,“8”=64K,B=128K,C=256K,D=384K,E=512K) ?从6K字节至64K字节的SRAM ■时钟、复位和电源管理 ?2.0至3.6伏供电和I/O管脚 ?上电/断电复位(POR/PDR)、可编程电压监测器(PVD) ?内嵌4至16MHz高速晶体振荡器 ?内嵌经出厂调校的8MHz的RC振荡器 ?内嵌40kHz的RC振荡器 ?PLL供应CPU时钟 ?带校准功能的32kHzRTC振荡器 ■低功耗 ?睡眠、停机和待机模式 ?VBAT为RTC和后备寄存器供电 ■2个12位模数转换器,1us转换时间(16通道) ?转换范围:0至3.6V ?双采样和保持功能 ?温度传感器 ■DMA ?7通道DMA控制器 ?支持的外设:定时器、ADC、SPI、I2C和USART ■多达80个快速I/O口 ?26/37/51/80个多功能双向5V兼容的I/O口 ?所有I/O口可以映像到16个外部中断

STM32的8种输入输出方式

如图所示,推挽放大器的输出级有两个“臂”(两组放大元件),一个

输入高电平时,输出端的电流将是下级门从本级电源经VT3拉出。这样一来,输出高低电平时,VT3 一路和 VT5 一路将交替工作,从而减低了功耗,提高了每个管的承受能力。又由于不论走哪一路,管子导通电阻都很小,使RC常数很小,转变速度很快。因此,推拉式输出级既提高电路的负载能力,又提高开关速度。 开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内). 开漏形式的电路有以下几个特点: 1. 利用外部电路的驱动能力,减少IC内部的驱动。当IC内部MOSFET导通时,驱动电流是从外部的VCC流经R pull-up ,MOSFET到GND。IC内部仅需很下的栅极驱动电流。 2. 一般来说,开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻时,只能输出低电平,如果需要同时具备输出高电平的功能,则需要接上拉电阻,很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平。比如加上上拉电阻就可以提供TTL/CMOS电平输出等。(上拉电阻的阻值决定了逻辑电平转换的沿的速度。阻值越大,速度越低功耗越小,所以负载电阻的选择要兼顾功耗和速度。) 3. OPEN-DRAIN提供了灵活的输出方式,但是也有其弱点,就是带来上升沿的延时。因为上升沿是通过外接上拉无源电阻对负载充电,所以当电阻选择小时延时就小,但功耗大;反之延时大功耗小。所以如果对延时有要求,则建议用下降沿输出。 4. 可以将多个开漏输出的Pin,连接到一条线上。通过一只上拉电阻,在不增加任何器件的情况下,形成“与逻辑”关系。这也是I2C,SMBus等总线判断总线占用状态的原理。补充:什么是“线与”?: 在一个结点(线)上, 连接一个上拉电阻到电源 VCC 或 VDD 和 n 个 NPN 或 NMOS 晶体管的集电极 C 或漏极 D, 这些晶体管的发射极 E 或源极 S 都接到地线上, 只要有一个晶体管饱和, 这个结点(线)就被拉到地线电平上. 因为这些晶体管的基极注入电流(NPN)或栅极加上高电平(NMOS),晶体管就会饱和, 所以这些基极或栅极对这个结点(线)的关系是或非 NOR 逻辑. 如果这个结点后面加一个反相器, 就是或 OR 逻辑. 其实可以简单的理解为:在所有引脚连在一起时,外接一上拉电阻,如果有一个引脚输出为逻辑0,相当于接地,与之并联的回路“相当于被一根导线短路”,所以外电路逻辑电平便为0,只有都为高电平时,与的结果才为逻辑1。 关于推挽输出和开漏输出,最后用一幅最简单的图形来概括: 该图中左边的便是推挽输出模式,其中比较器输出高电平时下面的PNP三极管截止,而上面NPN三极管导通,输出电平VS+;当比较器输出低电平时则恰恰相反,PNP三极管导通,输出和地相连,为低电平。右边的则可以理解为开漏输出形式,需要接

stm32入门C语言详解

阅读flash:芯片内部存储器flash操作函数我的理解——对芯片内部flash进行操作的函数,包括读取,状态,擦除,写入等等,可以允许程序去操作flash上的数据。 基础应用1,FLASH时序延迟几个周期,等待总线同步操作。推荐按照单片机系统运行频率,0—24MHz时,取Latency=0;24—48MHz时,取Latency=1;48~72MHz时,取Latency=2。所有程序中必须的 用法:FLASH_SetLatency(FLASH_Latency_2); 位置:RCC初始化子函数里面,时钟起振之后。 基础应用2,开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的 用法:FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); 位置:RCC初始化子函数里面,时钟起振之后。 3、阅读lib:调试所有外设初始化的函数。 我的理解——不理解,也不需要理解。只要知道所有外设在调试的时候,EWRAM需要从这个函数里面获得调试所需信息的地址或者指针之类的信息。 基础应用1,只有一个函数debug。所有程序中必须的。 用法:#ifdef DEBUG debug(); #endif 位置:main函数开头,声明变量之后。 4、阅读nvic:系统中断管理。 我的理解——管理系统内部的中断,负责打开和关闭中断。 基础应用1,中断的初始化函数,包括设置中断向量表位置,和开启所需的中断两部分。所有程序中必须的。 用法:void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; //中断管理恢复默认参数 #ifdef VECT_TAB_RAM //如果C/C++ Compiler\Preprocessor\Defined symbols中的定义了 VECT_TAB_RAM(见程序库更改内容的表格) NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); //则在RAM调试 #else //如果没有定义VECT_TAB_RAM NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);//则在Flash里调试 #endif //结束判断语句 //以下为中断的开启过程,不是所有程序必须的。 //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC优先级分组,方式。 //注:一共16个优先级,分为抢占式和响应式。两种优先级所占的数量由此代码确定, NVIC_PriorityGroup_x可以是0、1、2、3、4,分别代表抢占优先级有1、2、4、8、16个和响应优先级有16、8、4、2、1个。规定两种优先级的数量后,所有的中断级别必须在其中选择,抢占级别高的会打断其他中断优先执行,而响应级别高的会在其他中断执行完优先执行。 //NVIC_InitStructure.NVIC_IRQChannel = 中断通道名; //开中断,中断名称见函数库 //NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 //NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应优先级 //NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //启动此通道的中断 //NVIC_Init(&NVIC_InitStructure); 中断初始化

stm32知识点最终版!

1.*嵌入式系统:以计算机技术为基础,以应用为中心,软件硬件可剪裁,适合应用系统对功能可靠性、成本、体积、功耗严格要求的专业计算机系统。 2.*嵌入式系统与传统系统等所区分的三个特征:微处理器通常由32位以上的RISC组成;软件通常是以嵌入式操作系统为核心,外加用户应用程序;具有明显的可嵌入性。 3.*嵌入式系统的应用:智能消费电子中;工业控制中;医疗设备中;信息家电及家庭智能管理系统;网络与通信系统中;环境工程;机器人。 4.*ARM定义的三大分工明确的系列:“A”系列面向尖端的基于虚拟内存的操作系统和用户应用(针对日益增长的运行包括linux、Windows、CE和Android在内的消费电子和无线产品);“R”系列针对实时系统(针对需要运行实时操作系统来惊醒控制应用的系统,包括汽车电子、网络和影像系统);“M”系列对胃控制器和点成本应用提供优化(针对开发费用低功耗低,同时针对性能要求不断增加的嵌入式应用而设计,如汽车车身控制系统和各种大型家电)。 5.ARM Cortex处理器系列是基于ARMv7构架的产品,既有ARM Cortex-M系列,也有高性能的A系列。 6.NEON技术是64/128位SIMD指令集,用于新一代媒体和信号处理应用加速。NEON支持8位,16位,32位,64位整数及单精度浮点SIMD操作,以进行音频,视频、图像和游戏的处理。 7.ARM Cortex-M3处理器的特点:性能丰富成本低,低功耗,可配置性能强,丰富的链接。 8.*STM32F10x处理器分为:101,102,103,105,107。 9.*STM32的总线速度:USB接口速度12Mb/s;USART接口速度4.5Mb/s;SPI接口速度可达18Mb/s;IC接口速度400kHz。 10.STM32系列处理器的优点:先进的内部结构;三种功耗控制;最大程度集成整合;出众及创新的外设。 11.STM32F10x按性能分为:基本型STM32F101,USB基本型STM32F102,增强型STM32F103,互联网型STM32F105、STM32F107系列。 12.STM32F103RBT6系列的命名规则:R-引脚数量、B-Flash大小、T-封装、6-工作温度。 13.*STM32F103按照引脚功能分为:电源、复位、时钟控制、启动配置、输入输出口。 14.STM32F103总线系统包括:驱动单元、被动单元、总线矩阵。 15.最小系统是指仅包含必须的元器件、仅可运行最基本软件的基本系统。 16.典型的最小系统包括:微控制器芯片、供电电路、时钟电路、复位电路、启动配置电路和程序下载电路。 第三章 1.STM32标准库命名则:PPP_Init:根据PPP_InitTypeDef中指定的参数初始化外设ppp; PPP_DeInit:将外设PPP寄存器重设为缺省值; PPP_StructInit:将PPP_InitTypeDef结构中的参数设为缺省值; PPP_Cmd:使能或失能PPP外设; PPP_ItConfig:使能或失能PPP外设的中断源; PPP_GetITStatus:判断PPP外设中断发生与否; PPP_ClearITPendingBit:清除PPP外设中断待处理标志位; PPP_DMAConfig:使能或者失能PPP外设的DMA接口; PPP_GetFlagStatus:检查PPP外设的标志位; PPP_ClearFiag:清除PPP外设的标志位。 2.文件结构:每个C程序通常分为两个文件,一个文件用于保存程序的声明,成为头文件,以.h为后缀。另一个用于保存程序的实现,称为源文件,以.c后缀。 3.C语言的关键字有32个,根据作用分为数据类型、控语言、储存类型、其他关键字。 4.指针:是C语言中广泛使用的一种数据类型. 5.指向数组元素的指针 定义一个整形数组和一个指向整型的指针变量: Int a [10]; Int*p=NULL;//定义指针式要初始化 P=a;//数组名a为数组第0个元素的地址 //与p=&a[0]等价 P+i和a+i表示a[i]的地址;*(p+i)和*(a+i)表示P+i和a+i内容。 6.结构体:是由基本数据类型构成的,并并一个标识符来命名的各种变量的组合。

stm32f107 新手入门笔记

对于STM32学习我的熟悉过程可以分以下阶段: 1、入门程序的熟悉 2、GPIOX的操作,各类寄存器原理的了解 3、逐个寄存器熟悉 4、中断,定时器的基础入门熟悉 5、USART的了解, 6、重复2345的步骤,加深对这些模块寄存器直接的协同了解突破,达到熟练。 在这里,我发下了STM32的USART基本字节发送非常简单,然后用这个来配合中断显示,在程序中插入各类输出显示,可以很清楚的知道程序中的运行状态,先后次序,对于程序调试有很大帮助。 STM32F107开发板入门篇一——第一个程序的理解: 准备开发环境MDK4.0以上,最简单的入门方式就是先调用MDK里面自带的例程程序,然后最好是先看 D:\Keil\ARM\Boards\Keil\MCBSTM32C\Blinky\Blinky.c 这里我就拿例这个例程序分析,虽然每句都分析了,但是刚入手STM32可能还是会有很多疑问,所以暂时不考虑寄存器问题,这里先给出一个程序的概念以及一些基本注意的东西,后面会有寄存器的说明: 阅读下面程序最好用MDK打开上面的程序配合看,效果更直观。 RCC->APB2ENR|=1<<6; //使能PE口时钟(STM32所有的寄存器操作都需要先使能时钟) GPIOE->CRH=0x33333333; //配置PE口的高八位输出方式每位由4位二进制数控制,这里每位都是0011 代表50MHZ的高速输出参考GPIO->CRH SystemInit(); /* Setup and initialize ADC converter */ RCC->APB2ENR |= 1 << 9; /* Enable ADC1 clock ADC1使能时钟*/ GPIOC->CRL &= 0xFFF0FFFF; /* Configure PC4 as ADC.14 input ADC1在此芯片用PC4来作为模拟输入设置为输入(IO口使用前都必须对其功能设置)*/ ADC1->SQR1 = 0x00000000; /* Regular channel 1 conversion 主要是第1,2位设置为0表示单通道采集其他位置0不是用其他功能*/ ADC1->SQR2 = 0x00000000; /* Clear register 清领SQR2寄存器不适用其他功能*/ ADC1->SQR3 = 14 << 0; /* SQ1 = channel 14 选用通道14,就是PC4 */ ADC1->SMPR1 = 5 << 12; /* Channel 14 sample time is 55.5 cyc 通道14的采样周期选择101 即55.5周期*/ ADC1->SMPR2 = 0x00000000; /* Clear register 清0采样寄存器二*/ ADC1->CR1 = 1 << 8; /* Scan mode on 开启扫描模式*/ ADC1->CR2 = (1 << 20) | /* Enable external trigger */

stm32芯片简介

单片机存储器处理器成本STM32 背景如果你正为项目的处理器而进行艰难的选择:一方面抱怨16位单片机有限的指令和性能,另一方面又抱怨32位处理器的高成本和高功耗,那么,基于ARM Cortex-M3内核的STM32系列处理器也许能帮你解决这个问题。使你不必在性能、成本、功耗等因素之间做出取舍和折衷。 即使你还没有看完STM32的产品手册,但对于这样一款融合ARM和ST技术的“新生儿”相信你和我一样不会担心这款针对16位MCU应用领域的32位处理器的性能,但是从工程的角度来讲,除了芯片本身的性能和成本之外,你或许还会考虑到开发工具的成本和广泛度;存储器的种类、规模、性能和容量;以及各软件获得的难易,我相信你看完本专题会得到一个满意的答案。 对于在16位MCU领域用惯专用在线仿真器(ICE)的工程师可能会担心开发工具是否能够很快的上手?开发复杂度和整体成本会不会增加?产品上市时间会不会延长?没错,对于32位嵌入式处理器来说,随着时钟频率越来越高,加上复杂的封装形式,ICE已越来越难胜任开发工具的工作,所以在32位嵌入式系统开发中多是采用JTAG仿真器而不是你熟悉的ICE。但是STM32采用串行单线调试和JTAG,通过JTAG调试器你可以直接从CPU获取调试信息,从而将使你的产品设计大大简化,而且开发工具的整体价格要低于ICE,何乐而不为? 有意思的是STM32系列芯片上印有一个蝴蝶图像,据ST微控制器产品部Daniel COLONNA 先生说,这是代表自由度,意在给工程师一个充分的创意空间。我则“曲解”为预示着一种蝴蝶效应,这种蝴蝶效应不仅会对方案提供商以及终端产品供应商带来举足轻重的影响,而且会引起竞争对手策略的改变……翅膀已煽动,让我们一起静观其变! STM32市面上流通的型号截至2010年7月1日,市面流通的型号有:基本型:STM32F101R6 STM32F101C8 STM32F101R8 STM32F101V8 STM32F101RB STM32F101VB 增强型:STM32F103C8 STM32F103R8 STM32F103V8 STM32F103RBSTM32F103VB STM32F103VE STM32F103ZE STM32系列的作用简介ARM公司的高性能”Cortex-M3”内核 1.25DMips/MHz,而ARM7TDMI只有0.95DMips/MHz 一流的外设 1μs的双12位ADC,4兆位/秒的UART,18兆位/秒的SPI,18MHz的I/O翻转速度低功耗 在72MHz时消耗36mA(所有外设处于工作状态),待机时下降到2μA 最大的集成度 复位电路、低电压检测、调压器、精确的RC振荡器等 简单的结构和易用的工具 STM32F10x重要参数2V-3.6V供电 容忍5V的I/O管脚 优异的安全时钟模式 带唤醒功能的低功耗模式 内部RC振荡器 内嵌复位电路 工作温度范围: -40°C至+85°C或105°C STM32F101性能特点36MHz CPU 多达16K字节SRAM 1x12位ADC温度传感器 STM32F103性能特点72MHz CPU多达20K字节SRAM 2x12位ADC 温度传感 PWM定时器 CAN USB STM32互联型系列简介:全新STM32互连型(Connectivity)系列微控制器增加一个全

一份不错的STM32学习计划

一份不错的STM32学习计划 基于ARM公司Cortex-M3内核的STM32系列芯片具有高效的内核,丰富的外设,优异的实时性能,杰出的功耗控制,且具有有竞争力的价格,应用前景看好。作为对STM32了解不多的电子工作者,有必要了解STM32的特性,学习其使用方法,为将来工程应用打下基础。 为了能快速的上手STM32,特制定了基于“EK-STM32F仿真学习套件”的新手上路计划。该套件基于STM32F103VB芯片,片内资源丰富,并外扩了丰富的硬件接口,是很好的学习入门工具。此学习计划重点学习STM32的软件编程方法,通过学习和编写一些实验程序,可初步了解STM32各功能模块的使用方法,为更深一步的工程应用打下基础。 利用EK-STM32仿真学习板完成以下实验: 1. 利用4个LED实现流水灯.学习GPIO的输出控制功能. 2. 利用按键KEY3和KEY4分别控制LED1,2和LED3,4的亮灭,采用扫描方法.学习GPIO的输入功能. 3. 利用按键KEY3和KEY4分别控制LED1,2和LED3,4的亮灭,采用中断方法.学习外部中断功能. 4. 利用LCD数码显示屏显示从1自加到9999,步进值根据数字位数不同分别为1,10,100,1000.练习GPIO控制功能,熟悉LCD的编程方法. 5. 利用五维摇杆控制LCD显示数字1-5.练习GPIO的输入/输出控制功能. 6. 利用五维摇杆和LCD屏实现秒表功能.学习定时器的使用. 7. 利用PWM控制LED的亮度变化.学习定时器的PWM功能. 8. 上位机通过UART1控制LCD屏显示数字.学习UART的数据接收功能. 9. 上位机通过UART1和学习板实现简单的问答功能.学习UART的数据发送功能. 10. 利用电位器控制LCD屏显示不同电压.学习ADC功能使用. 11. 采用I2C的24C02读写实验.学习I2C功能. 12. SD卡读写实验.学习SPI功能. 13. USB简单通讯实验.学习USB功能. 因为此学习方案定位于新手入门,所以难度不算太大。但是USB由于以前没有接触过,所以需要多下功夫学习。ST官方有提供USB的固件,同时有很多资料可以参考,也可以向EDN上的高手请教,顺利完成USB通讯实验应该没有太大问题。还有一个问题是SD卡读写实验,因为对SD卡了解较少,需要进一步查阅资料学习。 通过完成上述实验项目,可以学习STM32的GPIO、定时器、UART、SPI、I2C、ADC、

献给新手:解析STM32的库函数

意法半导体在推出STM32微控制器之初,也同时提供了一套完整细致的固件开发包,里面包含了在STM32开发过程中所涉及到的所有底层操作。通过在程序开发中引入这样的固件开发包,可以使开发人员从复杂冗余的底层寄存器操作中解放出来,将精力专注应用程序的开发上,这便是ST推出这样一个开发包的初衷。 但这对于许多从51/AVR这类单片机的开发转到STM32平台的开发人员来说,势必有一个不适应的过程。因为程序开发不再是从寄存器层次起始,而要首先去熟悉STM32所提供的固件库。那是否一定要使用固件库呢?当然不是。但STM32微控制器的寄存器规模可不是常见的8位单片机可以比拟,若自己细细琢磨各个寄存器的意义,必然会消耗相当的时间,并且对于程序后续的维护,升级来说也会增加资源的消耗。对于当前“时间就是金钱”的行业竞争环境,无疑使用库函数进行STM32的产品开发是更好的选择。本文将通过一个简单的例子对STM32的库函数做一个简单的剖析。 以最常用的GPIO设备的初始化函数为例,如下程序段一: GPIO_InitTypeDef GPIO_InitStructure; 1 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; 2 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 4 GPIO_Init(GPIOA , &GPIO_InitStructure 5 这是一个在STM32的程序开发中经常使用到的GPIO初始化程序段,其功能是将GPIOA.4口初始化为推挽输出状态,并最大翻转速率为50MHz。下面逐一分解: 首先是1,该语句显然定义了一个GPIO_InitTypeDef类型的变量,名为GPIO_InitStructure,则找出GPIO_InitTypeDef的原型位于“stm32f10x_gpio.h” 文件,原型如下: typedef struct { u16 GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMode_TypeDef GPIO_Mode; }GPIO_InitTypeDef; 由此可知GPIO_InitTypeDef是一个结构体类型同义字,其功能是定义一个结构体,该结构体有三个成员分别是u16类型的GPIO_Pin、 GPIOSpeed_TypeDef 类型的GPIO_Speed和GPIOMode_TypeDef 类型的 GPIO_Mode。继续探查GPIOSpeed_TypeDef和GPIOMode_TypeDef类型,在“stm32f10x_gpio.h”文件中找到对GPIOSpeed_TypeDef的定义: typedef enum { GPIO_Speed_10MHz = 1,

【设计教程大集合】STM32F3XX大全

STM32F3系列是意法半导体ARM? Cortex?-M4微控制器产品组合的入门级产品。经过市场检验的M4处理器内核可支持DSP指令,内置浮点单元(FPU),运行频率高达72MHz,若再搭配意法半导体独有的且基于内核耦合存储器(CCM-SRAM) 的程序加速(Routine Booster) 功能,其电机控制等例行程序的执行速度可比原来提升43%。STM32F3系列属于共有600余款产品的STM32产品家族,性能表现比STM32F1 Cortex-M3系列更加出色。STM32系列产品的软硬件具有广泛的共性,并提供简单易用的设计工具和开发生态系统。 基本资料 【产品新闻】意法半导体(ST)推出闪存容量高达512KB的STM32F3微控制器,大幅提升系统集成度 【数据手册】STM32F358xC、STM32F378xx、STM32F318、STM32F302、STM32F303等ARM Cortex-M4 32位内核 【硬件资源】STM32F3系列固件、软件、工具资源 【视频】意法半导体STM32F3系列探索套件(discovery kit)介绍 进阶设计 目前意法半导体针对智慧型手机Sensor Hub提供采用Cortex-M0核心开发的STM32F072、采用Cortex-M4核心开发的STM32F301和STM32F401,以及采用Cortex-M4核心开发的STM32F429,其中三星(Samsung)智慧型手机Note 3的Sensor Hub中,即搭载该公司STM32F401。 【STM32F303开发】+视觉姿态识别 对一个目标进行姿态识别,以简单的三角形为例,目标放置在一个旋转平台上,初始姿态位置,通过图像识别姿态,并将姿态数据传送给nucleo,nucleo驱动舵机进行角度调整。

STM32单片机实习,第一课,工程模板建立篇

第一天学习笔记 序号:06 班级:232183 姓名:王猛一、实训项目 基于STM32的智能小车。 二、基本原理 1、嵌入式与STM32 A.什么是嵌入式? 简单的说,除了PC和服务器之外,所有的控制类设备都是嵌入式。 B.嵌入式的特点 硬件特点: ◆体积小、集成效率高; ◆面向特定的应用; ◆功耗低、电磁兼容性好; 如图:

软件特点: 嵌入式软件的开发和硬件紧密相连;

?软件代码效率高并且可靠性好; ?软件一般固化在FLASH和ROM中; ?软件系统要有高实时性; ?一般用c语言开发; 如图: C.主流嵌入式芯片的架构 ARM————英国的一家公司(只设计芯片的IP内核,授权给其他半导体公司)ARM————是一款功耗很低、性能很高的处理器芯片的架构; ARM以前的架构:ARM7、ARM9、ARM11(已经不用); ARM现在的架构:cortex A\R\M; Cortex A系列:开放式操作系统的高处理器(A8\A9\A53\A72); 应用产品:上网本、数字电视、家用网关等

Cortex R系列:面向实时应用; 应用产品:汽车制动系统、航空、动力传输系统等;

Cortex M系列:面向确定性的成本敏感的产品; 应用产品:门禁、扫地机器人、平衡车、无人机、手环等;

D.C51和STM32 51单片机是嵌入式学习中的一款入门级MCU,51单片机诞生于70年代,属于传统的8位单片机,51单片机不能满足市场需求,所以需要新的MCU,也就是STM32; ARM公司推出了基于ARMv7架构的32位的cortex M3\M4的微控制器内核,ST(意法半导体)公司就推出了基于cortex M3\M4内核的MCU,也就是STM32,性价比很高,成本低,简单易用的库函数开发。 E.STM32的应用领域 STM32属于微控制器,自带了很多常用的通信接口(UART\IIC\SPI),可以接非常多的传感器,可以控制很多的设备。 如:无人机、平衡车、智能水杯等

stm32f1与4系列的区别

以前看到摘录的,帖过来参考: F1采用Crotex M3内核,F4采用Crotex M4内核。 F1最高主频 72MHz, F4最高主频168MHz。 F4具有单精度浮点运算单元,F1没有浮点运算单元。 F4的具备增强的DSP指令集。F4的执行16位DSP指令的时间只有F1的30%~70%。F4执行32位DSP指令的时间只有F1的25~60%。 F1内部SRAM最大64K字节, F4内部SRAM有192K字节(112K+64K+16K)。 F4有备份域SRAM(通过Vbat供电保持数据),F1没有备份域SRAM。 F4从内部SRAM和外部FSMC存储器执行程序的速度比F1快很多。F1的指令总线I-Bus只接到Flash上,从SRAM和FSMC取指令只能通过S-Bus,速度较慢。F4的I-Bus不但连接到Flash上,而且还连接到SRAM和FSMC上,从而加快从SRAM或FSMC取指令的速度。 F1最大封装为144脚,可提供112个GPIO;F4最大封装有176脚,可提供140个GPIO。 F1的GPIO的内部上下拉电阻配置仅仅针对输入模式有用,输出时无效。而F4的GPIO在设置为输出模式时,上下拉电阻的配置依然有效。即F4可以配置为开漏输出,内部上拉电阻使能,而F1不行。 F4的GPIO最高翻转速度为84MHz,F1最大翻转速度只有18MHz。 F1最多可提供5个UART串口,F4最多可以提供6个UART串口。 F1可提供2个I2C接口,F4可以提供3个I2C接口。 F1和F4都具有3个12位的独立ADC,F1可提供21个输入通道,F4可以提供24个输入通道。F1的ADC最大采样频率为1Msps,2路交替采样可到2Msps(F1不支持3路交替采样)。F4的ADC最大采样频率为2.4Msps,3路交替采样可到7.2Msps。 F1只有12个DMA通道,F4有16个DMA通道。F4的每个DMA通道有4*32位FIFO,F1没有FIFO。 F1的SPI时钟最高速度为 18MHz, F4可以到37.5MHz。 F1没有独立的32位定时器(32位需要级联实现),F4的TIM2和TIM5具有32位上下计数功能。 F1和F4都有2个I2S接口,但是F1的I2S只支持半双工(同一时刻要么放音,要么录音),而F4的I2S支持全双工,放音和录音可以同时进行。

写第一个STM32程序常见错误及解决方法

1.启动KEIL,创建工程以后,先用创建文件,然后什么也不干,直接点击保存,保存 到你的工程文件夹下面,命名为main.c(其他也可以,命名为main.c是为了方便你同其他的C文件快速区分开来)。 然后输入以下几行代码: #include "stm32f10x.h" void main(void) { } 然后点击Build,会有以下报错信息: C:\Keil\ARM\Inc\ST\STM32F10x\stm32f10x.h(96): error: #35: #error directive: "Please select first the target STM32F10x device used in your application (in stm32f10x.h file)" 这是说stm32f10x.h中要求工程在预编译时通过一个字符串,来识别所用的芯片FLASH大小,然后确定头文件中哪些语句有效。ST把STM32按FLASH大小尺寸来归类的,具体在STM32参考手册里面有。 解决办法:请点击 中的 打开的界面中选到选项,然后Define里面输入STM32F10X_MD(因为这个实验板上 用的STM32F103C8T6对应这个“中等容量的FLASH”,换做其他芯片不一定是这个字符串),如图:

然后点击OK。 再,然后会出第二个错误: C:\Keil\ARM\Inc\ST\STM32F10x\stm32f10x.h(8297): error: #5: cannot open source input file "stm32f10x_conf.h": No such file or directory 这说明文件包含的路径没有设置好。 解决办法: 按上面所述选到选项。然后在 下选择,再点击,然后打开目录找到固件库里面的 这个文件(最好能把这个文件夹复制出来保存到一个纯英文路径的目录下),然后选择中里面的inc文件夹,然后再如法炮制选中里面的src文件夹。然后点击确定。效果如图: 点击OK,然后出现下图,再点OK保存

新手如何利用KEIL 5 新建 STM 32 LED灯闪烁

新手如何利用KEIL5新建STM32单片机LED闪烁灯 刚刚接触keil5这个软件,同时也刚刚接触STM32单片机,这两样东西,对于我来说,我完全就是一个门外汉,什么都不懂,为了建立这个LED闪烁灯,一个半月下来了,才刚刚建立完成。 现在把建立LED闪烁灯过程步骤,书写下来,以供新手参考 1、打开keil5软件,然后点击新建工程 保存新建工程路径以及工程名称

保存成功后,就会弹出一个对话框,让选择单片机型号。然后选择合适的单片机。 选完单片机后,点击OK按钮,弹出对话框

点开CMSIS,选择CORE,别问我为何选这个,我也不懂, 再点开Device,选择图片中绿色的部分,别问为什么,我也不懂啊!!我也挺郁闷的,为何这样选择。(如果亲们不论现在还是将来知道这么做的原因,请告诉我,谢谢!!) PS:在网上找别人的,别人说,这些是Keil5的启动文件,arm内核的文件,ST公司的函

数库和一些API等等,RCC(时钟初始化)CORE和STARTUP(初始化文件)这两个。 然后在工程文件路径下,新建一个“SYSTEM”,这个名称可以自定义。用来存放常用程序,如下图 新建一个空白文件,保存为“main.c”格式 PS:之前截图的时候,保存格式保存错了,所以又重新建了一个新工程,所以这个图片会和后面的截图中,保存路径不一致。但不影响说明 然后选择添加刚刚新建立的main.c文件,单击Add即可添加成功,然后关闭退出。

接着选择这个按钮 在Groups中,点击右侧虚线框,添加之前新建立的“SYSTEM”文件夹,以及“main.c”所在的文件夹。同时点击右侧Add Files添加文件夹下对应的C文件

STM32启动文件选用说明

stm32 启动文件的选择 最近在网上看到一些关于STM32启动文件的问题帖,都是类似这样的问题: 随便选两个 “startup_stm32f10x_ld、hd、md这3个启动文件有什么不同???” “官网固件库中的启动文件有啥区别,怎么选择?” 搜索了论坛,也看了一下,有一些回答,但是都不太全或者不甚明了。其实我以前也不清楚,当然我是新手,只不过是个爱折腾的新手,因为我觉得,这个有必要弄清楚。一是启动文件在一个工程中有着不可取代的作用,二是对于STM32这个让人蛋疼而又强大的东东,经常是新手乱添加启动文件或者去找一下工程例子“依葫芦画瓢”的添加,试问你的MCU和人家工程例子的就是一样,换一款型号,要命[夸张的修辞手法,呵呵]?所有说,基于这些,我就说一说我的认识: 注意此处只针对MDK-ARM的IDE,其他的一样,只不过想说明的是对不同的IDE,同一芯片型号的启动文件的“内容”是不一样的,这是因为编译器造成的,意思就是说,启动文件的功能一样,但是指令有所 区别。这个每个启动文件也注释了,如: (原文件名:.s for MDK IAR.JPG) 啰嗦了…… 启动文件的作用: 无论性能高下,结构简繁,价格贵贱,每一种微控制器(处理器)都必须有启动文件,启动文件的作用便是负责执行微控制器从“复位”到“开始执行main函数”中间这段时间(称为启动过程)所必须进行的工作。最为常见的51,AVR或MSP430等微控制器当然也有对应启动文件,但开发环境往往自动完整地提供了这个启动文件,不需要开发人员再行干预启动过程,只需要从main函数开始进行应用程序的设计即可。[来 自网上] 我的理解,说白了,大家常说,程序执行都从main函数开始,是的,没错,但是在这之前是谁来完成了这一个繁琐而又复杂的启动过程呢?就是它。(看来.s尽干脏活苦活,就像“活雷锋一样,做了好事有不 留名”) 具体的启动过程论坛里有,想了解的可以去细看。

STM32芯片型号的命名规则

STM32芯片型号的命名规则 一 STM32F105和STM32F107互连型系列微控制器之前,意法半导体已经推出STM32基本型系列、增强型系列、USB基本型系列、增强型系列;新系列产品沿用增强型系列的72MHz 处理频率。内存包括64KB到256KB闪存和20KB到64KB嵌入式SRAM。新系列采用LQFP64、LQFP100和LFBGA100三种封装,不同的封装保持引脚排列一致性,结合STM32平台的设计理念,开发人员通过选择产品可重新优化功能、存储器、性能和引脚数量,以最小的硬件变化来满足个性化的应用需求。 截至2010年7月1日,市面流通的型号有: 基本型:STM32F101R6 STM32F101C8 STM32F101R8 STM32F101V8 STM32F101RB STM32F101VB 增强型:STM32F103C8 STM32F103R8 STM32F103V8 STM32F103RBSTM32F103VB STM32F103VE STM32F103ZE STM32型号的说明:以STM32F103RBT6这个型号的芯片为例,该型号的组成为7个部分,其命名规则如下: (1)STM32:STM32代表ARM Cortex-M3内核的32位微控制器。 (2)F:F代表芯片子系列。 (3)103:103代表增强型系列。 (4)R:R这一项代表引脚数,其中T代表36脚,C代表48脚,R代表64脚,V代表100脚,Z代表144脚。 (5)B:B这一项代表内嵌Flash容量,其中6代表32K字节Flash,8代表64K字节Flash,B代表128K字节Flash,C代表256K字节Flash,D代表384K字节Flash,E代表512K字节Flash。 (6)T:T这一项代表封装,其中H代表BGA封装,T代表LQFP封装,U代表VFQFPN 封装。 (7)6:6这一项代表工作温度范围,其中6代表-40——85℃,7代表-40——105℃。 二 从上面的料号可以看出以下信息: ST品牌ARM Cortex-Mx系列内核32位超值型MCU,LQFP -48封装闪存容量32KB 温度范围-40℃-85℃; 1.产品系列: STM32代表ST品牌Cortex-Mx系列内核(ARM)的32位MCU; 2.产品类型: F:通用快闪(Flash Memory); L:低电压(1.65~3.6V);F类型中F0xx和F1xx系列为2.0~3.6V; F2xx和F4xx系列为

学习笔记之STM32F103

学习笔记之STM32F103 目录 1. RCC_APB2Periph_AFIO的使用 (2) 2. GPIO设置为输出时必须设置GPIO_SPEED (2) 3. TIM_GetITStatus与TIM_GetITStatus的区别? (2) 4. 上拉输入、下拉输入、浮空输入、模拟输入的区别 (3)

1.RCC_APB2Periph_AFIO的使用 需要用到外设的重映射功能和中断功能时才需要开启AFIO时钟,使用默认的复用功能时不需要开始AFIO时钟。 举例:重映射USART2 USART2的TX/RX在PA.2/3 PA.2已经被Timer2的channel3使用需要把USART2的TX/RX重映射到PD.5/6库函数的调用。 (1)使能被重新映射到的I/O端口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); (2)使能被重新映射的外设时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); (3)使能AFIO功能的时钟(勿忘!) RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); (4)进行重映射 GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE); 2.GPIO设置为输出时必须设置GPIO_SPEED. 输入模式可以不用配置速度,但是输出模式必须确定最大输出频率。 当STM32的GPIO端口设置为输出模式时,有三种速度可以选择:2MHz、10MHz和50MHz,这个速度是指I/O口驱动电路的速度,是用来选择不同的输出驱动模块,达到最佳的噪声控制和降低功耗的目的。 高频的驱动电路,噪声也高,当你不需要高的输出频率时,请选用低频驱动电路,这样非常有利于提高系统的EMI性能。 注意:GPIO的引脚速度是指I/O口驱动电路的响应速度而不是输出信号的速度,输出信号的速度与你的程序有关。 3.TIM_GetITStatus与TIM_GetITStatus的区别? 函数(TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET) 和(TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) 这俩个中断的具体区别 (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET) 这个一般用于定时器3的通道3,捕获输入超时中断,比如做BLDC,PMSM电机控制会经常用到;

最全的STM32八种IO口模式讲解(已经标注,新手必备)

以及上拉输入、下拉输入、浮空输入、模拟输入的区别 最近在看数据手册的时候,发现在Cortex-M3里,对于GPIO的配置种类有8种之多: (1)GPIO_Mode_AIN 模拟输入 (2)GPIO_Mode_IN_FLOATING 浮空输入 (3)GPIO_Mode_IPD 下拉输入 (4)GPIO_Mode_IPU 上拉输入 (5)GPIO_Mode_Out_OD 开漏输出 (6)GPIO_Mode_Out_PP 推挽输出 (7)GPIO_Mode_AF_OD 复用开漏输出 (8)GPIO_Mode_AF_PP 复用推挽输出 对于刚入门的新手,我想这几个概念是必须得搞清楚的,平时接触的最多的也就是推挽输出、开漏输出、上拉输入这三种,但一直未曾对这些做过归纳。因此,在这里做一个总结: 推挽输出:可以输出高,低电平,连接数字器件; 推挽结构一般是指两个三极管分别受两互补信号的控制,总是在一个三极管导通的时候另一个截止。高低电平由IC的电源低定。 推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。 详细理解: 如图所示,推挽放大器的输出级有两个“臂”(两组放大元件),一个“臂”的电流增加时,另一个“臂”的电流则减小,二者的状态轮流转换。对负载而言,好像是一个“臂”在推,一个“臂”在拉,共同完成电流输出任务。当输出高电平时,也就是下级负载门输入高电平时,输出端的电流将是下级门从本级电源经VT3拉出。这样一来,输出高低电平时,VT3 一路和VT5 一路将交替工作,从而减低了功耗,提高了每个管的承受能力。又由于不论走哪一路,管子导通电阻都很小,使RC常数很小,转变速度很快。因此,推拉式输出级既提高电路的负载能力,又提高开关速度。 开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内). 开漏形式的电路有以下几个特点: 1. 利用外部电路的驱动能力,减少IC内部的驱动。当IC内部MOSFET导通时,驱动电流是从外部的VCC流经R pull-up ,MOSFET到GND。IC内部仅需很下的栅极驱动电流。

相关主题
相关文档
最新文档