版主
主题
回帖0
积分10609
阅读权限200
注册时间2008-11-22
最后登录1970-1-1
在线时间 小时
|
楼主 |
发表于 2013-10-12 14:30
|
显示全部楼层
C8051F MCU应 用 笔 记
$ Z7 r; c" k. b
) U) H( S1 u- e& Z5 iAN009 — 从应用程序写 FLASH
: S9 ? [0 @" v4 M8 a1 Y1 x' u
6 h4 ~* j% p6 t0 Z相关器件
) c5 {, L4 T1 L w) Q' I本应用笔记适用于下列器件: 3 U7 i1 P6 s+ T" k
C8051F000、C8051F001、C8051F002、C8051F005、C8051F006、C8051F007、C8051F010、- P8 U# g# Q7 y+ \3 s! o8 z0 n
C8051F011 和 C8051F012。 ' Y% h6 ]7 X* M+ Z7 V9 {9 R
引言
+ E! k8 w, Z- f. b: b本应用笔记的目的是说明如何从应用程序写FLASH。在应用编程允许将FLASH用于非易失性. ^8 z1 l( B1 N4 ~
信息的存储(例如配置参数),还可以允许采用JTAG接口之外的另一种接口(例如UART)进行在! P9 \, n. ?0 u/ q6 G
系统引导装载。本笔记的最后给出了如何读和写FLASH的‘C’代码。
7 H& L: c6 v5 Q6 h c' o/ t; X关键点
. N8 V( b% E, |4 G 在应用编程允许将FLASH用于非易失性信息的存储,这一点与EEPROM类似。 9 E& G" f* v/ ]. H, }
FLASH写/擦除寿命在 – 40 ~ + 85℃的工业温度范围内保证在 10000 次以上。 . q7 e8 q* N9 D# y7 ]2 X5 n' X1 ?
FLASH存储器用 MOVC指令读取(MOVC a, @A+DPTR)。 6 ^3 l; N, ^0 {& J9 z3 y) V
FLASH存储器用 MOVX 指令写入(MOVX @A+DPTR, a)。 7 X6 V6 }' g' P M& \
FLASH页以 512 字节分界(0200h, 0400h, 依此类推)。 , a8 }% v7 ]# d7 U/ s
FLASH写操作只能写入 0。因此在写一个 FLASH字节之前,包含该字节的页必须首先被擦除
+ r: e) f6 S* C(使该页中的所有位都为 1)。 $ S' F& ~2 i' {$ u
在进行 FLASH写或擦除之前,必须根据当前的系统时钟设置 FLSCL 中的 FLASCL 位。
+ f! w$ R% Q e9 j, m) F7 d 在进行 FLASH写之前,必须将 PSWE 置 1。
% a: J" Q6 N+ }( T0 X) s/ y 在进行 FLASH擦除之前,必须将 PSWE 和 PSEE 置 1。 7 z! w8 S% o5 b/ J
FLASH页的擦除操作是将PSWE和PSEE置1并向该页512字节中的任一字节进行写操作。
$ o2 _5 B7 V% z2 K6 }8 k! e 含有读锁定字节和写/擦除锁定字节的 FLASH页不能由用户软件擦除(但是,该页可以由用户
( P" x, ?- T$ g1 k; N7 J9 x软件写入)。该页只能通过 JTAG 接口擦除。
2 ^ y6 p* H7 n# U7 ?' I. F( C& R过程 , Y0 x7 K1 X) k* h
FLASH 是按一系列 512 字节的页组织的。另外还有一个 128 字节的页,该页位于 FLASH 的9 q8 H ?7 M3 v
顶部,起始地址为 0x8000。由于写一个 FLASH字节只能对各位写入 0,因此在写一个 FLASH字
2 ]2 G6 S; }1 }6 p, V节之前,该字节必须被初始化为 0xFF。一个 FLASH擦除操作将一页内的所有字节初始化为 0xFF。
: [) [0 Q/ G5 X" G1 J+ m/ K' ~! W擦除一个 FLASH 页
4 m/ p& n; u2 x" w8 V一个 FLASH 页可以通过下述过程擦除: 2 W/ V) ?! e; C1 F7 r
1.根据当前系统时钟频率值按 C8051F000 数据表的说明设置 FLSCL(当使用缺省的 2MHz
+ g& U) i: s" y) }2 U内部振荡器时,FLSCL=0x86)。
" N/ _) w- _8 j0 e+ M1 ?+ r+ A+ l3 d( W$ s
Silicon Laboratories Inc. 新华龙电子有限公司
6 e) Y% Z* w- w2 C4635 Boston Lane 深圳市福田区华强北路现代之窗大厦A座13F C室(518013)
( ~' \6 a- \7 b' k% |Austin, TX 78735 电话:0755-83645240 83645242 83645244 83645251 0 v( V5 Y7 q" j
Email: mcuinfo@silabs.com (版权所有) 电邮:shenzhen@xhl.com.cn
0 D Q7 T, g1 B7 o. pInternet: www.silabs.com 网址:www.xhl.com.cn $ k! f3 m& q e+ F% E3 F
. B9 X l% X" ]: J
! m7 j: v7 P- `/ B# SAN009 — 从应用程序写 FLASH
; e" e* o7 M8 O( e6 x1 ]) e0 _9 H: r0 ?8 z7 g1 B/ N
2. 通过向 PSCTL写入 03h 使 PSWE 和 PSEE 置 1。 5 Q! l4 E; d4 `) P* u1 d/ C( D7 h/ }
3. 向待擦除页内的任一字节写入任意值:
- R4 `1 ~: R3 z2 G! _- d/ g ; 初始化 DPTR,使其指向待擦除页内的地址
7 m% x' l) e* y0 L5 Z* f1 i( ]# f' W mov DPTR, #address
( a' _6 K8 L9 X) W; j5 p ; 启动擦除过程
, {& r7 Q# g- @& Y2 M+ F1 ?. v5 M2 q" i movx @DPTR, a + ~% o2 `/ P8 f0 j2 W
4.如果不再进行擦除操作,将 PSEE 设置为‘0’。 5 @2 k4 k: N# n4 h5 [, M" K; |( c& f
擦除每个页需要 10到 20ms 的时间。注意:CPU内核在 FLASH擦除过程中停止工作,但外
9 E* ]4 g/ P- W+ a7 l7 B: r+ A0 @设(象 ADC、UART、SMBus 和定时器)仍然工作。在擦除过程中产生的任何中断都将被挂起,# R; R) o" {. ?
直到该过程结束。在写一个 FLASH字节期间 CPU的工作情况与此相同。 ( ]: @- b1 l9 S5 a; `& E) V7 A9 s
写一个 FLASH 字节
/ P3 E) V r( d, i7 M; q下述过程用于写一个 FLASH字节: , q# V9 e! u5 D/ ~ p3 P
1. 根据当前系统时钟频率值按 C8051F000 数据表的说明设置 FLSCL(当使用缺省的 2MHz4 q; b5 A* _8 }0 q& x# X7 Q
内部振荡器时,FLSCL=0x86)。 2 p4 N0 j6 R) n/ }* l! ?+ u
2. 通过向 PSCTL写入 01h 使 PSWE 置 1(PSEE 必须为‘0’)。 # Q) T; }# U# K9 Q
3. 写入字节数据。
7 ~9 o, Y. ~: u t0 g! P ; 初始化 DPTR,使其指向待写字节的地址
: a7 G/ n( N6 c7 \& a' z2 q mov DPTR, #address
1 ^0 l1 x D) `& n ; 将待写字节装入 acc
5 M# B0 |3 Z( J) w% M mov a, #value & J) J* z( E+ @0 ^2 ?# m
; 启动写操作
9 I& l: n$ H O/ }# b( p movx @DPTR, a
4 K: \: M& _' f5 c& I$ l6 c4. 如果不再进行写操作,将 PSWE 设置为‘0’。 1 D$ @; e9 @5 a0 H
每个 FLASH字节的写操作需要 20到 40μs 的时间。 " S' |$ A& `+ w2 L
更新 FLASH中的数据
i5 a. A, z+ H$ D3 a1 C1 {6 a当保存一组配置信息时,经常需要在一组字节中单独改变某个字节的数值。单独更新某个字节
: E! G1 h, Y, H* W" v, }2 ^9 _(或字节子集)的一般过程如下:
+ H' K }; z. j7 E1 K1. 将 FLASH页拷贝到一个临时存储区(RAM 或一个已被擦除的‘临时’FLASH页)。 6 Y+ y) A& Z9 z2 ]/ x
2. 擦除 FLASH页的数据。 8 l1 M" @* _1 G* I( a0 w2 n
3. 将前面存储在临时存储区的内容复制到 FLASH页中。
; H, _; H3 c: C用‘C’代码访问 FLASH : U; U i1 w. u3 r! i$ l/ m0 ]4 K% {
所附的示例代码说明了如何用‘C’程序擦除、写和读 FLASH 内容。由于 FLASH 读操作是
, p! F6 K) A1 E: P$ S. x用 MOVC 指令实现的,因此用于读操作的 FLASH 指针必须是 CODE 类型。由于 FLASH 写操作
" @7 `6 n- s5 T. k. A是用 MOVX 指令实现的,所以用于写(或擦除)操作的 FLASH指针必须是 XDATA 类型。 * I& H( K% z+ X; v" Y$ R. S
* W O. T* v! n- k2 AN009-1.0 JAN01 7 \& t5 }$ N2 X6 ^7 k6 j$ q
& m9 J& J: U, F' T
. i$ k2 }1 I) g( i% z& a
* m7 ^3 ]8 ?' z: Y
AN009 — 从应用程序写 FLASH
+ ~" C# w+ t$ M, o. ^7 o1 Z! T& l8 ~7 p: |6 M
软件示例 - c5 i3 i( r0 P1 r8 N9 q
//-----------------------------------------------------------------------------------------------------------------------
& [- [$ L. |/ j7 Q) V// FLASH_1.c 2 r, Z+ E3 `: [0 v5 w+ }
//-----------------------------------------------------------------------------------------------------------------------
; u. L6 X# Q& j// 9 O( Y* B* g! W
// 作者:BW , S7 O z# ]3 E h
//
" `3 A* t+ P) Y// 本示例程序给出了用‘C’程序擦除、写和读 FLASH存储器的例子。 & I2 i! Z4 f! Z2 {9 T( B' t* \, G
// ( ^3 _- U4 a# v* h& L7 i
// 目标器件:C8051F000 或 C8051F010 0 ?: j* A7 R% j" V4 C( R
// 开发工具:KEIL C51 , _9 R: c% @8 v
// ( j2 G( @( ~0 t& M2 O( _
# [# e" T3 @: ~0 |- Z; _//-----------------------------------------------------------------------------
$ l- F4 a, j, K% J: |! T9 Z; U0 \// 包含文件
& P& ?. }2 }* ?* w. g# @6 l//-----------------------------------------------------------------------------
% Q4 h# W8 v0 c U0 G/ v, o3 t1 v5 t* P5 o; Q( S! l
#include <c8051f000.h> // SFR 声明 7 I' h" D; C; Q* y
#include <stdio.h>
1 }$ f& A& b- ~; f0 e ^
6 Q5 f3 M7 y2 w& t( C% v) o, m1 }//-----------------------------------------------------------------------------
$ E# a4 @2 w) l! b9 P// Function PROTOTYPES 7 c2 M, z9 I' I# v4 z
//-----------------------------------------------------------------------------
5 h" R& U7 c% S+ C! b1 I/ x9 c/ {
6 K) z" x7 E* q' R0 F8 gvoid main (void); 4 p/ l5 X: E3 \
% b7 D% d5 l1 k) ?5 X0 l
//-----------------------------------------------------------------------------
- L& B) v# V0 e4 q& L// MAIN Routine 8 `$ b2 g2 \) O6 @9 |
//-----------------------------------------------------------------------------
, ~9 `+ n1 J5 _) c9 Q( |* d$ Z% C) O& m6 P1 _% J
void main (void) { 1 q6 }6 W/ d$ W9 ?" h K
, |, B3 u. N, f9 w1 n
unsigned char test_string[ ] = "Howdy!"; // 将被拷贝到 FLASH中的字符串
3 d) E2 V4 [% V# `* d: ^: }# s" S7 U
unsigned char xdata *pwrite; // 程序存储器空间的指针(FLASH),指向待写地址 2 N. j5 d3 X& h
unsigned char code *pread; // 程序存储器空间的指针(FLASH),指向待读地址
0 x' h9 E- w0 l$ `2 k unsigned char *pgen; // 一般指针 , `) o7 c ^- [; o" [
char test; // 测试字符 # A' n7 P! T! T% B, ~! W
9 f' B) ^" O& a, K AN009-1.0 JAN01 3 ! E* @. N& D/ w# ~; M3 q4 M; `: J- ] c
9 x$ b# E7 d+ a! d1 J |
2 D3 d# D/ b7 Z9 J. H
) h; |2 a$ N) D1 y6 y0 pAN009 — 从应用程序写 FLASH
/ F) G+ M4 \- w. s+ v+ k6 _* M
3 n8 K1 u7 y& ~8 Q6 a // 禁止看门狗定时器 . x* v+ l& g5 ~ c
WDTCN = 0xde; " q' E; w9 A! e! H" ~# N* P
WDTCN = 0xad;
" Z0 s6 N$ m8 g C- o9 J0 j // 擦除 128 字节的信息页(位于 0x8000) S+ f6 n$ q' D/ r3 z+ K& E& f8 Z
FLSCL = 0x86; // 设置 FLASH标度寄存器(对 2MHz 系统时钟) ! ~4 [ s& t3 W) A1 B& t- L
PSCTL = 0x03; // 将 PSWE 和 PSEE 置‘1’(MOVX 指令对应 ; i D5 J7 o& r& D& V0 a& Y) W7 ?
// 的 FLASH页 8 D8 q5 o/ |( z
pwrite = 0x8000; // 将指针指向待擦除页
" i* c' h8 P) q* s& b% R *pwrite = 0; // 启动擦除过程
0 e; e& c* K j D) d PSCTL = 0x01; // 清除 PSEE,PSWE 仍然置 1
( X1 h$ C1 p9 k // MOVX 指令将写到对应的地址
& N' ]2 J5 S% G% [! J' m$ K+ I# R$ K, s! o
// 现在我们要拷贝字符串 <test_string> 的内容到 FLASH页,从地址 0x8000 开始。
1 i5 T1 p9 m( _! @8 k7 O( C- e% ?& F4 s- M i9 ^0 l
pgen = test_string; // pgen 指向源字符串
* c" [* w4 T c0 C- u5 ~ do {
3 }% X$ s2 U# Z2 @ *pwrite++ = *pgen++; // 拷贝字节 ! a+ e5 _4 l! k! q* ]$ h, N; y
} while (*pgen != '\0'); // 直到 NULL 结束符 : p% T% c' B1 _, h" D& k
) N+ B/ Z8 E/ o# i: }* f8 o, Z *pwrite = NULL; // 用 NULL 结束目的字符串
, {- L7 n! H, P, P& s# q! p5 F+ s/ e7 W
PSCTL = 0; // 禁止 FLASH写
) @. }- h/ e& O8 _ FLSCL = 0x8f; // 禁止 FLASH写
* R d3 Y, S+ _3 [2 M5 n
, h+ [# U' T$ F/ { // 现在我们读写入的字符串
, X4 c$ t4 @" j8 a0 |: T
[* l k5 s* G- |7 Z pread = 0x8000; // 初始化 CODE 读指针为字符串起始地址 * n: [" V/ q$ W# {
; u9 ?# t! y, a( e
test = 0x5a;
7 i7 I$ a F6 C; c8 | do { , u7 l# S: z0 W8 k2 F: z/ q
test = *pread++;
9 I( K) S/ x9 c0 a9 R: m } while (test != '\0'); 0 f+ @5 }' P% ~1 Q+ M8 a
Q2 X8 m* | F4 Z8 o- X$ u) q4 p) P
while (1) { // 原地循环
- F& l G9 z8 ~& g! ~1 h9 c } - c1 b2 |# k9 e4 N
}
2 R# v! }% v" \) [3 d2 H$ `7 i' V# L! G5 }! B* v5 z6 d G
4 AN03 K0 G; M" K- Y; V3 o+ @" n
4 f( j" K" M9 B9 b! D0 b! b
|
|