版主
主题
回帖0
积分10609
阅读权限200
注册时间2008-11-22
最后登录1970-1-1
在线时间 小时
|
楼主 |
发表于 2013-10-12 14:30
|
显示全部楼层
C8051F MCU应 用 笔 记# z5 k0 K( R/ [6 `( N
" t; p) Z1 z( v' a, F
AN009 — 从应用程序写 FLASH $ Q) J% q: {' m; `9 [/ W
1 U' B6 j6 O: ^! S2 G相关器件
. o' n8 |$ B W7 Z/ j$ h本应用笔记适用于下列器件: ! Z+ u% r9 a2 `: g% @. e6 h# I
C8051F000、C8051F001、C8051F002、C8051F005、C8051F006、C8051F007、C8051F010、
8 p- _! p+ V! E! z; A" G1 }C8051F011 和 C8051F012。
) x- D4 v. ~5 k1 X* s$ w& |' r) Q引言
7 H' G+ X w0 s/ N+ k [本应用笔记的目的是说明如何从应用程序写FLASH。在应用编程允许将FLASH用于非易失性
# L; B" B& `; u0 Y! N信息的存储(例如配置参数),还可以允许采用JTAG接口之外的另一种接口(例如UART)进行在
1 O6 W7 i9 a: h( n" H( I系统引导装载。本笔记的最后给出了如何读和写FLASH的‘C’代码。 E# J( [( ^) b+ @& P, b
关键点
+ ?; v- J" f0 e; V; i3 Z c3 e 在应用编程允许将FLASH用于非易失性信息的存储,这一点与EEPROM类似。
& B( M( E! |+ S. k) ] FLASH写/擦除寿命在 – 40 ~ + 85℃的工业温度范围内保证在 10000 次以上。 8 |7 J) }2 O a& T7 S. K
FLASH存储器用 MOVC指令读取(MOVC a, @A+DPTR)。 3 I+ w; a$ g( i9 m( n" s
FLASH存储器用 MOVX 指令写入(MOVX @A+DPTR, a)。 / h0 i9 p$ \: V- _
FLASH页以 512 字节分界(0200h, 0400h, 依此类推)。
6 p2 q; o1 N; z FLASH写操作只能写入 0。因此在写一个 FLASH字节之前,包含该字节的页必须首先被擦除6 k5 N: q/ X% T! `( A7 A, Y0 o
(使该页中的所有位都为 1)。
' |- E. f7 J8 V 在进行 FLASH写或擦除之前,必须根据当前的系统时钟设置 FLSCL 中的 FLASCL 位。 2 U1 ~3 |$ y* X& v4 p
在进行 FLASH写之前,必须将 PSWE 置 1。 ; M2 O3 k) j9 m6 v. I6 w2 j+ D
在进行 FLASH擦除之前,必须将 PSWE 和 PSEE 置 1。
7 s6 T! z8 a( X# _ d FLASH页的擦除操作是将PSWE和PSEE置1并向该页512字节中的任一字节进行写操作。 7 N4 p3 S( l7 K; b0 D5 v/ t
含有读锁定字节和写/擦除锁定字节的 FLASH页不能由用户软件擦除(但是,该页可以由用户' d* F( J8 ]( W/ ]+ K( w
软件写入)。该页只能通过 JTAG 接口擦除。 3 o9 s% ]' p7 z3 B1 Y5 A
过程 + ?# b+ ?' o# z5 Y: @6 e- e
FLASH 是按一系列 512 字节的页组织的。另外还有一个 128 字节的页,该页位于 FLASH 的
7 q3 y, T- \- z5 ?. l5 _( ]顶部,起始地址为 0x8000。由于写一个 FLASH字节只能对各位写入 0,因此在写一个 FLASH字" n! p) E3 y9 K# \3 }. z. Y
节之前,该字节必须被初始化为 0xFF。一个 FLASH擦除操作将一页内的所有字节初始化为 0xFF。 1 i5 X7 ]# p& Z. Z P* z( b
擦除一个 FLASH 页 6 G( D4 `( K1 y( _
一个 FLASH 页可以通过下述过程擦除: ; ?0 C9 \9 q+ x5 c( z' m6 d: N' }
1.根据当前系统时钟频率值按 C8051F000 数据表的说明设置 FLSCL(当使用缺省的 2MHz
, I z+ G; e" k8 `2 M内部振荡器时,FLSCL=0x86)。
; a( X8 J+ w& E1 Y* u+ o3 O! d1 l2 u1 k
Silicon Laboratories Inc. 新华龙电子有限公司
$ p: j7 ?8 w8 D8 O! E! v4635 Boston Lane 深圳市福田区华强北路现代之窗大厦A座13F C室(518013)
* K" n3 w" f* W( WAustin, TX 78735 电话:0755-83645240 83645242 83645244 83645251
6 M! B8 y; `( ~/ U9 E W4 uEmail: mcuinfo@silabs.com (版权所有) 电邮:shenzhen@xhl.com.cn & w$ ~3 W, j2 O0 U1 O4 l2 b
Internet: www.silabs.com 网址:www.xhl.com.cn
5 W: Q7 d! d% g' W6 _0 G& b4 r
9 `$ ~2 n4 h2 g5 B* e. ^. G* J9 ~, g* W8 I5 h! {2 t
AN009 — 从应用程序写 FLASH
8 C1 w2 d) I" c& z+ \$ H$ T( Z: E' L8 [5 f) i+ Q
2. 通过向 PSCTL写入 03h 使 PSWE 和 PSEE 置 1。 2 y: A; N0 J' b2 |
3. 向待擦除页内的任一字节写入任意值: 1 K& P5 ^1 y* b3 R
; 初始化 DPTR,使其指向待擦除页内的地址 ) U1 p0 c0 |8 t- s
mov DPTR, #address
+ y; O8 Q2 T$ k7 w ; 启动擦除过程 1 V* p4 K3 [1 e3 B( B/ v
movx @DPTR, a
& R$ F, \+ r T3 ]" e4.如果不再进行擦除操作,将 PSEE 设置为‘0’。
: F/ K: s1 V' w- g- u; E擦除每个页需要 10到 20ms 的时间。注意:CPU内核在 FLASH擦除过程中停止工作,但外" m9 a7 d2 d Z' D
设(象 ADC、UART、SMBus 和定时器)仍然工作。在擦除过程中产生的任何中断都将被挂起,
. S& B9 H. p) ^5 [ }9 `直到该过程结束。在写一个 FLASH字节期间 CPU的工作情况与此相同。 $ A9 t$ D- A( r8 ^" i
写一个 FLASH 字节
$ ~2 A2 l& m- D- T# @3 q下述过程用于写一个 FLASH字节: # P3 b1 S5 K" \3 K7 H5 P
1. 根据当前系统时钟频率值按 C8051F000 数据表的说明设置 FLSCL(当使用缺省的 2MHz
/ Y# J- Z7 s0 ]) u- l) Y内部振荡器时,FLSCL=0x86)。 5 G' A" j0 |4 u0 i6 \, R5 z% A
2. 通过向 PSCTL写入 01h 使 PSWE 置 1(PSEE 必须为‘0’)。 5 C' _; i e" i
3. 写入字节数据。 3 |8 _3 W: |$ n2 {. W: q
; 初始化 DPTR,使其指向待写字节的地址
# B4 b4 S! Q3 x# j% F* F& X mov DPTR, #address - y- J$ E9 M/ l9 J4 O
; 将待写字节装入 acc : o, p6 i' W3 J
mov a, #value & r$ G; [& g A9 i# {/ u
; 启动写操作
* e' b$ ~2 Y; @0 b% L; \$ Q+ p$ ? movx @DPTR, a
0 r9 J2 _ f' i) l' l4. 如果不再进行写操作,将 PSWE 设置为‘0’。
" f3 E% G# M5 k O; t, A0 C3 R$ t每个 FLASH字节的写操作需要 20到 40μs 的时间。 5 \ b7 V }0 q) e) r; n/ h
更新 FLASH中的数据
. a- I. q* o4 z当保存一组配置信息时,经常需要在一组字节中单独改变某个字节的数值。单独更新某个字节
$ ~: g$ p: f! ~, N(或字节子集)的一般过程如下: 2 p( Q. @7 \7 a0 Z1 k+ q
1. 将 FLASH页拷贝到一个临时存储区(RAM 或一个已被擦除的‘临时’FLASH页)。
* X x& a7 F6 U& x A2. 擦除 FLASH页的数据。 ) U6 d7 g" F9 j; Z9 z( S# P
3. 将前面存储在临时存储区的内容复制到 FLASH页中。 9 p: T) _9 m( E4 @- e' r
用‘C’代码访问 FLASH
4 |5 z4 V2 f" ?$ \- K) |/ s6 `所附的示例代码说明了如何用‘C’程序擦除、写和读 FLASH 内容。由于 FLASH 读操作是4 }' H) {) X& T& v0 ~8 z" C
用 MOVC 指令实现的,因此用于读操作的 FLASH 指针必须是 CODE 类型。由于 FLASH 写操作9 F8 h' r( g3 F9 v n
是用 MOVX 指令实现的,所以用于写(或擦除)操作的 FLASH指针必须是 XDATA 类型。 - W# U- k; L) j, {, l! u6 I
" b( Z2 X7 q# b3 e. D3 `2 AN009-1.0 JAN01
' P3 w. J! w+ z% K9 p% b4 g: W- y, V
! H/ P$ C. [# F) S c' r
# n7 K N6 r [6 p" B7 ^AN009 — 从应用程序写 FLASH - e2 B9 \7 ]) H# _
8 \6 ^7 m$ a0 g
软件示例
# @2 f# i) `9 P( j0 g, {# ~, M//-----------------------------------------------------------------------------------------------------------------------
6 g' G7 O0 K: @2 ^& w7 W// FLASH_1.c 9 k. m' l0 m" n* z* _6 f
//-----------------------------------------------------------------------------------------------------------------------
7 J" r! I0 ?* L! H8 n! \7 O//
! \2 J8 x5 f1 a! s// 作者:BW
! [) M5 m' f& _+ ^# G4 n% Z// 1 o I2 E. A& W2 L
// 本示例程序给出了用‘C’程序擦除、写和读 FLASH存储器的例子。 7 O: P5 I* g- [8 a1 ?
// 3 W0 f- Z$ |9 ?
// 目标器件:C8051F000 或 C8051F010
( O. l A3 T5 G+ R7 D// 开发工具:KEIL C51
. k/ w0 K: J5 f; L& Y//
' q2 b$ g* S% W6 t$ d+ E' \: ~7 C: L2 z3 |- R
//----------------------------------------------------------------------------- 9 B. t$ Y$ L* ^. |# U+ t
// 包含文件
O" K/ B" h, _6 V5 q, d//-----------------------------------------------------------------------------
$ b( ^5 ^$ |# n5 t4 {, ?
( p5 C9 t# G; o" d$ ~$ ~#include <c8051f000.h> // SFR 声明 & i' U4 Y! y1 J f
#include <stdio.h> # c# Y/ w9 t/ [3 H; k6 q
7 q* I+ ~1 a1 y/ |9 M
//----------------------------------------------------------------------------- - i# x7 h+ N" C" o8 K- O. a. }) J5 }% _
// Function PROTOTYPES
* A( W3 O z( b; c/ E//----------------------------------------------------------------------------- " ?7 l7 m; `+ }$ {( T6 Q
* X# `2 |3 f2 T& qvoid main (void);
9 ]+ J1 V; O' t5 R! w" o: ?. X3 d6 _1 j: A9 S0 F' k. |
//-----------------------------------------------------------------------------
; T$ `* t3 S2 w; x+ l* `5 q* R! [// MAIN Routine
4 W3 y& }" N2 Z* u//----------------------------------------------------------------------------- $ {2 [3 x) \" o+ N% w) U) J
8 a0 r, G, @9 H% ?/ W) H
void main (void) {
$ t' k) X* x& j/ I; T" K
5 b3 C G7 b( A) t unsigned char test_string[ ] = "Howdy!"; // 将被拷贝到 FLASH中的字符串
6 U' u& a5 v+ Y, s$ G( |5 y' _8 l
unsigned char xdata *pwrite; // 程序存储器空间的指针(FLASH),指向待写地址 $ N1 ?: l0 G4 U! _
unsigned char code *pread; // 程序存储器空间的指针(FLASH),指向待读地址
3 O0 l6 W" A- @$ |1 F unsigned char *pgen; // 一般指针
/ F, d# V7 L4 a! [ char test; // 测试字符
0 `7 a4 \7 M$ {# f) K. m6 k' B* _, E- d( d+ \4 S1 w0 g
AN009-1.0 JAN01 3
* M% |% d5 F9 [, h- L0 d4 X( ~% s/ E
, }7 @, ~, k. t0 C
+ N7 r' E4 U4 fAN009 — 从应用程序写 FLASH / z5 w J$ A1 @
2 D1 }3 b7 N$ Z% k, v2 d1 c
// 禁止看门狗定时器 7 k! ?0 I, X2 `6 q
WDTCN = 0xde;
6 F5 ~+ q( ]: g WDTCN = 0xad; 3 z2 f. z* b8 `6 @9 B$ x( @
// 擦除 128 字节的信息页(位于 0x8000)
: N; Q5 O$ G9 q4 x4 M FLSCL = 0x86; // 设置 FLASH标度寄存器(对 2MHz 系统时钟)
: `2 b4 I6 ]5 I" R, T5 Q2 w PSCTL = 0x03; // 将 PSWE 和 PSEE 置‘1’(MOVX 指令对应 " n1 X: a2 z* j8 m
// 的 FLASH页 / Z: j# ~* ]1 a6 i, N/ [
pwrite = 0x8000; // 将指针指向待擦除页
# ~5 ]2 W3 P3 D6 Y *pwrite = 0; // 启动擦除过程 ) X& l- ?/ W) l3 M, h' A6 I
PSCTL = 0x01; // 清除 PSEE,PSWE 仍然置 1 / W: R( w$ g9 v5 l. X+ x
// MOVX 指令将写到对应的地址
, b9 n3 z% O8 b9 J1 K
4 G! B$ h9 o4 O/ M* V5 U3 D. b" F // 现在我们要拷贝字符串 <test_string> 的内容到 FLASH页,从地址 0x8000 开始。 9 z" ]7 e2 F: C6 u2 @# b7 Z5 @& L4 k; I
6 R/ O8 _% l/ e* e4 G) F pgen = test_string; // pgen 指向源字符串
; _( I. o1 ~+ o4 m% w! L# ]7 Y) r do { * _; r) W0 I( ^& r+ a
*pwrite++ = *pgen++; // 拷贝字节 - P; [. \ {( ?, _
} while (*pgen != '\0'); // 直到 NULL 结束符 ~! O! H" ]' q! k$ [' [
3 }- H {, f+ R *pwrite = NULL; // 用 NULL 结束目的字符串
' W8 Y7 `; ?. z9 `% m9 {1 [8 t" V3 A! V
PSCTL = 0; // 禁止 FLASH写
* S! b: |* p( Z/ y4 A FLSCL = 0x8f; // 禁止 FLASH写
- J, ?$ I- @* @ _$ p7 e! {; e3 J7 R5 ]9 M
// 现在我们读写入的字符串
d* P n* l1 s
" ^8 \5 H3 P: q pread = 0x8000; // 初始化 CODE 读指针为字符串起始地址
[* F3 S5 ^- ~& D$ i1 b1 o9 q3 F0 s2 \3 J5 N
test = 0x5a;
& W z5 @, M5 `, B6 p do {
1 l( E9 j2 c8 }" x test = *pread++;
5 q7 b' m+ S' d. r3 P2 W } while (test != '\0'); ( R0 w6 s' ?- a0 s/ l6 H
$ ~ q( o, \( q! k! u% H% G
while (1) { // 原地循环 8 E6 I a9 K- [3 ?, p
}
& C" B6 P, R3 R* W5 k}
- q& u! t6 {9 n% W5 v( h! g J' e n+ E1 G% I
4 AN0
- s# \3 d& q/ q% H3 M; O' P% M. C' ?' r( U! Q- J+ h, p
|
|