Flash擦写的内容,个人做HC9S12系列单片机时觉得应该是各模块内容中最难而且是最麻烦的一步了。只有能够对Flash进行擦写以后,所做的Bootloader才有真正手段将串口或者其他通讯手段接收到的数据或者程序写入Flash中进行程序或者数据的更新。当初做Flash的擦写也遇到了很多问题,网上搜罗下来也没有合适的帖子能够详细的将整个过程或者学习的思路以及最后实现的程序详细的加以解析,而本博文就是基于这个出发点来写的。技术本身应当是共享的才能真正让社会进步,不是么?
关于单片机Flash的基本内容,我在此前Bootloader相关的博文中也已经提及。Flash本身是非易失性存储,可以通过编程的方式擦写其中的内容,掉电后其内容不会丢失,一般是单片机的程序存储位置。单片机运行时先将Flash中下一条运行的程序读出,然后执行其内容,再读出下一条指令,再执行循环往复。但是我们希望,能够使我们开发的单片机应用程序能够有自动更新程序的功能。比方说我现在开发的一款共享单车智能车锁,在共享单车在大马路上只能通过网络交互的时候,我希望能够更新该车锁中单片机的程序以提供新的功能。这种时候,我们就需要擦写Flash来完成这一目的。
Flash擦写操作最应该看的就是单片机的或者Flash的手册,认真的看,通篇阅读后再尝试用C语言去加以实现其功能。我们的讲解也是在这个过程中逐渐展开的,当然,还是针对HC9S12G128系列的单片机内置Flash而言。本次篇博文仅考虑了比较简单的Flash擦除与Flash写入操作,当然,在理解了Flash操作的基础上,Flash的其他操作如写保护,解保护其实是一样的道理。好了,下面我们就开始吧。
G128系列单片机的Flash存储大小有128KB, 其全局地址范围为: 0x2_0000 - 0x3_FFFF。这篇文章中已经假设各位读者已经对分页地址,非分页地址,逻辑地址,全局地址已经有所理解,如果尚不明确其意义的,我在freescale飞思卡尔 HCS12 系列单片机bootloader详解(二)这篇博文中做了解释,理解了这些概念间的相互关系再来看本博文会比较有帮助。了解Flash擦写前,根据我们手册中的内容,Flash的控制体系是这样的:
在S12系列单片机中,编程人员对Flash的操作并不是实际意义上对每个Flash存储区直接进行操作的,而是通过这个Flash Interface进行的。通过对这个Flash Interface的寄存器进行配置,再由它对Flash进行直接的操作。这里,我们称Flash Interface为Flash操作控制器或者Flash控制器。那么如何控制Flash控制器呢?手册中已经给出了Flash操作控制相关的所有寄存器,如下图所示,这些寄存器就是我们单片机的寄存器,它们的操作与普通的寄存器没有什么两样,在单片机寄存器定义头文件中均可以找到。还有一点就是通过总线时钟按照对应单片机Flash控制器的要求设置时钟分频器,给你使用的Flash控制器设置合适的时钟频率使其能够正常工作。
HCS12G128单片机部分Flash控制器相关的操作寄存器(不同型号单片机会有所不同)
首要的任务当然是设置Flash控制器的时钟了,它以总线时钟为时钟源,通过设置FCLKDIV(Flash时钟分频寄存器)来对其进行设置。G128的FCLKDIV寄存器定义在手册中的内容如下:
在这页手册中可以看到,有三个寄存器需要处理FDIVLD,FDIVLCK,FDIV。先说FDIV寄存器,这个寄存器有六位,通过分频将总线时钟频率分频至1MHz以下从而使Flash控制器可以正常工作。FDIV的值与总线时钟频率有关,根据总线频率的大小确定FDIV的值,其取值在手册中也给出了下表:
对于这个表,用法也非常简单,假如当前我的总线频率为15MHz,查表中15MHz在14.6与15.6之间,那么FDIV的值就是0x0E了。当确定好Flash控制器的频率后需要将其写保护以防误操作修改了分频寄存器,那么对FDIVLCK写1就好了,当FDIVLCK写入1后,除非重启,否则FDIV的值不能被修改,重启后FDIVLCK的值将重新归零。
由此总结我们Flash控制器的时钟设置步骤如下:
1. 根据总线频率设置分频FDIV
2. 对分频进行保护,将FDIVLCK置为1
这里需要注意,当需要写入FCLKDIV这个寄存器(也就是完成上面两个操作时),一定要确保此时Flash控制器不在执行指令,那么Flash控制器如何执行指令的呢?怎么查看它是在执行指令的呢?
请看下节,Flash控制器的指令寄存器
注: 本系列文章均为原创,如有转载引用请标明来源
原文地址:https://www.cnblogs.com/15821216114sw/p/9509680.html