STM32学习笔记(初学者快速入门
原来那个 3.1.0 版的 stm32f10x.h 被人为地修改了一下,所以,不在 define 中定 义也不要紧,而新升级的 3.1.2 则不行了。 至此,简单的升级搞定。 本文见于好多地方,但查询后未能确定其原始出处及作者,故这里说明是转贴, 但作者和原始出处信息就无法提供了,如果原作者看到请跟贴说明,知情者也请 跟贴说明。 -------------------------------------------------------------------------ARM 中的 RO、RW 和 ZI DATA 一直以来对于 ARM 体系中所描述的 RO,RW 和 ZI 数据存在似是而非的理解, 这段时间对其仔细了解了一番,发现了一些规律,理解了一些以前书本上有的但 是不理解的东西,我想应该有不少人也有和我同样的困惑,因此将我的一些关于 RO,RW 和 ZI 的理解写出来,希望能对大家有所帮助。 要了解 RO,RW 和 ZI 需要首先了解以下知识: ARM 程序的组成 此处所说的“ARM 程序”是指在 ARM 系统中正在执行的程序,而非保存在 ROM
用菜单 Project-->New uVision Porject...建立新的工程,选择目标器件为 STM3 2103VC,这个过程与建立 51 单片机的工程没有什么区别,这里就偷点懒,不 上图了。接下来看一看怎么设置。
点那个品字形,打开对话框
这里就给个图了,相信有一定操作基础的人应该会用。顺便提一下,原来用 VC 或者 IAR 时总觉得它们的一个功能:就是建立一个是 Debug 组和 Release 组, 这个功能挺好的,从这个图可在 Keil 里也是一样可以建的。 将刚才那个文件夹图中 CMSIS 中的文件加入 CMSIS 组,一共 3 个,其中\Sour ce\CMSIS\Core\CM3 有两个 C 语言源程序文件全部加入,另外还有一个在 \Source\CMSIS\Core\CM3\startup\arm 文件夹中,这个文件夹中有 4 个.s 文 件,我们选择其中的 startup_stm32f10x_hd.s 文件。这是根据项目所用 CPU 来 选择的,我们用的 CPU 是 103VC 的,属于高密度的芯片,所以选这个。 至于 LIB 中的文件,就在这儿:\Source\STM32F10x_StdPeriph_Driver\src 啦。 这里有很多个文件,把什么文件加进去呢?怕麻烦的话,把所有文件全部加进去, 这并不会增加编译后的代码量,但会增加很多的编译时间。
,拆包 细细端详,做工精良,尤其那上面的 3.2 吋屏,越看越喜欢。接下来就是一阵折 腾了,装 JLINK 软件,给板子通电,先试试 JLINK 能不能与电脑和板子通信上 了。真顺,一点问题也没有。于是准备将附带的程序一个一个地写进去试一试。 一检查,大部分例子的 HEX 文件并没有给出,这要下一步自己生成,但是几个 大工程的例子都有 HEX 文件,如 MP3,如 UCCGI 测试等,写完以后观察程序 运行的效果。因为之前也做过彩屏的东西,知道那玩艺代码量很大,要流畅地显 示并不容,当时是用 AVR 做的,在 1.8 吋屏上显示一幅画要有一段时间。现在 看起来,用 STM32 做的驱动显示出来的画面还是很快的,不过这里显示的大部 分是自画图,并没有完整地显示一整幅的照片,所以到底快到什么程度还不好说, 看来不久以后这可以作为一个学习点的。 一个晚上过去了,下一篇就是要开始 keil 软件的学习了。
中的 bin 映像(image)文件,这一点清注意区别。 一个 ARM 程序包含 3 部分:RO,RW 和 ZI RO 是程序中的指令和常量 RW 是程序中的已初始化变量 ZI 是程序中的未初始化的变量 由以上 3 点说明可以理解为: RO 就是 readonly, RW 就是 read/write, ZI 就是 zero ARM 映像文件的组成 所谓 ARM 映像文件就是指烧录到 ROM 中的 bin 文件,也称为 image 文件。以 下用 Image 文件来称呼它。 Image 文件包含了 RO 和 RW 数据。 之所以 Image 文件不包含 ZI 数据,是因为 ZI 数据都是 0,没必要包含,只要程 序运行之前将 ZI 数据所在的区域一律清零即可。包含进去反而浪费存储空间。 Q:为什么 Image 中必须包含 RO 和 RW? A:因为 RO 中的指令和常量以及 RW 中初始化过的变量是不能像 ZI 那样“无中 生有”的。 ARM 程序的执行过程 从以上两点可以知道,烧录到 ROM 中的 image 文件与实际运行时的 ARM 程序 之间并不是完全一样的。因此就有必要了解 ARM 程序是如何从 ROM 中的 image 到达实际运行状态的。 实际上,RO 中的指令至少应该有这样的功能: 1. 将 RW 从 ROM 中搬到 RAM 中,因为 RW 是变量,变量不能存在 ROM 中。 2. 将 ZI 所在的 RAM 区域全部清零,因为 ZI 区域并不在 Image 中,所以需要 程序根据编译器给出的 ZI 地址及大小来将相应得 RAM 区域清零。ZI 中也是变 量,同理:变量不能存在 ROM 中 在程序运行的最初阶段,RO 中的指令完成了这两项工作后 C 程序才能正常访问 变量。否则只能运行不含变量的代码。 说了上面的可能还是有些迷糊,RO,RW 和 ZI 到底是什么,下面我将给出几个 例子,最直观的来说明 RO,RW,ZI 在 C 中是什么意思。
我们读武侠小说,总会有一些创出独门功夫的宗师,功夫极高,然后他的弟 子则基本上无法超越他。我在想,这位宗师在创造他自己的独门功夫时,必然会 有很多的次的曲折、弯路、甚至失败,会浪费他的很多时间,而他教给弟子时, 则已去掉了这些曲折和弯路,当然更不会把失败教给弟子,按理说,效率应该更 高,可是没用,弟子大都不如师。为什么呢?也许知识本身并不是最重要的,获 取知识的过程才是最重要的?也许所谓的知识,并不仅仅是一条条的结论,而是 附带着很多说不清道不明的东西?如植物的根,一条主根上必带有大量的小小的 触须? 闲话多了些,就权当前言了。下面准备开始。 一、条件的准备
第一次进入时 Include Paths 文本框中是空白的,点击其后的按钮打开对话框, 增加相应的路径
这样路径就设好了。单击 OK,回到上一界面,然后再单击 OK,退出设置,即 可编译、链接。 下一会要试一试新的 3.12 版的库效果如何了。
STM32 学习笔记(3)
升级库 光盘中所带的例子是 3.10 的,另外还有一个 3.12 的,我 试着将 3.12 的库替代 原来的库,还真有问题,下面就简述问题及解决方法。 (1)将库文件解压 库文件名是:stm32f10x_stdperiph_lib.zip,解压后放在任意一个文件夹中。 (2)由于原作者做了很好的规划,每一个项目中都分成三个文件夹,并且在 s ource 文件夹中又做了 3 个文件夹,其中 APP 文件夹是放自己写的文件的,其 他的两个是从库中复制过来的,因此,想当然地把 3.1.2 版本中相同的两个文件 夹: CMSIS 和 STM32F10x_StdPeriph_Driver 直接复制过来,以为一切 OK,结果 一编译,出来一堆错误。 其中有错误:
我的习惯,第一步是先搭建一个学习的平台。原来学 51,PIC,AVR 时,都 是想方设法自己做些工具,实验板之类,现在人懒了,直接购买成品了。
硬件电路板:火牛板 软件:有 keil 和 iar 可供选择。网上的口水仗不少,我选 keil,理由很简单, 这个我熟。目前要学的知识中,软、硬件我都不熟,所以找一个我有点熟的东西 就很重要。在我相当熟练之前,肯定不会用到 IAR,如果真的有一天不得不用 I AR,相信学起来也很容易,因为这个时候硬件部分我肯定很熟了,再加上有 ke il 的基础,所以应该很容易学会了。 调试工具:JLINK V8。这个不多说了,价格便宜又好用,就是它了。 二、热身 网上选购的,付了款就是等了。拿到包裹,端详良久,起身。。。。沐浴, 更衣,焚香,,, , , 总得先吃晚饭,洗澡,再点个电蚊香什么的吧。
#include "stm32f10x_conf.h" #endif 看来,是这个 USE_STDPERIPH_DRIVER 没有被定义啊,于是,人为地去掉 条件: //#ifdef USE_STDPERIPH_DRIVER
#include "stm32f10x_conf.h" //#endif 再次编译,果然就 OK 了。可是,可是,也不能就这么去掉啊,怎么办呢?万能 的网啊,一搜果然就有了。
STM32 学习笔记(2)
本想着偷点懒的,没想到竞被加了“精”,没办法啦,只能勤快点啦。。。 硬件调通后,就要开始编程了。 编程的方ห้องสมุดไป่ตู้有两种,一种是用 st 提供的库,另一种是从最底层开始编程,网上 关于使用哪种方法编程的讨论很多,据说用库的效率要低一些。但是用库编程非 常方便,所以我还是从库开始啦。库是 ST 提供的,怎么说也不会差到哪里,再 说了,用 32 位 ARM 的话,开发的观念也要随之改变一点了。
Source\App\main.c(7): error: #20: identifier "GPIO_InitTypeDef" is undefin ed .... 还有大量的警告:
Source\STM32F10x_StdPeriph_Driver\src\stm32f10x_flash.c(130): warnin g: #223-D: function "assert_param" declared implicitly 看了看,在 APP 文件夹中还有一些不属于自己的东西: stm32f10x_conf.h,stm32f10x_it.h,stm32f10x_it.c,打开一看,果然是 3.10 版本的,没说的,换。。。。,找到 STM32F10x_StdPeriph_Lib_V3.1.2\Proje
STM32 学习笔记
从 51 开始,单片机玩了很长时间了,有 51,PIC,AVR 等等,早就想跟潮 流玩玩 ARM,但一直没有开始,原因-----不知道玩了 ARM 可以做什么(对我自 己而言)。如果为学习而学习,肯定学不好。然后 cortex-m3 出来了,据说,这 东西可以替代单片机,于是马上开始关注。也在第一时间开始学习,可惜一开始 就有点站错了队,选错了型(仍是对我自己而言)。我希望这种芯片应该是满大 街都是,随便哪里都可以买得到,但我选的第一种显然做不到。为此,大概浪费 了一年多时间吧,现在,回到对我来说是正确的道路上来啦,边学边写点东西。
STM32f103C8T6入门学习记录
设置输出为推挽输出。它有8中工作模式,输出只有两种推挽和开漏输出。其它可以参
考相关手册
GPIO_Init(GPIOB , &GPIO_InitStructure);
这一句就是将前面四句的设置初始化到GPIOB中;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
保存工程名,选择Obj文件夹,文件名为first_project,不用加后缀格式,系统默认。
接下来会弹出让你选择器件的窗口,这里我们选择STmicroelectronics的STM32F103C8
最后会弹出是否复制启动代码的对话框,选择YES;
3
1、在project窗口右键点击Tagert 1选择manage conponents或者 找到倒数第二个品字形图标;
delay();
GPIO_SetBits(GPIOB,GPIO_Pin_6 );//点亮PB.6
delay();
GPIO_ResetBits(GPIOB,GPIO_Pin_6 );//熄灭PB.6
delay();
}
}
2
GPIO_InitTypeDef GPIO_InitStructure;
定义一个结构变量GPIO_InitStructure,结构体类型为GPIO_InitTypeDef,相当于int
STM32学习笔记
STM32学习笔记1009132.阅读gpio:I/O设置函数我的理解——所有输入输出管脚模式设置,可以是上下拉、浮空、开漏、模拟、推挽模式,频率特性为2M,10M,50M。
也可以向该管脚直接写入数据和读取数据。
基础应用1,gpio初始化函数。
所有程序必须。
用法:void GPIO_Configuration(void){GPIO_InitTypeDef GPIO_InitStructure; //GPIO状态恢复默认参数GPIO_InitStructure.GPIO_Pin = GPIO_Pin_标号 | GPIO_Pin_标号 ;//管脚位置定义,标号可以是NONE、ALL、0至15。
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//输出速度2MHzGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入模式GPIO_Init(GPIOC, &GPIO_InitStructure); //C组GPIO初始化//注:以上四行代码为一组,每组GPIO属性必须相同,默认的GPIO参数为:ALL,2MHz,FLATING。
如果其中任意一行与前一组相应设置相同,那么那一行可以省略,由此推论如果前面已经将此行参数设定为默认参数(包括使用GPIO_InitTypeDef GPIO_InitStructure代码),本组应用也是默认参数的话,那么也可以省略。
以下重复这个过程直到所有应用的管脚全部被定义完毕。
……}基础应用2,向管脚写入0或1用法:GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)0x01);//写入11,介绍几个特殊的文件stm32f10x_type.h 所有其他文件使用的通用数据类型和枚举stm32f10x_map.h 外设存储器映像和寄存器数据结构唯一的一个用户需要包括在自己应用中的文件stm32f10x_lib.h 主头文件,包含了其他头文件stm32f10x_lib.c Debug模式下初始化所有外设的指针stm32f10x_it.h 该头文件包含了所有的中断处理程序的原形cortexm3_macro.h 文件cortexm3_macro.s对应的头文件cortexm3_macro.s Cortex-M3内核特殊指令的指令包装stm32f10x_ppp.h 外设PPP的头文件。
stm32自学笔记共20页
•
LED0=1;
•
LED1=0;
•
delay_ms(300);
•
}
•}
第二章 跑马灯实验
• Led.c函数
• void LED_Init(void)
•{
•
RCC->APB2ENR|=1<<2; //使能PORTA时钟
•
GPIOA->CRH|=0XFFFFFFFF3;//PA8 推挽输出
•
GPIOA->ODR|=1<<8; //PA8 输出高
• JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD,在原理图上可以看 到PA13和PA15为键盘和JTAG与SWD所共用,而这两种方针接口,他们 和普通的IO口公用,当想使用普通IO口时,必须先把他们关闭。在这 个函数里面设置参数,如果为二进制数00,则代表全部使能,如果是 二进制数01,则是能SWD,如果是10,则表示全部关闭。JTAG是一种 国际标准测试协议,主要用于芯片内部的测试。
• }要想实现一个点亮led小灯的功能,最少只需对3个寄存器进行设 置,第一步是设置外设时钟使能先把PORTA时钟使能,接下来把IO
口设置为输出,在接下来设置输出为高电平还是低电平,这里使用 推挽输出(3.3v),推挽输出主要是增强驱动能力,为外部提供大电 流。
第二章 跑马灯实验
• #ifndef __LED_H • #define __LED_H • #include "sys.h" • #define LED0 PAout(8)// PA8 • #define LED1 PDout(2)// PD2 • void LED_Init(void);//初始化
STM32学习笔记
STM32学习一、初识库(略)二、(略)三、(略)四、(略)五、(略)六、系统定时器1、注意外部函数的声明;2、与六相同,也使用了中断;3、Volatile是不让编译优化的意思;4、Extern即定义外部函数,static是静态变量的意思。
七、串口通信1、当使用printf时,记得要在“bsp_usart1.h”文件中把“stdio.h”包含进来2、NVIC是中断优先级配置函数3、注意使用微库右图中的Use Micro LIB要打勾4、八、DMA1、DMA含义:data memory access,直接内存访问,此时不经过CPU2、这种方式节省CPU资源,好像可以同时做两件事(ADC、SPI、I2C等),不同的外设通道不同,可参看数据手册,串口1是通道4九、ADC1、ADC为12位,时钟为14MHz,最小采样时间为1微秒2、要提高采集频率,可采用多通道交叉采样。
十、FSMC液晶显示1、FSMC含义:灵活的静态存储器控制器2、注意配置IO引脚的第二功能时应注意配置成“AF-pp”即复用推挽模式;3、注意片选BANK1-44、野火自带的屏的高度840,宽320十一、I2C总线1、I2C一般都是开漏输出2、一般向I2C写数据时,如不加限制,是从头开始,写到本页结束如果再写又回到本页开头,会覆盖原来内容,因此,为避免这种情况,加地址。
十二、SPI总线1、SPI总线的读写速度(特别是读速度)要比对SD卡的快,而且成本低;2、SPI总线模块可存汉字字库、图片等,一些掉电保护信息也可存于此;3、在“bsp_spi_flash.c”中,语句“RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA| RCC_APB2Periph_GPIOD, ENABLE);”中的D端口时钟不需要开,即“RCC_APB2Periph_GPIOD”是不必要的,可以删去;4、“sizeof()”是C语言的保留字,其用法在此有描述。
STM32学习笔记(初学者快速入门)a
#include "stm32f10x_conf.h" //#endif 再次编译,果然就 OK 了。可是,可是,也不能就这么去掉啊,怎么办呢?万能 的网啊,一搜果然就有了。
说说我怎么学的吧。 找个例子,如 GPIO,可以看到其结构如下: SOURCE(文件夹)
- APP(文件夹) -CMSIS(文件夹) -STM32F10x_StdPeriph_Driver(文件夹) Lis(文件夹) OBJ(文件夹) 其中 SOURCE 中保存的是应用程序,其中又有好多子文件夹,而 CMSIS 文件 夹中和 STM32F10x_StdPeriph_Driver 文件夹中是 ST 提供的库,这样,如果要 做新的工程只要将这个文件夹整个复制过来就行,其中 APP 中保存自己的代码。 因为我们用 51 单片机时一般比较简单,有时就一个文件,所以通常不设置专 门的输出文件夹,而这里做开发,通常会有很多个文件加入一个工程中,编译过 程中会产生很多中间文件,因此设置专门的文件夹 LIS 和 OBJ 用来保存中间文 件。 下面就将设置简单描述一下。 将复到过来的 GPIO 根目录下的所有文件删除,因为我们要学着自己建立工程。
到设置 C/C++页面 在那个 define 中加入“USE_STDPERIPH_DRIVER,STM32F10X_HD” 当然,去掉条件编译前面的注释,回到原样。 再次编译,一切顺利。可是,原来的工程例子也没有加这个啊,怎么回事呢?再 次打开原来的例子,找到 stm32f10x.h,可以看到有这么一行:
详细的STM32单片机学习笔记
详细的STM32单片机学习笔记STM32单片机学习笔记1、AHB系统总线分为APB1(36MHz)和APB2(72MHz),其中21,意思是APB2接高速设备2、Stm32f10x.h相当于reg52.h(里面有基本的位操作定义),另一个为stm32f10x_conf.h 专门控制外围器件的配置,也就是开关头文件的作用3、HSE Osc(High Speed External Oscillator)高速外部晶振,一般为8MHz,HSI RC(High Speed InternalRC)高速内部RC,8MHz4、LSE Osc(Low Speed External Oscillator)低速外部晶振,一般为32.768KHz,LSI RC (Low Speed InternalRC)低速内部晶振,大概为40KHz左右,提供看门狗时钟和自动唤醒单元时钟源5、SYSCLK时钟源有三个来源:HSI RC、HSE OSC、PLL6、MCO[2:0]可以提供4源不同的时钟同步信号,PA87、GPIO口貌似有两个反向串联的二极管用作钳位二极管。
8、总线矩阵采用轮换算法对系统总线和DMA进行仲裁9、ICode总线,DCode总线、系统总线、DMA总线、总线矩阵、AHB/APB桥10、在使用一个外设之前,必须设置寄存器RCC_AHBENR来打开该外设的时钟11、数据字节以小端存储形式保存在存储器中12、内存映射区分为8个大块,每个块为512MB13、FLASH的一页为1K(小容量和中容量),大容量是2K。
14、系统存储区(SystemMemory)为ST公司出厂配置锁死,用户无法编辑,用于对FLASH 区域进行重新编程。
所以我们烧写程序务必选择BOOT1 = 0,这样通过内嵌的自举程序对。
stm32学习笔记(狼牙整理)
系统时钟 SYSCLK 最大频率为 72MHz,它是供 STM32 中绝大部分部件工作的时钟源。 系统时钟可由 PLL、HSI 或者 HSE 提供输出,并且它通过 AHB 分频器分频后送给各模 块使用,AHB 分频器可选择 1、2、4、8、16、64、128、256、512 分频。其中 AH B 分频器输出的时钟送给 5 大模块使用:①、送给 AHB 总线、内核、内存和 DMA 使用 的 HCLK 时钟。 ②、分频后送给 STM32 芯片的系统定时器时钟(Systick=Sysclk/8=9Mhz) ③、直接送给 Cortex 的自由运行时钟(free running clock)FCLK。【ARMJISHU 注:FCL K 为处理器的自由振荡的处理器时钟,用来采样中断和为调试模块计时。在处理器休眠时, 通过 FCLK 保证可以采样到中断和跟踪休眠事件。 Cortex-M3 内核的“自由运行时钟(fre e running clock)”FCLK。“自由”表现在它不来自系统时钟 HCLK,因此在系统时钟停 止时 FCLK 也继续运行。FCLK 和 HCLK 互相同步。FCLK 是一个自由振荡的 HCLK。FCL K 和 HCLK 应该互相平衡,保证进入 Cortex-M3 时的延迟相同。】④、送给 APB1 分频 器。APB1 分频器可选择 1、2、4、8、16 分频,其输出一路供 APB1 外设使用(PCLK1, 最大频率 36MHz),另一路送给定时器(Timer)2、3、4 倍频器使用。该倍频器可选择 1 或 者 2 倍频,时钟输出供定时器 2、3、4 使用。 ⑤、送给 APB2 分频器。APB2 分频器可选择 1、2、4、8、16 分频, 其输出一路供 APB 2 外设使用(PCLK2,最大频率 72MHz),另一路送给定时器(Timer)1 倍频器使用。该倍频
STM32学习笔记(初学者快速入门
STM32学习笔记(初学者快速入门STM32 学习笔记从51 开始单片机玩了很长时间了有51PICAVR 等等早就想跟潮流玩玩ARM 但一直没有开始原因-----不知道玩了ARM 可以做什么对我自己而言如果为学习而学习肯定学不好然后cortex-m3 出来了据说这东西可以替代单片机于是马上开始关注也在第一时间开始学习可惜一开始就有点站错了队选错了型仍是对我自己而言我希望这种芯片应该是满大街都是随便哪里都可以买得到但我选的第一种显然做不到为此大概浪费了一年多时间吧现在回到对我来说是正确的道路上来啦边学边写点东西这里写的是我的学习的过程显然很多时候会是不全面的不系统的感悟式的甚至有时会是错误的有些做法会是不专业的那么为什么我还要写呢这是一个有趣的问题它甚至涉及到博客为什么要存在的问题显然博客里面的写的东西其正确性权威性大多没法和书比可为什么博客会存在呢理由很多我非专家只说我的感慨我们读武侠小说总会有一些创出独门功夫的宗师功夫极高然后他的弟子则基本上无法超越他我在想这位宗师在创造他自己的独门功夫时必然会有很多的次的曲折弯路甚至失败会浪费他的很多时间而他教给弟子时则已去掉了这些曲折和弯路当然更不会把失败教给弟子按理说效率应该更高可是没用弟子大都不如师为什么呢也许知识本身并不是最重要的获取知识的过程才是最重要的也许所谓的知识并不仅仅是一条条的结论而是附带着很多说不清道不明的东西如植物的根一条主根上必带有大量的小小的触须闲话多了些就权当前言了下面准备开始一条件的准备我的习惯第一步是先搭建一个学习的平台原来学51PICAVR 时都是想方设法自己做些工具实验板之类现在人懒了直接购买成品了硬件电路板火牛板软件有keil 和iar 可供选择网上的口水仗不少我选keil理由很简单这个我熟目前要学的知识中软硬件我都不熟所以找一个我有点熟的东西就很重要在我相当熟练之前肯定不会用到IAR如果真的有一天不得不用IAR 相信学起来也很容易因为这个时候硬件部分我肯定很熟了再加上有keil 的基础所以应该很容易学会了调试工具JLINK V8 这个不多说了价格便宜又好用就是它了二热身网上选购的付了款就是等了拿到包裹端详良久起身沐浴更衣焚香总得先吃晚饭洗澡再点个电蚊香什么的吧拆包细细端详做工精良尤其那上面的32 吋屏越看越喜欢接下来就是一阵折腾了装JLINK 软件给板子通电先试试JLINK 能不能与电脑和板子通信上了真顺一点问题也没有于是准备将附带的程序一个一个地写进去试一试一检查大部分例子的HEX 文件并没有给出这要下一步自己生成但是几个大工程的例子都有HEX 文件如MP3如UCCGI 测试等写完以后观察程序运行的效果因为之前也做过彩屏的东西知道那玩艺代码量很大要流畅地显示并不容当时是用AVR 做的在18 吋屏上显示一幅画要有一段时间现在看起来用STM32 做的驱动显示出来的画面还是很快的不过这里显示的大部分是自画图并没有完整地显示一整幅的照片所以到底快到什么程度还不好说看来不久以后这可以作为一个学习点的一个晚上过去了下一篇就是要开始keil 软件的学习了STM32 学习笔记2本想着偷点懒的没想到竞被加了精没办法啦只能勤快点啦硬件调通后就要开始编程了编程的方法有两种一种是用st 提供的库另一种是从最底层开始编程网上关于使用哪种方法编程的讨论很多据说用库的效率要低一些但是用库编程非常方便所以我还是从库开始啦库是ST 提供的怎么说也不会差到哪里再说了用32 位ARM 的话开发的观念也要随之改变一点了说说我怎么学的吧找个例子如GPIO可以看到其结构如下SOURCE 文件夹- APP 文件夹-CMSIS 文件夹-STM32F10x_StdPeriph_Driver 文件夹Lis 文件夹OBJ 文件夹其中SOURCE 中保存的是应用程序其中又有好多子文件夹而CMSIS 文件夹中和STM32F10x_StdPeriph_Driver 文件夹中是ST 提供的库这样如果要做新的工程只要将这个文件夹整个复制过来就行其中APP 中保存自己的代码因为我们用51 单片机时一般比较简单有时就一个文件所以通常不设置专门的输出文件夹而这里做开发通常会有很多个文件加入一个工程中编译过程中会产生很多中间文件因此设置专门的文件夹LIS 和OBJ 用来保存中间文件下面就将设置简单描述一下将复到过来的GPIO 根目录下的所有文件删除因为我们要学着自己建立工程用菜单Project-- New uVision Porject建立新的工程选择目标器件为STM32103VC这个过程与建立51 单片机的工程没有什么区别这里就偷点懒不上图了接下来看一看怎么设置点那个品字形打开对话框这里就给个图了相信有一定操作基础的人应该会用顺便提一下原来用VC或者IAR 时总觉得它们的一个功能就是建立一个是Debug 组和Release 组这个功能挺好的从这个图可在Keil 里也是一样可以建的将刚才那个文件夹图中CMSIS 中的文件加入CMSIS 组一共3 个其中\Source\CMSIS\Core\CM3 有两个C 语言源程序文件全部加入另外还有一个在\Source\CMSIS\Core\CM3\startup\arm 文件夹中这个文件夹中有4 个s 文件我们选择其中的startup_stm32f10x_hds 文件这是根据项目所用CPU 来选择的我们用的CPU 是103VC 的属于高密度的芯片所以选这个至于LIB 中的文件就在这儿\Source\STM32F10x_StdPeriph_Driver\src 啦这里有很多个文件把什么文件加进去呢怕麻烦的话把所有文件全部加进去这并不会增加编译后的代码量但会增加很多的编译时间接下来设定目标输出文件夹上面这个图怎么出来的就不说啦单击Select Foler for Objects在弹出来的对话框中选择OBJ 文件夹同样方法选择List 文件的输出文件夹设置好后如果直接编译是不行的会出错还需要提供头文件所在位置单击cC标签页第一次进入时Include Paths 文本框中是空白的点击其后的按钮打开对话框增加相应的路径这样路径就设好了单击OK回到上一界面然后再单击OK退出设置即可编译链接下一会要试一试新的312 版的库效果如何了STM32 学习笔记3升级库光盘中所带的例子是310 的另外还有一个312 的我试着将312 的库替代原来的库还真有问题下面就简述问题及解决方法1将库文件解压库文件名是stm32f10x_stdperiph_libzip解压后放在任意一个文件夹中2 由于原作者做了很好的规划每一个项目中都分成三个文件夹并且在source 文件夹中又做了3 个文件夹其中APP 文件夹是放自己写的文件的其他的两个是从库中复制过来的因此想当com 版本中相同的两个文件夹CMSIS 和STM32F10x_StdPeriph_Driver 直接复制过来以为一切OK结果一编译出来一堆错误其中有错误Source\App\mainc 7 error 20 identifier "GPIO_InitTypeDef" is undefined还有大量的警告Source\STM32F10x_StdPeriph_Driver\src\stm32f10x_flashc 130 warning 223-D function "assert_param" declared implicitly看了看在APP 文件夹中还有一些不属于自己的东西stm32f10x_confhstm32f10x_ithstm32f10x_itc打开一看果然是310版本的没说的换找到STM32F10x_StdPeriph_Licom\Project\Template 文件夹用里面的同样的文件替换掉这几个文件这回应该万事大吉了吧再一看依然如故没办法了只好细细研究了通过观察发现原来可以编译通过的工程在mainc 下面挂满了h 文件而这个通不过的则少得很这是编译能通过的工程这是编译通不过的工程显然有些文件没有被包含进来一点一点跟踪发现大部分的头文件都包含在stm32f10x_confh 中而这个文件又出现在stm32f10xh 中其中有这样的一行ifdef USE_STDPERIPH_DRIVERinclude "stm32f10x_confh"endif看来是这个USE_STDPERIPH_DRIVER 没有被定义啊于是人为地去掉条件ifdef USE_STDPERIPH_DRIVERinclude "stm32f10x_confh"endif再次编译果然就OK 了可是可是也不能就这么去掉啊怎么办呢万能的网啊一搜果然就有了到设置 CC页面在那个define 中加入USE_STDPERIPH_DRIVERSTM32F10X_HD当然去掉条件编译前面的注释回到原样再次编译一切顺利可是原来的工程例子也没有加这个啊怎么回事呢再次打开原来的例子找到stm32f10xh可以看到有这么一行而新的stm32f10xh 中则是这样的原com 版的stm32f10xh 被人为地修改了一下所以不在define 中定义也不要紧而新com 则不行了至此简单的升级搞定本文见于好多地方但查询后未能确定其原始出处及作者故这里说明是转贴但作者和原始出处信息就无法提供了如果原作者看到请跟贴说明知情者也请跟贴说明ARM 中的RORW 和ZI DATA一直以来对于ARM 体系中所描述的RORW 和ZI 数据存在似是而非的理解这段时间对其仔细了解了一番发现了一些规律理解了一些以前书本上有的但是不理解的东西我想应该有不少人也有和我同样的困惑因此将我的一些关于RORW 和ZI 的理解写出来希望能对大家有所帮助要了解RORW 和ZI 需要首先了解以下知识ARM 程序的组成此处所说的ARM 程序是指在ARM 系统中正在执行的程序而非保存在ROM中的bin 映像image文件这一点清注意区别一个ARM 程序包含3 部分RORW 和ZIRO 是程序中的指令和常量RW 是程序中的已初始化变量ZI 是程序中的未初始化的变量由以上3 点说明可以理解为RO 就是readonlyRW 就是readwriteZI 就是zeroARM 映像文件的组成所谓ARM 映像文件就是指烧录到ROM 中的bin 文件也称为image 文件以下用Image 文件来称呼它Image 文件包含了RO 和RW 数据之所以Image 文件不包含ZI 数据是因为ZI 数据都是0没必要包含只要程序运行之前将ZI 数据所在的区域一律清零即可包含进去反而浪费存储空间Q为什么Image 中必须包含RO 和RWA 因为RO 中的指令和常量以及RW 中初始化过的变量是不能像ZI 那样无中生有的ARM 程序的执行过程从以上两点可以知道烧录到ROM 中的image 文件与实际运行时的ARM 程序之间并不是完全一样的因此就有必要了解ARM 程序是如何从ROM 中的image到达实际运行状态的实际上RO 中的指令至少应该有这样的功能1 将RW 从ROM 中搬到RAM 中因为RW 是变量变量不能存在ROM 中2 将ZI 所在的RAM 区域全部清零因为ZI 区域并不在Image 中所以需要程序根据编译器给出的ZI 地址及大小来将相应得RAM 区域清零ZI 中也是变量同理变量不能存在ROM 中在程序运行的最初阶段RO 中的指令完成了这两项工作后 C 程序才能正常访问变量否则只能运行不含变量的代码说了上面的可能还是有些迷糊RORW 和ZI 到底是什么下面我将给出几个例子最直观的来说明RORWZI 在C 中是什么意思1 RO看下面两段程序他们之间差了一条语句这条语句就是声明一个字符常量因此按照我们之前说的他们之间应该只会在RO 数据中相差一个字节字符常量为1 字节Prog1includevoid main voidProg2includeconst char a 5 void main voidProg1 编译出来后的信息如下Code RO Data RW Data ZI Data Debug948 60 0 96 0 Grand TotalsTotal RO Size Code RO Data1008 098kBTotal RW Size RW Data ZI Data 96 009kBTotal ROM Size Code RO Data RW Data 1008098kBProg2 编译出来后的信息如下Code RO Data RW Data ZI Data Debug948 61 0 96 0Grand TotalsTotal RO Size Code RO Data 1009 099kBTotal RW Size RW Data ZI Data 96 009kBTotal ROM Size Code RO Data RW Data 1009 099kB以上两个程序编译出来后的信息可以看出Prog1 和Prog2 的RO 包含了Code 和RO Data 两类数据他们的唯一区别就是Prog2 的RO Data 比Prog1 多了1 个字节这正和之前的推测一致如果增加的是一条指令而不是一个常量则结果应该是Code 数据大小有差别2 RW同样再看两个程序他们之间只相差一个已初始化的变量按照之前所讲的已初始化的变量应该是算在RW 中的所以两个程序之间应该是RW 大小有区别Prog3includevoid main voidProg4includechar a 5 void main voidProg3 编译出来后的信息如下Code RO Data RW Data ZI DataDebug948 60 0 96 0 Grand TotalsTotal RO Size Code RO Data 1008 098kBTotal RW Size RW Data ZI Data 96009kBTotal ROM Size Code RO Data RW Data 1008098kBProg4 编译出来后的信息如下Code RO Data RW Data ZI Data Debug948 60 1 96 0 GrandTotalsTotal RO Size Code RO Data 1008 098kBTotal RW Size RW Data ZI Data 97 009kBTotal ROM Size Code RO Data RW Data 1009 099kB可以看出Prog3 和Prog4 之间确实只有RW Data 之间相差了1个字节这个字节正是被初始化过的一个字符型变量a所引起的3 ZI再看两个程序他们之间的差别是一个未初始化的变量a从之前的了解中应该可以推测这两个程序之间应该只有ZI 大小有差别Prog3includevoid main voidProg4includevoid main voidProg3 编译出来后的信息如下Code RO Data RW Data ZI Data Debug948 60 0 96 0 GrandTotal RO Size Code RO Data 1008 098kBTotal RW Size RW Data ZI Data 96 009kBTotal ROM Size Code RO Data RW Data 1008 098kBProg4 编译出来后的信息如下Code RO Data RW Data ZI Data Debug948 60 0 97 0 GrandTotalsTotal RO Size Code RO Data 1008 098kBTotal RW Size RW Data ZI Data 97009kBTotal ROM Size Code RO Data RW Data 1008098kB编译的结果完全符合推测只有ZI 数据相差了1 个字节这个字节正是未初始化的一个字符型变量a所引起的注意如果一个变量被初始化为0则该变量的处理方法与未初始化华变量一样放在ZI 区域即ARM C 程序中所有的未初始化变量都会被自动初始化为0总结1 C 中的指令以及常量被编译后是RO 类型数据2 C 中的未被初始化或初始化为0 的变量编译后是ZI 类型数据3 C 中的已被初始化成非0 值的变量编译后市RW 类型数据附程序的编译命令假定C 程序名为tstcarmcc -c -o tsto tstcarmlink -noremove -elf -nodebug -info totals -info sizes -map -list aamap-o tstelf tsto编译后的信息就在aamap 文件中ROM 主要指NAND FlashNor FlashRAM 主要指PSRAMSDRAMSRAMDDRAM继续学习中先把开发板自带一个例子做了些精简以免看得吓人就是这个让PORTD 上接的4 个LED 分别点亮开始研究代码int main voidInit_All_Periph看到这一行开始跟踪于是又看到了下面的内容void Init_All_Periph voidRCC_Configuration继续跟踪void RCC_Configuration voidSystemInit这行代码在system_stm32f10xc 中找到了void SystemInit voidReset the RCC clock configuration to the default reset state fordebug purposeSet HSION bitRCC- CR uint32_t 0x00000001Reset SW HPRE PPRE1 PPRE2 ADCPRE and MCO bits ifndef STM32F10X_CLRCC- CFGR uint32_t 0xF8FF0000elseRCC- CFGR uint32_t 0xF0FF0000endif STM32F10X_CLReset HSEON CSSON and PLLON bitsRCC- CR uint32_t 0xFEF6FFFFReset HSEBYP bitRCC- CR uint32_t 0xFFFBFFFFReset PLLSRC PLLXTPRE PLLMUL and USBPREOTGFSPRE bits RCC- CFGR uint32_t 0xFF80FFFFifndef STM32F10X_CLDisable all interrupts and clear pending bits RCC- CIR 0x009F0000elseReset PLL2ON and PLL3ON bitsRCC- CR uint32_t 0xEBFFFFFFDisable all interrupts and clear pending bits RCC- CIR 0x00FF0000Reset CFGR2 registerRCC- CFGR2 0x00000000endif STM32F10X_CLConfigure the System clock frequency HCLK PCLK2 and PCLK1 prescalersConfigure the Flash Latency cycles and enable prefetch bufferSetSysClock这一长串的又是什么如何来用呢看来偷懒是不成的了只能回过头去研究STM32 的时钟构成了相当的复杂系统的时钟可以有3 个来源内部时钟HSI外部时钟HSE或者PLL 锁相环模块的输出它们由RCC_CFGR 寄存器中的SW 来选择SW 10系统时钟切换由软件置1或清0来选择系统时钟源在从停止或待机模式中返回时或直接或间接作为系统时钟的HSE 出现故障时由硬件强制选择HSI 作为系统时钟如果时钟安全系统已经启动00HSI 作为系统时钟01HSE 作为系统时钟10PLL 输出作为系统时钟11不可用PLL 的输出直接送到USB 模块经过适当的分频后得到48M 的频率供USB 模块使用系统时钟的一路被直接送到I2S 模块另一路经过AHB 分频后送出送往各个系统其中直接送往SDIFMSCAHB 总线8 分频后作为系统定时器时钟经过APB1 分频分别控制PLK1定时器TIM2TIM7经过APB2 分频分别控制PLK2定时器TIM1TIM8再经分频控制ADC由此可知STM32F10x 芯片的时钟比之于51AVRPIC 等8 位机要复杂复多因此我们立足于对着芯片手册来解读程序力求知道这些程序代码如何使用为何这么样使用如果自己要改可以修改哪些部分以便自己使用时可以得心应手单步执行看一看哪些代码被执行了Reset the RCC clock configuration to the default reset state fordebug purposeSet HSION bitRCC- CR uint32_t 0x00000001这是RCC_CR 寄存器由图可见HSION 是其bit 0 位HSION内部高速时钟使能由软件置1或清零当从待机和停止模式返回或用作系统时钟的外部4-25MHz 时钟发生故障时该位由硬件置1来启动内部8MHz 的RC 振荡器当内部8MHz 时钟被直接或间接地用作或被选择将要作为系统时钟时该位不能被清零0内部8MHz 时钟关闭1内部8MHz 时钟开启Reset SW HPRE PPRE1 PPRE2 ADCPRE and MCO bitsifndef STM32F10X_CLRCC- CFGR uint32_t 0xF8FF0000这是RCC_CFGR 寄存器该行程序清零了MC0[20]这三位和ADCPRE[10]ppre2[20]PPRE1 〔20〕HPRE 〔30〕SWS 〔10〕和SW 〔10〕这16 位MCO 微控制器时钟输出由软件置1或清零0xx没有时钟输出100系统时钟 SYSCLK 输出101内部8MHz 的RC 振荡器时钟输出110外部4-25MHz 振荡器时钟输出111PLL 时钟2 分频后输出Reset HSEON CSSON and PLLON bitsRCC- CR uint32_t 0xFEF6FFFF清零了PLLONHSEBYPHSERDY 这3 位Reset HSEBYP bitRCC- CR uint32_t 0xFFFBFFFF清零了HSEBYP 位为什么不一次写HSEBYP外部高速时钟旁路在调试模式下由软件置1或清零来旁路外部晶体振荡器只有在外部4-25MHz 振荡器关闭的情况下才能写入该位0外部4-25MHz 振荡器没有旁路1外部4-25MHz 外部晶体振荡器被旁路所以要先清HSEON 位再清该位Reset PLLSRC PLLXTPRE PLLMUL and USBPREOTGFSPRE bitsRCC- CFGR uint32_t 0xFF80FFFF清零了USBPREPLLMULPLLXTPRPLLSRC 共7 位Disable all interrupts and clear pending bitsRCC- CIR 0x009F0000这个暂不解读SetSysClock跟踪进入该函数可见一连串的条件编译单步运行执行的是elif defined SYSCLK_FREQ_72MHzSetSysClockTo72为何执行该行呢找到SYSCLK_PREQ_的相关定义如下图所示这样就得到了我们所要的一个结论如果要更改系统工作频率只需要在这里更改就可以了可以继续跟踪进入这个函数来观察如何将工作频率设定为72MHz 的static void SetSysClockTo72 void。
学习STM32笔记汇总
STM32F207学习笔记1、使用篇 (1)1、1标准外设库的简介 (1)1.2标准外设库中一些文件的作用 (2)1.3开发拾遗 (2)2、STM32技术概述 (3)2.1 一些概述 (3)2.2 STM32的最小系统 (3)2.3 一些IO (4)2.31 GPIO与AFIO (4)2.32 RCC 复位与时钟控制 (5)2.33 中断与事件控制 (6)2.34总线结构与存储器: (6)2.35 定时器(是定时还是计数只取决于时钟源) (6)1、使用篇1、1标准外设库的简介在嵌入式设计中,硬件成本不断降低,而软件成本大幅升高,随着新型内核的不断出现,软件底层设计的复杂性和移植的困难度在不断增加,ARM公司意识到这个问题后,联合芯片提供商,为软件人员提供标准的应用程序接口,而CMSIS就是为CONTEX-M3内核提供的。
这些通用的API接口来访问CORTEX 内核以及一些专用外设,以减少更换芯片以及开发工具等移植工作所带来的金钱以及时间上的消耗。
只要都是基于M3的芯片,代码均是可以复用的。
CMSIS 包含了CORESUPPORT和DECICESUPPORT。
即ARM负责的东西和芯片厂商如ST负责的。
其中ARM提供了core_m3.c和.h。
定义一些CORTEX-M处理器内部的一些寄存器地址以及功能函数。
芯片商提供的启动代码、初始化函数、系统头文件。
为了推广了STM32系列的微处理器芯片,意法半导体可谓是煞费苦心!不光提供了CMSIS要求内容,还提供了各个模块的标准库函数.,包含了所有外设的驱动函数,覆盖每一种外设的所有功能。
可以让程序员将更多的精力放在应用开发,加快上市时间,用标准的ANSI-C编写不受开发环境的影响。
这一系列的辅助文件以固件库(标准外设库)来提供。
那手头上的版本STM32F2xx_StdPeriph_Lib_V1.1.0来说,有三部分构成:1、library:标准外设库的主要内容,由两部分构成①CMSIS(1)ARM公司提供的内核访问函数等。
STM32学习笔记
FLASH篇:一、闪存:主存储器,信息块和闪存存储器接口寄存器等3部分组成。
1、主存储器:存放代码与数据常量(编译器编译完成后CODE=,RO=,RW=,ZI=,依次为代码,常量,初始化变量,未初始化变量),即前面两个。
B0,B1都为GND时,从0x08000000开始运行代码。
2、信息块:分为启动代码和用户选择字节。
启动代码是生产线上少些进去的,用于USART1串口下载时使用,B0=1,B1=0时运行这段代码。
用户选择字用于配制写保护杜保护等功能。
3、闪存存储器接口寄存器:控制闪存的读写,用于控制整个模块。
二、闪存编程/擦除控制器(FPEC)对主存储器和信息块的写入管理。
在执行写操作时,任何对闪存读操作都会锁住总线,在写操作完成后读操作才正确而执行。
包含有7个32位寄存器:键寄存器FLASH_KEYR;选择字节键寄存器FLASH_OPTKEYR;闪存控制寄存器FLASH_CR;闪存地址寄存器FLASH_AR;闪存状态寄存器FLASH_SR;选择字节寄存器FLASH_ORR;写保护寄存器FLASH_WRPR;复位后,FPEC模块是被保护的,不能写入FLASH_CR寄存器,通过写入特定的序列到FLASH_KEYR寄存器可以打开FPEC模块(写入KEY1和KEY2),当其中有一个写入错误,写入RDPRT进行解锁。
RDPRT=0X0000000A5;KEY1=0X45670123;KEY2=0XCDEF99AB;注:每次必须写入16位,也只有写16位。
三、闪存读取直接寻址方式,任何32为数据读操作都能访问闪存模块的内容并得到相应的数据。
读操作时FLASH_ACR寄存器配置FLASH等待周期为2。
DATA=*(U16)*ADDR;四、闪存的编程和擦除五、重要的寄存器FLASH_CR:START, PER ,PGFLASH_SR:BSTFLASH_AR:写编程地址或者擦除页地址。
六、固件库及库函数固件库文件:stm32f10x_flash.c 以及stm32f10x.h解锁与上锁:void FLASH_Unlock(void);void FLASH_Lock(void);写操作函数:FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);擦除函数: FLASH_Status FLASH_ErasePage(uint32_t Page_Address);FLASH_Status FLASH_EraseAllPages(void);FLASH_Status FLASH_EraseOptionBytes(void);获取状态:FLASH_Status FLASH_GetStatus(void);等待操作完成:FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout); 返回值是通过枚举类型定义的:typedef enum{FLASH_BUSY = 1,//忙FLASH_ERROR_PG,//编程错误FLASH_ERROR_WRP,//写保护错误FLASH_COMPLETE,//操作完成FLASH_TIMEOUT//操作超时}FLASH_Status;FLASH操作的5个状态。
