找回密码
 注册
关于网站域名变更的通知
查看: 327|回复: 1
打印 上一主题 下一主题

嵌入式内存的读写方法,以及强制类型转换的知识点

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2018-10-24 10:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
嵌入式内存的读写方法,以及强制类型转换的知识点

3 ^5 \6 p" H* c* l) R& a+ L由函数flash读取,type为0代表128字节储存区,为1代表64K存储区(512字节/扇区)
- _, n3 ?: t6 Z( G; `0 S
void InteRFlashRead(unsigned short addr, unsigned char nLength, unsigned char* dat)
& E# m! N! g/ w{% }* v! G% I$ `( y4 Q* R, l3 [  T
unsigned char i;
; [2 c' o3 [0 m& EEA = 0;
1 G! r; p" z9 B' P  e! y. ^PSCTL=0x04;# O( Y$ b. T7 n: l8 ^# P
FLSCL = 0x00;
; o- P3 [6 g/ y, ]6 mfor(i=0; i# H! l  E% t3 g. c8 u( a
{  P5 k$ j* p7 q; I3 t# E+ M
*(dat+i) = *(unsigned char code*)(addr+i);5 y0 M) q, ~, e5 w0 l
}7 ^+ \6 O% j1 ~7 D  v
PSCTL = 0;+ A9 J$ Y8 O( r3 I
EA = 1;
$ _+ f0 T) q1 E5 w% C}
! |4 u9 \/ f# d* G/ a而想到的问题,其中的   *(dat+i)= *(unsigned char code *)(addr+i);是什么意思呢?
6 _% G2 T- u* f7 K# @这里面定义的dat是char型指针,也就是说一个指针(地址)保存一个字节的数据,然而addr这个地址是short型,addr是一个指针保存2个字节的数据,所以要进行强制的类型转换,(unsignedchar code *)这一部分就是强制转换8 x" [; R! Z9 n6 `' k2 s! @: l

# w/ W: f6 o! a. C+ L3 g这里要明确的是如果我们对一个整型强制转换时可以用下列例子描述:- f; t" J6 ]2 Y$ S
unsigned inta=0x1234;1 f- Q1 r4 }  V# ^1 Y# q& l
b=(unsigned char)a;
2 o/ p0 z3 O: p; ]# p( L那么b就等于0x34   (,[size=14.399999618530273px]int型数值赋给char型变量[size=14.399999618530273px]时,只保留其最低8位,高位部分舍弃)- {' q9 w2 v! \  `" I9 K
[size=14.399999618530273px]8 N/ p1 C" C7 V+ b
! G# k& Y& w+ ^' {% y
[size=14.545454025268555px]但是这个例子当中涉及到了指针的操作,首先把addr是一个地址值,相当于指针当中的&p的值比如是0x1111,那么(unsignedchar code*)(addr+i)这一步就是转换成指向这个地址的指针,指针的值是0x1111,前面再加一个*号就表示取值,哈哈,就这么理解。
7 f- x! x+ }1 d' b- f0 |2 h2 N9 Q+ I. S& \8 Y+ Z# o9 ?
0 [& o$ F5 ?# a  \' Q' M
2、以前看到#define SREG   (*(volatile unsigned char*)0x5F)这样的定义,总是感觉很奇怪,不知道为什么,今天终于有了一点点心得,请大虾们多多批砖~~~
' x+ l& J7 g* E' S. w    嵌入式系统编程,要求程序员能够利用C语言访问固定的内存地址。既然是个地址,那么按照C语言的语法规则,这个表示地址的量应该是指针类型。所以,知道要访问的内存地址后,比如0x5F,8 l0 K* ?2 L  }4 m8 h' o; l
    第一步是要把它强制转换为指针类型
# @' m2 X2 T2 d) L( Q( _(unsigned char *)0x5F,AVR的SREG是八位寄存器,所以0x5F强制转换为指向unsignedchar类型。
/ y% C/ T& e! T! D- k5 j  volatile(可变的)这个关键字说明这变量可能会被意想不到地改变,这样编译器就不会去假设这个变量的值了。这种“意想不到地改变”,不是由程序去改变,而是由硬件去改变——意想不到。# M# [) n, l- U
  第二步,对指针变量解引用,就能操作指针所指向的地址的内容了. A1 |7 O- K1 p7 f; B
   *(volatile unsigned char*)0x5F* n7 L8 N; q5 Z% d$ Q+ H3 D5 d
  第三步,小心地把#define宏中的参数用括号括起来,这是一个很好的习惯,所以#defineSREG    (*(volatile unsigned char*)0x5F)
, Z& G  u+ O$ v5 ?) h   类似的,如果使用一个32位处理器,要对一个32位的内存地址进行访问,可以这样定义:7 X  T# c; U( H
    #define RAM_ADDR    (*(volatile unsigned long *)0x0000555F)! r9 L8 F( d0 e7 F6 z" E
   然后就可以用C语言对这个内存地址进行读写操作了: T- n6 j1 v9 H1 u4 h
    读:tmp = RAM_ADDR;! W: O7 m; p# i, A8 K; d
    写:RAM_ADDR = 0x55;
2 Y! }1 C$ r# Z- Q6 j3 D- }- l+ N4 k4 ^& b3 O
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-25 00:37 , Processed in 0.156250 second(s), 23 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表