一、Flash原理
Flash数据读取和保存的目的是在单片机的程序存储区开辟一块空间专门用来保存系统需要记忆的参数和数据,从而完全取代EEROM,达到降低成本和数据保密的目的。该实现方法主要分为四个部分:
-
- FLASH数据的读取
- FLASH数据的设定
- FLASH数据的保存
- FLASH空间的擦除
其中,数据的读取和保存方法需要根据数据的配置格式来确定,这里我们是这样定义的:
-
-
-
- 数据格式的定义
- 数据长度:8BIT/16BIT/32BIT
- 起始标志:0xAB/其他
- 数据长度:8/16/32/64/128/256…
- 数据区
- 校验码:不同的方法校验码不同
- 举例
- 数据长度:8BIT
- 起始标志:0xAB
- 数据长度:32
- 数据区
- 校验码:数据和为0Xff
- 数据存储表如下:
- 数据格式的定义
-
-
0 | 0xAB |
1 | Data0 |
2 | Data1 |
3 | Data2 |
4 | Data3 |
5 | Data4 |
6 | Data5 |
7 | Data6 |
…………
28 | Data27 |
29 | Data28 |
30 | Data29 |
31 | checksum |
总共32个bytes,其中0xAB为数据的起始标志,checksum=0xFF-(INT8U)(0xAB+Data0+…Data29)
使用32个bytes,主要是根据flash中页的大小决定的,一般来说,flash中页的大小可以为64bytes/128 bytes/256 bytes/512 bytes/1024 bytes等,是32的整数倍,便于数据的操作
-
-
-
- 当然数据的格式可以根据系统的需求由程序员自己定义
-
-
- FLASH数据的读取
数据的读取程序在系统运行的任何时候都可以执行,只要知道数据在flash的具体地址就行。不会影响可执行代码,程序员可根据系统的实际需要进行设计
- FLASH数据的保存和擦除
数据的保存需要对flash进行擦除和编程,在进行擦除和写数据的时候,系统程序一般是不能正常运行的,因此FLASH数据的保存需要特殊处理,一般情况下是在系统关机的时候进行操作,操作结束后,可以选择关闭系统电源或者系统重新启动。
由于执行flash擦除和编程的时候,是对flash进行操作,中央处理器不能从flash直接运行程序代码,解决这个问题的方法是,将执行flash擦除和编程的这段代码搬运到RAM里面执行,这就好像电脑从硬盘先将软件拷贝到内存,然后在内存里面运行该程序。由于需要将执行flash擦除和编程的这段代码搬运到RAM里面,从而可能破坏RAM的原始数据,这也是该功能尽量在系统关机的时候进行操作的原因之一。当然程序员也可以在RAM里开辟一块区域专门用来存放这段代码,还有一种方法是用堆栈来实现,这是最好的方法。因此这里的重点就是:
- 数据保存的程序
- 将数据保存的程序拷贝到RAM的代码
- 擦除FLASH空间的代码
- 向FLASH空间写数据的代码
- RAM地址的重新分配以及变量的定义
- 相关的逻辑
- 数据的保存逻辑
按照上面的例子,所选取的MCU内部的FLASH的页大小为512Bytes,也就是说擦除一次,可以保存512/32=16次,因此,保存数据之前,要先确定所要保存的数据、保存数据的地址;保存的数据很好确定,只要分配一个32bytes的buffer就好了。要确定保存数据的地址,就要知道已经写了多少bytes的空间,根据数据的格式,采用查询的方法,因为0xAB是起始标志,因此我们只要从该空间的首地址0xXXXX保存的数据开始查询,如果是0xAB,则查询地址0xXXXX+32对应的数据是否是0xAB,依次类推;如果不是0xAB,说明该地址是这次需要保存数据的起始地址。这样就可以编写程序进行数据写入了!
同时,由于在系统初始化的时候,需要把flash的数据取出来使用,我们采用同样的数据判断逻辑,将最后一次保存的数据区域找出来,因此实际上,在系统初始化读取数据的时候,也就确定了下一次保存数据的flash地址,只要把该地址保存好,系统关机的时候,直接根据该地址保存数据就好了。
需要注意的地方是:当flash为空白或者数据已满的情况下,如何读取和判断数据是关键。
- flash擦除和编程
带有flash的单片机,一般都有flash的擦除指令和编程指令,有些甚至提供了功能丰富的擦除代码和编程代码,程序员可以根据单片机厂商提供的芯片资料选择合适的实现方法
二、实验准备
STM32F103C8T6、STlink、杜邦线若干、Keil、STM32CubeMX等
三、keil代码编写
1、CubeMX创建
定时器配置
对应外设c8t6本身设计好的PC13 LED灯
对应的GPIO设置
设置堆栈大小
四、STlink调式
1、工程文件链接:https://pan.baidu.com/s/1LmyUqFEIK4wiqzxtGua_2A
提取码:1234
在main.c文件中添加部分代码
2、硬件连线
ST-LINK | STM32 |
---|---|
SWCLK/TCK | SWCLK/TCK |
SWDIO/TMS | SWDIO/TMS |
GND | GND |
VCC | VCC |
具体参照此篇博客3、stm32F103入门学习--程序烧录的几种方法_daniaoxp的博客-CSDN博客_stm32烧录程序的步骤
程序编译没错就烧录进STM32中。
3、调式
View->memory windows->memory 1打开内存观察窗口,并在地址栏中输入:0x800c000,观察将要修改的flash区间区容:
全速运行,FlashRBuff中内容与数组FlashWBuff内容一样。
在Memory1窗口,可以看到在FLASH地址0x0800C000区成功写入对应内容。
可以看一下起始位置的数据0x08000000
之后的FF说明数据没有再写入覆盖了。
通过内部flash的学习,以后基于STM32开发就可以省去一些外部flash或EEPROM了。
五、片内Flash的提示音播放程序
1、使用DAC输出周期2khz的正弦波
使用单音音频(比如2000Hz的正弦波)的wav数据进行实验,过DAC或PCM音频模块能够基本还原出原始正弦波声音后,再用语言/音乐信号进行实验。
生成单音正弦波
文件—>新建—>音频文件
效果->生成->音调
导出文件wav文件。并UItraEdit打开。CTRL+A,接着鼠标右键,选择 十六进制复制选定视图,将内容粘贴到一个新建文件中
在新建文件中,CTRL+A,接着鼠标右键,选择范围输入起始的行号和列号,确定就选中了整个我们需要的内容
复制到notepad++中
Edit编辑->列块编辑->输入0x
借用DAC生成正弦波的例程代码链接:https://pan.baidu.com/s/1y-BkIyppGe-HGJArgTMvKg
提取码:1234
将内容复制到keil文件对应的位置,在下图红框中进行替换
2、使用DAC输出数字音频歌曲数据转换为模拟音频波形输出
操作同上,采样率修改一下,其余烧录步骤都是一样的,不再赘述。
编辑好代码后,烧录,借助音频模块听听看能否还原。
六、总结
此次学习了Jlink的使用,以及FLash的音频播放。
七、参考
STM32操作访问flash,包括写入数据到flash和从flash读取数据_Ace's Blog-CSDN博客_stm32保存数据到flash