STM32堆栈整理

STM32堆栈整理
STM32堆栈整理

STM32内存编程

在startup_stm32f10x_md.s文件中,它的前面几行就有以上定义,;

栈=1K

Stack_Size EQU 0x00000400

;堆=512B

Heap_Size EQU 0x00000200

Stack_Size不影响Hex,更不影响Hex怎么运行的,只是在Debug调试时会提示错。栈溢出也有是超过了国界进行活动,只要老外没有意见,你可以接着玩,有老外不让你玩,你就的得死,或是大家都死(互相撕杀),有的人写单片机代码在函数里定义一个大数组int buf[8192],栈要是小于8192是会死的很惨。

Heap_Size可为0,即不使用动态分配。Heap_Size的大小与malloc所分配的内存有关,当连续分配而又不释放,会导致满堆或内存泄露。

本文源起的诉求,即在object过多的情况下进行解析,程序需要N多次的动态内存分配,而Heap_Size太小,导致无法分配内存。通过修改Heap_Size的大小解决了诉求。

STM32的内存分配规律

从0X20000000开始依次为:静态存储区+堆区(可有可无)+栈区

所有的全局变量,包括静态变量之类的,全部存储在静态存储区。紧跟静态存储区之后的,是堆区(如没用到malloc,则没有该区),之后是栈区。

附录

STM32内存地址说明

在MDK编译过程中,内存的划分如下:

Code是存储程序代码的。

RO-data是存储const常量和指令。

RW-data是存储初始化值不为0的全局变量。

ZI-data是存储未初始化的全局变量或初始化值为0的全局变量。

Flash=Code + RO Data + RW Data;

RAM= RW-data+ZI-data;

此内存划分暂未包括堆栈,堆栈会在程序运行时,占用RAM。

堆栈的内存占用就是MDK里,RAM分配给RW-data+ZI-data之后的地址开始分配的。---------------------

STM32的堆栈大小在官方文件已经定义好了,分别是:

Heap_Size EQU 0x00000200 一共512字节

Stack_Size EQU 0x00000400 一共1K字节

/***********************************************************************************/

但是STM32在keil环境下每次编译后的堆栈起始地址并不是固定的(就算事先已经定义好了堆栈的大小),因为栈的起始地址是由用户程序中事先定义好的变量数目决定的(实测是如此)。但欣慰的是,一旦这次编译之后,堆栈的首地址就不会再发生改变了,换言之,就是在烧完程序之后,堆栈的地址就永远不变了。

/***********************************************************************************/

要关心STM32的堆栈关系,首先无法避免的就是下面这两幅图片了:

图一:MDK环境下,STM32 Bulid Output窗口部分截图

图二:MDK环境下,STM32的.map文件中关于堆栈地址的说明(绿色高亮部位)

/***********************************************************************************/

STM32的内部sram的首地址为0x20000000,图二中的__i nitial_sp既为栈的高地址(也就是栈的首地址)(STM32的堆栈地址在MDK下的配置默认是连续的,栈的地址高于堆的地址,栈的生长方向为从高地址向低地址生长,栈的地址为从低地址向高地址生长,最后两者生长到了一起,也就是“头碰头”)图二中的HEAP既为堆的低地址,STACK既为最后头碰头的地址(注意并不是栈的起始地址而是结束地址,因为栈相对于堆是逆向生长的)

/***********************************************************************************/

那么问题来了,__initial_sp的值是怎么来的呢?这就要看图一了。

首先抛出结论:__initial_sp = 0x20000000+RW+ZI

RW:Read/Write 可读可写的数据段。就是那些在任务初始化时就已经被赋值了的变量,MDK一般将这种类型的数据保存在STM32的SRAM中。(“全局变量”存在“普通意义上的”SRAM 中)(“局部变量”存储在“栈”中)(“局部的static变量”在存储上等价于全局变量)ZI:Zero Initial 初始化为0的变量,也就是直接初始化并没有赋值的变量

可以这么认为:在STM32的片内SRAM中,__initial_sp-0x20000000为用户已经使用了的SRAM空间,从高地址到低地址依次为“栈Stack”“堆Heap”“全局变量”

/***********************************************************************************/

至此,图二中绿色高亮部分的STACK和HEAP的数值也就不难理解了

STACK = __initial_sp - 0x400(栈的大小)

HEAP = STACK - 0x200(堆的大小)

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

STM32学习笔记

输入模式初始化GPIOE2,3,4 ①IO口初始化:GPIO_InitTypeDef GPIO_InitStructure; ②使能PORTA,PORTE时钟: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE); ③PE.2.3.4端口配置:GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; ④设置成(上拉)输入:GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; ⑤GPIO_Init(GPIOE, &GPIO_InitStructure); 输出模式初始化 ①IO口初始化:GPIO_InitTypeDef GPIO_InitStructure; ②使能PB,PE端口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); ③3LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; ④设置(推挽)输出模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; ⑤设置IO口速度为50MHz GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; ⑥说明初始化哪个端口GPIO_Init(GPIOB, &GPIO_InitStructure); 在LED灯试验中初始为高电平灭GPIO_SetBits(GPIOB,GPIO_Pin_5); 再初始化相同发输出模式时③④⑤可省略例如(经实验初始化恰好为不同IO口相同IO序号③可省略,应该不规范吧) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 端口配置, 推挽输出GPIO_Init(GPIOE, &GPIO_InitStructure); //推挽输出,IO口速度为50MHz GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高 1,头文件可以定义所用的函数列表,方便查阅你可以调用的函数; 2,头文件可以定义很多宏定义,就是一些全局静态变量的定义,在这样的情况下,只要修改头文件的内容,程序就可以做相应的修改,不用亲自跑到繁琐的代码内去搜索。 3,头文件只是声明,不占内存空间,要知道其执行过程,要看你头文件所申明的函数是在哪个.c文件里定义的,才知道。 4,他并不是C自带的,可以不用。 5,调用了头文件,就等于赋予了调用某些函数的权限,如果你要算一个数的N次方,就要调用Pow()函数,而这个函数是定义在math.c里面的,要用这个函数,就必需调用math.h 这个头文件。

(完整版)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学习笔记_STM32F103ZET6

STM32F103 系列芯片的系统架构: 系统结构: 在每一次复位以后,所有除SRAM 和FLITF 以外的外设都被关闭,在使用一个外设之前,必须设置寄存器RCC_AHBENR 来打开该外设的时钟。

GPIO 输入输出,外部中断,定时器,串口。理解了这四个外设,基本就入门了一款MCU。 时钟控制RCC: -4~16M 的外部高速晶振 -内部8MHz 的高速RC 振荡器 -内部40KHz低速RC 振荡器,看门狗时钟 -内部锁相环(PLL,倍频),一般系统时钟都是外部或者内部高速时钟经过PLL 倍频后得到 - 外部低速32.768K 的晶振,主要做RTC 时钟源

ARM存储器映像: 数据字节以小端格式存放在存储器中。一个字里的最低地址字节被认为是该字的最低有效字节,而最高地址字节是最高有效字节。

存储器映像与寄存器映射: ARM 存储器映像 4GB 0X0000 00000X1FFF FFFF 0X2000 00000X3FFF FFFF 0X4000 00000X5FFF FFFF

寄存器说明: 寄存器名称 相对外设基地址的偏移值 编号 位表 读写权限 寄存器位 功能说明 使用C语言封装寄存器: 1、总线和外设基地址封装利用地址偏移 (1)定义外设基地址(Block2 首地址) (2)定义APB2总线基地址(相对外设基地址偏移固定) (3)定义GPIOX外设基地址(相对APB2总线基地址偏移固定)(4)定义GPIOX寄存器地址(相对GPIOX外设基地址偏移固定)(5)使用 C 语言指针操作寄存器进行读/写 //定义外设基地址 #define PERIPH_BASE ((unsigned int)0x40000000) 1) //定义APB2 总线基地址 #define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) 2) //定义GPIOC 外设基地址 #define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) 3) //定义寄存器基地址这里以GPIOC 为例 #define GPIOC_CRL *(unsigned int*)(GPIOC_BASE+0x00) 4) #define GPIOC_CRH *(unsigned int*)(GPIOC_BASE+0x04) #define GPIOC_IDR *(unsigned int*)(GPIOC_BASE+0x08) #define GPIOC_ODR *(unsigned int*)(GPIOC_BASE+0x0C) #define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE+0x10) #define GPIOC_BRR *(unsigned int*)(GPIOC_BASE+0x14) #define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE+0x18) //控制GPIOC 第0 管脚输出一个低电平5) GPIOC_BSRR = (0x01<<(16+0)); //控制GPIOC 第0 管脚输出一个高电平 GPIOC_BSRR = (0x01<<0);

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学习 c语言笔记

这是前段时间做彩屏显示时候遇到的难题, *(__IO uint16_t *) (Bank1_LCD_C)这个就是将后面的数据转换为地址,然后对地址单元存放数据。可如下等效: __IO uint16_t *addr; addr = (__IO uint16_t *) Bank1_LCD_C; #ifdef和#elif连用,语法和if。。。else if语句一样 推挽输出增加驱动,可以驱动LED起来 static int count=0 count++ 这个语句中,count仅仅被初始化一次 以后加加一次期中的值就不会变化了 SysTick_CTRL(控制和状态寄存器) SysTick_LOAD(重装载寄存器) SysTick_VAL(当前值寄存器) SysTick_CALIB(校准值寄存器)

TFT经验:弄多大的相片,必须先把那个相片的尺寸改掉,再去取模,才可以,要不会有重影的嘿嘿嘿嘿 VBAT 是电池供电的引脚 VBAT和ADD同时都掉电时才能让备份区复位。 volatile一个变量的存储单元可以在定义该变量的程序之外的某处被引用。 volatile主要是程序员要告诉编译器不要对其定义的这个变量进行优化,防止其不能被引用,不能被改变。 VDDA>2.4V ADC才能工作 VDDA>2.7V USB才能工作 VDD(1.8-3.6v) VBAT=1.8-3.6v VSS VSSA VREF必须接到地线 没有外部电源供电时必须VBAT接上VDD 使用PLL时,VDDA必须供电

printf("abs(x)=%d\n",x<0?(-1)*x:x) 条件编译是问号前边为真则取冒号前边的值,为假的,则取后边的值。 所以说上边这条打印的语句是打印x的绝对值。 //stm32f10x_nvic.c stm32f10x_lib.c stm32f10x_gpio.c stm32f10x_flash.c stm32f10x_rcc.c TIM6 TIM7基本定时器 (只有这两个定时器不能产生PWM) TIM1 TIM8高级控制定时器 TIM2 TIM3 TIM4 TIM5为通用定时器 其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。而通用定时器也能同时产生多达4路的PWM输出,这样,STM32最多可以同时产生30路PWM输出! 修改和自己写代码时候

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固件库V3.0 使用芯片型号:STM32F103 开发环境:MDK ******************************** 第一课时钟频率 STM32F103内部8M的内部震荡,经过倍频后最高可以达到72M。目前TI的M3系列芯片最高频率可以达到80M。 在stm32固件库3.0中对时钟频率的选择进行了大大的简化,原先的一大堆操作都在后台进行。系统给出的函数为SystemInit()。但在调用前还需要进行一些宏定义的设置,具体的设置在system_stm32f10x.c文件中。 文件开头就有一个这样的定义: //#define SYSCLK_FREQ_HSE HSE_Value //#define SYSCLK_FREQ_20MHz 20000000 //#define SYSCLK_FREQ_36MHz 36000000 //#define SYSCLK_FREQ_48MHz 48000000 //#define SYSCLK_FREQ_56MHz 56000000 #define SYSCLK_FREQ_72MHz 72000000 ST 官方推荐的外接晶振是8M,所以库函数的设置都是假定你的硬件已经接了8M 晶振来运算的.以上东西就是默认晶振8M 的时候,推荐的CPU 频率选择.在这里选择了: #define SYSCLK_FREQ_72MHz 72000000 也就是103系列能跑到的最大值72M 然后这个C文件继续往下看 #elif defined SYSCLK_FREQ_72MHz const uint32_t SystemFrequency = SYSCLK_FREQ_72MHz; const uint32_t SystemFrequency_SysClk = SYSCLK_FREQ_72MHz; const uint32_t SystemFrequency_AHBClk = SYSCLK_FREQ_72MHz; const uint32_t SystemFrequency_APB1Clk = (SYSCLK_FREQ_72MHz/2); const uint32_t SystemFrequency_APB2Clk = SYSCLK_FREQ_72MHz; 这就是在定义了CPU跑72M的时候,各个系统的速度了.他们分别是:硬件频率,系统时 钟,AHB总线频率,APB1总线频率,APB2总线频率.再往下看,看到这个了: #elif defined SYSCLK_FREQ_72MHz static void SetSysClockTo72(void); 这就是定义72M 的时候,设置时钟的函数.这个函数被SetSysClock ()函数调用,而SetSysClock ()函数则是被SystemInit()函数调用.最后SystemInit()函数,就是被你调用的了

献给新手:解析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,

STM32学习笔记(5)通用定时器PWM输出

STM32学习笔记(5):通用定时器PWM输出 2011年3月30日TIMER输出PWM 1.TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。一般用来控制步进电机的速度等等。 STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出。 1.1PWM输出模式 STM32的PWM输出有两种模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。模式1和模式2的区别如下: 110:PWM模式1-在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。 111:PWM模式2-在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为有效电平,否则为无效电平。 由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。 而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式,关于3种模式的具体资料,可以查看《STM32参考手册》的“14.3.9 PWM模式”一节,在此就不详细赘述了。 1.2PWM输出管脚 PWM的输出管脚是确定好的,具体的引脚功能可以查看《STM32参考手册》的“8.3.7 定时器复用功能重映射”一节。在此需要强调的是,不同的TIMx有分配不同的引脚,但是考虑到管脚复用功能,STM32提出了一个重映像的概念,就是说通过设置某一些相关的寄存器,来使得在其他非原始指定的管脚上也能输出PWM。但是这些重映像的管脚也是由参考手册给出的。比如

STM32学习笔记

1、GPIO函数: 输出: HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);//此例以PA12口为例 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET); //此例以PA12口为例 HAL_GPIO_ TogglePin(GPIOA,GPIO_PIN_12); //此例以PA12口为例 2、串口函数: 1、串口发送/接收函数 HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制 HAL_UART_Receive();串口轮询模式接收,使用超时管理机制 HAL_UART_Transmit_IT();串口中断模式发送 HAL_UART_Receive_IT();串口中断模式接收 HAL_UART_Transmit_DMA();串口DMA模式发送 HAL_UART_Transmit_DMA();串口DMA模式接收 2、串口中断函数 HAL_UART_TxHalfCpltCallback();一半数据发送完成时调用 HAL_UART_TxCpltCallback();数据完全发送完成后调用 HAL_UART_RxHalfCpltCallback();一半数据接收完成时调用 HAL_UART_RxCpltCallback();数据完全接受完成后调用 HAL_UART_ErrorCallback();传输出现错误时调用 例程:串口接收中断 uint8_t aTxStartMessages[] = "\r\n******UART commucition using IT******\r\nPlease enter 10 characters:\r\n"; uint8_t aRxBuffer[20]; 2、在main函数中添加两个语句通过串口中断发送aTxStartMessage数组的数据和接收数据10个字符,保存在数组aRxBuffer中 HAL_UART_Transmit_IT(&huart1 ,(uint8_t*)aTxStartMessages,sizeof(aTxStartMessages)); //sizeof()可读取目标长度 HAL_UART_Receive_IT(&huart1,(uint8_t*)aRxBuffer,10); 3、在main.c文件后面添加中断接收完成函数,将接收到的数据又通过串口发送回去。 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { UNUSED(huart); HAL_UART_Transmit(&huart1,(uint8_t*)aRxBuffer,10,0xFFFF);//(uint8_t*)aRxBuffer为字符串地址,10为字符串长度,0xFFFF为超时时可以在中间加任何可执行代码。 }

【设计教程大集合】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驱动舵机进行角度调整。

相关文档
最新文档