|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
& ~$ f n' H$ c- T9 ^
由函数flash读取,type为0代表128字节储存区,为1代表64K存储区(512字节/扇区)
! | ^* f' I9 W9 j: O3 zvoid InteRFlashRead(unsigned short addr, unsigned char nLength, unsigned char* dat) ( u' F: N( K6 q* {
{
" y+ c9 S5 C# b; Sunsigned char i;* V4 d) o/ B+ g( F
EA = 0;2 y: P2 M7 q* c( N, }* s3 S* i
PSCTL=0x04;6 m; i- \5 D* ~ e6 I7 w
FLSCL = 0x00;2 S2 L G7 m; [6 B
for(i=0; i0 p O0 }+ e7 O1 t' ^5 D
{/ C# f& v: B: W" y" p
*(dat+i) = *(unsigned char code*)(addr+i);4 i! @. m' j K d
}$ K1 @" H+ ^3 y! [' {# N
PSCTL = 0;
& Y6 C- l. ]( p4 O c3 wEA = 1;. J8 ~$ y7 f& [& z b! O
}
& f5 u% j4 s- [8 K而想到的问题,其中的 *(dat+i)= *(unsigned char code *)(addr+i);是什么意思呢?
+ T% @ Q# {- g& G1 t这里面定义的dat是char型指针,也就是说一个指针(地址)保存一个字节的数据,然而addr这个地址是short型,addr是一个指针保存2个字节的数据,所以要进行强制的类型转换,(unsignedchar code *)这一部分就是强制转换
/ b; V" Q) _+ P* h$ E9 N
) Q( b/ B" t( n; }0 L这里要明确的是如果我们对一个整型强制转换时可以用下列例子描述:
8 c1 Z1 Q$ ]7 v; }1 w/ V% uunsigned inta=0x1234;, ]2 Z- e: m8 k6 E+ \6 w
b=(unsigned char)a;! c/ [ a$ o, z, c4 u$ j7 g, v) B
那么b就等于0x34 (,[size=14.399999618530273px]int型数值赋给char型变量[size=14.399999618530273px]时,只保留其最低8位,高位部分舍弃)" p" D. I4 L' a) A' u1 R
[size=14.399999618530273px]
6 K7 I" _8 L/ l& y4 ?+ U
# U5 C6 ^# s( z D/ w# W[size=14.545454025268555px]但是这个例子当中涉及到了指针的操作,首先把addr是一个地址值,相当于指针当中的&p的值比如是0x1111,那么(unsignedchar code*)(addr+i)这一步就是转换成指向这个地址的指针,指针的值是0x1111,前面再加一个*号就表示取值,哈哈,就这么理解。
6 o6 j& N3 H7 V" u8 K1 \# C9 O) Z$ b9 { J; A
# {& g; s4 P. n5 j: w% i( l. e) U
2、以前看到#define SREG (*(volatile unsigned char*)0x5F)这样的定义,总是感觉很奇怪,不知道为什么,今天终于有了一点点心得,请大虾们多多批砖~~~
. u+ A7 i- J7 E 嵌入式系统编程,要求程序员能够利用C语言访问固定的内存地址。既然是个地址,那么按照C语言的语法规则,这个表示地址的量应该是指针类型。所以,知道要访问的内存地址后,比如0x5F,* s# h: j. ] P! i7 b5 Z; N" Y' B
第一步是要把它强制转换为指针类型
, k: f4 `* @ N- ~; D6 f( v2 n(unsigned char *)0x5F,AVR的SREG是八位寄存器,所以0x5F强制转换为指向unsignedchar类型。! ]. ^& r! O# B8 n" Y1 Q. _/ p3 a
volatile(可变的)这个关键字说明这变量可能会被意想不到地改变,这样编译器就不会去假设这个变量的值了。这种“意想不到地改变”,不是由程序去改变,而是由硬件去改变——意想不到。
1 m( E& v- L' d. w! }8 o 第二步,对指针变量解引用,就能操作指针所指向的地址的内容了. z. B' [/ k9 B* l1 l) A) S
*(volatile unsigned char*)0x5F
/ w& `3 e6 A- ]8 b 第三步,小心地把#define宏中的参数用括号括起来,这是一个很好的习惯,所以#defineSREG (*(volatile unsigned char*)0x5F)6 Q1 r y$ ^7 y; R: R* E$ }
类似的,如果使用一个32位处理器,要对一个32位的内存地址进行访问,可以这样定义:, K2 I& q9 e( h6 i
#define RAM_ADDR (*(volatile unsigned long *)0x0000555F)
6 L H; _. ?$ m 然后就可以用C语言对这个内存地址进行读写操作了
7 k: ^: Y/ W& f; D p* }1 X 读:tmp = RAM_ADDR;2 c: |- }! g. q" t, E
写:RAM_ADDR = 0x55;1 a& X; r; ^- D/ e
: a) r: T* _0 _, D+ }
|
|