版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第七章ARM接口程序设计7.1LED显示控制7.2K9F1208访问技术7.3串口通信本章小结7.1LED显示控制
参考本书2.5.2小节的分析,两个LED数码管的控制地址为0x08000110和0x08000112。借助于看门狗定时器或定时计数器可实现简单的计数秒表。由于只有两位数码管,秒表计到99秒后,从0开始重新计数。
7.1.1看门狗定时器秒表
在工程ex6_12的基础上,新建工程ex7_1。工程ex7_1的工作界面如图7-1所示。图7-1工程ex7_1的工作界面由图7-1可知,工程ex7_1包括的文件与工程ex6_12中的相同,即S3C2410A.s、leflash.c和cvectaddr.c。在工程ex6_12的同名文件的基础上,只需修改文件cvectaddr.c的内容,添加七段数码管显示操作即可。文件cvectaddr.c的内容如下:
1#defineLED1_MASK0x20
2#defineLED2_MASK0x40
3#defineLED3_MASK0x80
4
5#defineGPCDAT_ADDR(*(volatileunsignedint*)
0x56000024)
6
7#defineSRCPND (*(volatileunsignedint*)
0x4A000000)
8#defineINTMOD
(*(volatileunsignedint*)
0x4A000004)
9#defineINTMSK(*(volatileunsignedint*)
0x4A000008)
10#definePRIORITY (*(volatileunsignedint*)
0x4A00000C)
11#defineINTPND (*(volatileunsignedint*)
0x4A000010)
12#defineINTOFFSET (*(volatileunsignedint*)
0x4A000014)
13
14//SEG7LEDAddress
15#defineSeg7A(*(volatileunsignedchar*)0x08000110)
16#defineSeg7B(*(volatileunsignedchar*)0x08000112)
17
18#defineU8unsignedchar
19
20U8seg7val[16]=
21{
22
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
23//0123456789ABCDEF
24};
25
26//enablewatchdogtimerintterupt
27voidopenDog(void)
28{
29 INTMOD=0x0; //setasIRQ
30 INTMSK&=~(0x200); //openDog
31 PRIORITY=0x7F;
32}
33intnumber=0;
34intnLED=0;
35intnCnt=0;
36__irqvoidc_Wdt_ISR()
37{
38
39 intiReg=0;
40 if(SRCPND|0x200)
41 SRCPND=0x200;
42 if(INTPND|0x200)
43 INTPND=0x200;
44 //INTMSK|=0xFFFFFFFF;//closeall,includeDog
45 nLED=0;
46 switch(number)
47 {
48 case0: //SWInumber0code
49 nLED^=(LED2_MASK|LED3_MASK);
//LED1light
50 break;
51 case1:
52 nLED^=(LED1_MASK|LED3_MASK);
//LED2light
53 break;
54 case2:
55 nLED^=(LED1_MASK|LED2_MASK);
//LED3light
56 break;
57 }
58 number++;
59 if(number>2)
60 number=0;
61 GPCDAT_ADDR=nLED; //Ledshineinturn
62
63 //Seg7LEDcountseachsecond
64 if(nCnt>=100)
65 nCnt=0;
66 Seg7A=seg7val[nCnt/10];
67 Seg7B=seg7val[nCnt%10];
68 nCnt++;
69
70 //openIRQ
71 __asm
72 {
73 MRSiReg,CPSR
74 BICiReg,iReg,#0x80
75 MSRCPSR_c,iReg
76 }
77//INTMSK&=~(0x200);//openDog
78}
编译连接,下载并运行工程ex7_1,可以看到七段数码管按秒从00计数到99,然后循环计数。7.1.2定时器1秒表
由于看门狗定时器主要用于系统程序运作监控,在程序正常运行过程中,有必要的“喂狗”操作,当程序运行不正常时,看门狗将会减计数到0,从而强制系统复位。因此,常用的秒表控制不占用看门狗定时器,而是由定时计数器实现的。
S3C2410A具有5个16位的定时器,其中定时器0~3具有PWM波发生功能,即可以输出PWM波,定时器4没有外部输出。定时器工作频率为PCLK/(预分频值+1)/分频值,在下面的工程ex7_2中,将使用定时器1,并设置其工作频率为20 kHz,即为48 MHz/(149+1)/16=20 kHz。定时器1的使用方法如下:
首先,设置TCFG0(定时器配置寄存器0,地址为0x51000000)的值为0x95,即定时器1的预分频值为0x95,
十进制数为149。注意:定时器0和1共用同一个预分频值。
然后,设置TCFG1(定时器配置寄存器1,地址为0x51000004)的值为0x30,即定时器1的分频值为16。
其次,设置TCNTB1(定时器1计数寄存器,地址为0x51000018)和TCMPB1(定时器1比较寄存器,地址为0x5100001C)的值为0x4E20和0x4000。这里没有用到TCMPB1,当TCNTB1减计数到0后,将触发定时器1中断。再次,设置TCON(定时器控制寄存器,地址为0x51000008)的值为0xA00,即刷新TCNB1和TCMPB1的值。
最后,设置TCON的值为0x900,启动定时器1。
从第五章的表5-7中可以查到,定时器1中断的偏移号为11。
在工程ex7_1的基础上,新建工程ex7_2,其工作界面如图7-2所示。图7-2工程ex7_2的工作界面工程ex7_2包括三个文件:S3C2410A.s、ledflash.c和cvectaddr.c。其中,文件S3C2410A.s与工程ex7_1中的相同;文件ledflash.c的源代码如下:
1externvoidopenTimer1(void);
2
3externvoidc_Timer1_ISR(void);
4
5voidinitTimer1(void);
6
7intmain()
8{
9//0x010FFF20+11*4istheaddressofTimer1jumper
10*(volatileunsignedint*)
(0x010FFF20+4*11)=(unsigned)c_Timer1_ISR;
11 //initializeTimer1
12 initTimer1();
13 //EnableTimer1Interrupter
14 openTimer1();
15 while(1)
16 {
17
18 }
19}文件cvectaddr.c的源代码如下:
1#defineLED1_MASK0x20
2#defineLED2_MASK0x40
3#defineLED3_MASK0x80
4
5#defineGPCDAT_ADDR(*(volatileunsignedint*)
0x56000024)
6
7#defineSRCPND
(*(volatileunsignedint*)
0x4A000000)
8#defineINTMOD (*(volatileunsignedint*)
0x4A000004)
9#defineINTMSK
(*(volatileunsignedint*)
0x4A000008)
10#definePRIORITY (*(volatileunsignedint*)
0x4A00000C)
11#defineINTPND (*(volatileunsignedint*)
0x4A000010)
12#defineINTOFFSET (*(volatileunsignedint*)
0x4A000014)
13
14//SEG7LEDAddress
15#defineSeg7A (*(volatileunsignedchar*)
0x08000110)
16#defineSeg7B (*(volatileunsignedchar*)
0x08000112)
17
18//Timer1registerrelatedAddress
19#defineTCFG0 (*(volatileunsignedint*)
0x51000000)
20#defineTCFG1 (*(volatileunsignedint*)
0x51000004)
21#defineTCON (*(volatileunsignedint*)
0x51000008)
22#defineTCNTB1 (*(volatileunsignedint*)
0x51000018)
23#defineTCMPB1 (*(volatileunsignedint*)
0x5100001C)
24
25#defineU8unsignedchar
26
27U8seg7val[16]=
28{
290xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E
30//0123456789ABCDEF
31};
32
33//initializeTimer1
34voidinitTimer1(void)
35{
36TCFG0=0x95;
//prescale=119
37TCFG1=0x30;
//divider=1/16
38TCNTB1=0x4E20-1; //counternumber=0x4E1F
39TCMPB1=0x4000;
40TCON=0xA00; //updateTCNTB1andTCMPB1
41TCON=0x900; //StartTimer1
42}
43
44//enableTimer1intterupt
45voidopenTimer1(void)
46{
47 INTMOD=0x0;
//setasIRQ
48 INTMSK&=~(0x800); //openTimer1
49
PRIORITY=0x7F;
50}
51intnumber=0;
52intnLED=0;
53intnCnt=0;
54__irqvoidc_Timer1_ISR()
55{
56
57intiReg=0;
58if(SRCPND|0x800)//mustchangefrom0x200to0x800
59SRCPND=0x800;
60if(INTPND|0x800)//mustchangefrom0x200to0x800
61 INTPND=0x800;
62//INTMSK|=0xFFFFFFFF;//closeall,includeTimer1
63 nLED=0;
64 switch(number)
65 {
66 case0: //SWInumber0code
67nLED^=(LED2_MASK|LED3_MASK); //LED1light
68 break;
69 case1:
70 nLED^=(LED1_MASK|LED3_MASK);
//LED2light
71 break;
72 case2:
73 nLED^=(LED1_MASK|LED2_MASK);
//LED3light
74 break;
75 }
76 number++;
77 if(number>2)
78 number=0;
79 GPCDAT_ADDR=nLED; //Ledshineinturn
80
81 //Seg7LEDcountseachsecond
82 if(nCnt>=100)
83 nCnt=0;
84 Seg7A=seg7val[nCnt/10];
85 Seg7B=seg7val[nCnt%10];
86 nCnt++;
87
88 //openIRQ
89 __asm
90 {
91 MRSiReg,CPSR
92 BICiReg,iReg,#0x80
93 MSRCPSR_c,iReg
94 }
95//INTMSK&=~(0x800); //openTimer1
96}
工程ex7_2实现的功能与工程ex7_1完全相同,即实现按秒从00计数到99,继而循环计数的功能。通过本节实例的学习,读者应掌握了S3C2410A的中断处理方法。7.2K9F1208访问技术
我们在前面第二章的2.4节介绍了K9F1208U0C的特性、管脚结构及电路接口原理图,关于K9F1208U0C更详细的信息请参考K9F1208芯片手册。为了便于理解如何访问K9F1208,本节将摘录部分K9F1208芯片资料的内容。
7.2.1K9F1208U0C
K9F1208U0C的存储阵列如图7-3所示。图7-3K9F1208U0C存储阵列由图7-3可知,一片K9F1208U0C芯片包含4096个存储块,每个存储块分为32个存储页,每个存储页为528字节。其中,512字节用于存储数据,16字节用于存储校验信息。这样,一片K9F1208U0C的存储空间大小为4096×32×(512+16)B=
(64+2)MB=66 MB,其中,1 MB=1024 KB,1 KB=1024 B。用户可用的存储空间为64 MB,对其完全寻址,至少需要26根地址线。I/O0~I/O7作为地址输入时至少占用4个周期,每个周期的地址输入如图7-3所示:第一个周期输入的A0~A7作为列地址;第2~4周期输入的A9~A25作为行地址,即页地址,因此,一片K9F1208U0C有217=128 K个存储页面。每个512 B的页面由A8分为上、下两部分(Read1命令),每部分为256个字节,可以被8位列地址寻址,即A0~A7寻址。每个存储页最后的16字节(512~527)使用A0~A3寻址,A4~A7忽略,对应于不同的访问命令(Read2命令)。现在,有充分理由相信,NAND型FLASH这种“分而治之”的存储寻址方式比NOR型FLASH的“一统天下”方式在芯片制造上更容易实现。
K9F1208U0C共有4个存储柱面(Plane),它的4096个存储块分布在不同的存储柱面上,不同的存储柱面可以同时读写。块序号被4整除的存储块,例如块0,4,8,…,4092位于面0上;而块序号除以4余1的存储块,例如块1,5,9,…,4093位于面1上;块2,6,10,…,4094位于面2上;块3,7,11,…,4095位于面3上。如图7-4所示,每个柱面上有528字节的数据寄存器,位于存储单元阵列和外部I/O口之间,用于缓冲读写的数据。图7-4存储器配置表由附录一的附表1-1可知,NAND型FLASH操作寄存器位于0x4E000000~0x4E000014。由第二章的图2-14和图2-16可知,K9F1208U0C的I/O0~I/O7接S3C2410A的D0~D7,其控制管脚接S3C2410A的NANDFLASH控制器的相应管脚。
通过S3C2410A访问K9F1208的一般步骤为:
(1)初始化S3C2410ANAND型FLASH控制器。
(2)读K9F1208的芯片ID号。
(3)整片擦除K9F1208,然后对K9F1208的存储块进行有效性检验,对无效存储块进行标记。
(4)编程K9F1208芯片,并读取写入的数据进行ECC校验。
K9F1208仅支持基于块的擦除和基于页的编程,针对FLASH来说,编程是指向其中写入数据。由于S3C2410A具有硬件ECC校验发生器,用户不需要编写ECC校验码产生函数。
下面两个小节将分别介绍K9F1208的读和编程操作方法。7.2.2K9F1208读设计
K9F1208的读操作需要初始化S3C2410A的NANDFLASH控制寄存器,方法如下:
//InitNANDControllerReg
voidinitFlash()
{
INTMSK=0xFFFFFFFF;
CLKCON=0x0007FFF0; //bit4
GPACON=0xFFFFFFFF;
NFCONF=(1<<15)|(1<<12)|(0<<11)|(7<<8)|(7<<4)|(7<<0);
while(!(NFSTAT&0x01));
NFCMD=0xFF; //ResetNAND
while(!(NFSTAT&0x01));
}
即关闭中断,开启NANDFLASH控制器时钟,启动NANDFLASH控制器管脚,配置NFCONF寄存器,等待K9F1208是否准备好,向K9F1208写命令字0xFF复位FLASH。
初始化NANDFLASH控制器之后,读取K9F1208的ID号,方法如下:
//ReadflashID
voidreadFlashID()
{
inti;
NFCMD=0x90;
NFADDR=0x0;
for(i=0;i<4;i++)
{
flashID=flashID|(NFDATA<<((3-i)*8));
while(!(NFSTAT&0x01));//Ready?
}
}即写命令字节0x90和地址字节0x0,然后依次读出4个字节,即为K9F1208的ID号。这里K9F1208U0C读出来的ID号为:0xEC765A3F。
然后,可以读取NANDFLASH的内容了。一般编写一个读FLASH函数,输入参量为读FLASH的起始地址、读取的字节长度和存放读出内容的数组,代码如下:
//Readflashcontents
//Here,addr:startaddress;size:Pagesize;buf:data
voidflashRd(unsignedintaddr,unsignedintsize,unsignedchar*buf)
{ inti,n=1;
while(!(NFSTAT&0x01));
NFCMD=0x00|((addr>>8)&0x01);
NFADDR=addr&0xFF;
NFADDR=(addr>>9)&0xFF;
NFADDR=(addr>>17)&0xFF;
NFADDR=(addr>>25)&0x01;
while(!(NFSTAT&0x01));
for(i=0;i<size;i++,n++)
{
*buf++=NFDATA;
if((n%528)==0) //onepagereadover,wait
{
while(!(NFSTAT&0x01));
}
}
while(i%528)//Readtheentirepage
{
NFDATA;
i++;
}
while(!(NFSTAT&0x01));
}上述代码首先等待FLASH准备好,然后,写命令0x00或0x01(当输入地址addr的第8位为1时),将地址按图7-4分成4个字节从低位至高位依次写入。由于NANDFLASH的读按528字节的页为单位,因此,如果输入的读取长度大于528时,读完一页后需要等待FLASH再次准备好;如果读取长度不是528的整倍数时,需要读完整页,但是读出的数据不用保存。
在工程ex7_2的基础上新建工程ex7_3,其工作界面如图
7-5所示。图7-5工程ex7_3的工作界面如图7-5,工程ex7_3包括三个文件:S3C2410A.s、cvectaddr.s和flashRW.c,其中,S3C2410A.s和cvectaddr.s与工程ex7_2中的同名文件代码相同;flashRW.c的代码清单如下:
1//NANDFLASHControllerRegistersAddr.
2#defineNFCONF
(*(volatileunsignedint*)
0x4E000000)
3#defineNFCMD
(*(volatileunsignedint*)
0x4E000004)
4#defineNFADDR (*(volatileunsignedint*)
0x4E000008)
5#defineNFDATA (*(volatileunsignedint*)
0x4E00000C)
6#defineNFSTAT (*(volatileunsignedint*)
0x4E000010)
7#defineNFECC (*(volatileunsignedint*)
0x4E000014)
8
9#defineCLKCON(*(volatileunsignedlong*)
(0x4C00000C))
10
11#defineINTMSK(*(volatileunsignedlong*)
(0x4A000008))
12
13#defineGPACON (*(volatileunsignedlong*)
(0x56000000))
14
15externvoidopenTimer1(void);
16
17externvoidc_Timer1_ISR(void);
18
19voidinitTimer1(void);
20
21//Flashoperator
22voidinitFlash(void);
23voidreadFlashID(void);
24voidflashRd(unsignedintaddr,unsignedintsize,
unsignedchar*buf);
25unsignedintflashID=0;
26unsignedcharflashWhat[3000];
27unsignedcharflashDat[3000];
28
29intmain()
30{
31inti,n=0;
32 //initializeNANDController
33 initFlash();
34 readFlashID();
35 flashRd(0,3000,flashWhat);
36 //Flashdata,except16Bper528
37 for(i=0;i<3000;i++)
38 {
39n=i/528;
40 if((i>=n*528)&&(i<n*528+512))
41 {
42 flashDat[i-n*16]=flashWhat[i];
43 }
44 }
45 //AboveisNandFlashoperator
46
47//0x010FFF20+11*4istheaddressofTimer1jumper
48*(volatileunsignedint*)(0x010FFF20+4*11)
=(unsigned)c_Timer1_ISR;
49 //initializeTimer1
50 initTimer1();
51 //EnableTimer1Interrupter
52 openTimer1();
53
54 while(1)
55 {
56
57 }
58}
59
60//InitNANDControllerReg
61voidinitFlash()
62{
63INTMSK=0xFFFFFFFF;
64CLKCON=0x0007FFF0; //bit4
65GPACON=0xFFFFFFFF;
66
67NFCONF=(1<<15)|(1<<12)|(0<<11)|(7<<8)|
(7<<4)|(7<<0);
68
69while(!(NFSTAT&0x01));
70NFCMD=0xFF; //ResetNAND
71while(!(NFSTAT&0x01));
72
73}
74
75//ReadflashID
76voidreadFlashID()
77{
78 inti;
79 NFCMD=0x90;
80 NFADDR=0x0;
81 for(i=0;i<4;i++)
82 {
83 flashID=flashID|(NFDATA<<((3-i)*8));
84 while(!(NFSTAT&0x01));//Ready?
85 }
86}
87
88//Readflashcontents
89//Here,addr:startaddress;size:Pagesize;buf:data
90voidflashRd(unsignedintaddr,unsignedintsize,
unsignedchar*buf)
91{
92 inti,n=1;
93 while(!(NFSTAT&0x01));
94 NFCMD=0x00|((addr>>8)&0x01);
95 NFADDR=addr&0xFF;
96 NFADDR=(addr>>9)&0xFF;
97 NFADDR=(addr>>17)&0xFF;
98 NFADDR=(addr>>25)&0x01;
99 while(!(NFSTAT&0x01));
100 for(i=0;i<size;i++,n++)
101 {
102 *buf++=NFDATA;
103 if((n%528)==0)//onepagereadover,wait
104 {
105 while(!(NFSTAT&0x01));
106 }
107 }
108 while(i%528)//Readtheentirepage
109 {
110 NFDATA;
111 i++;
112 }
113 while(!(NFSTAT&0x01));
114}
上述代码的第25~27行定义了变量和数组,用于存放从K9F1208中读取的ID号和长度为3000字节的内容。第33行初始化NANDFLASH控制器,第34行读取FLASH的ID号。第35行从FLASH中读取长度为3000字节的数据,第37至44行把读出的3000字节长度的数据中每528个字节去掉最后的16个字节。注意:这里读出的3000个字节首地址为0;如果首地址不为0,则需要修改第37~44行的代码,例如,首地址为5,则循环内第39行和第40中的变量i应变为i+5。
通过编译连接,下载并调试程序可查得,flashWhat的地址为0x01000020,flashDat的地址为0x01000BD8,从Memory中可查看地址0x0、0x01000020和0x01000BD8三个地址的内容,可知,0x0~0xA08和0x01000BD8~0x010015E0的内容完全相同(后面的内容均为FF);而0x01000020每528个字节会出现16个字节的内容是多余的(这些字节读自NANDFLASH的校验区)。7.2.3K9F1208Boot设计
K9F1208Boot设计是指将可执行代码文件(Hex文件)通过ULINK2在线下载到K9F1208中,然后,取下ULINK2,系统执行K9F1208中的代码。通过ULINK2下载可执行代码到NANDFLASH中。有两种方法:其一,为借助MDK的菜单“FLASH|Download”实现,这种方法在前面被多次使用,用于直接下载当前工程文件的可执行代码(扩展名为.axf的文件);其二,为本节将介绍的方法,即编写一个下载工程,用于将Hex格式的文件写入到K9F1208中,可以下载任意MDK生成的工程可执行代码文件(以.hex为扩展名)。在介绍这个专用下载工程之前,需要介绍一下MDK生成的Hex文件的格式。
1.Hex文件格式
打开工程ex7_2所在的目录,可以找到文件ex7_2.hex,用UltraEdit或文本编辑器可以打开该文件,如下:
1:0400000500000000F7
2:020000040000FA
3:100000003CF09FE53CF09FE53CF09FE53CF09FE530
4:100010003CF09FE50000A0E13CF09FE53CF09FE54F
5:1000200004D04DE200032DE9B8919FE5009099E5D9
6:10003000B4819FE5098188E0008098E508808DE51E
7:100040000083BDE8040100006400000068000000B7
8:100050006C00000070000000000000007400000050
9:1000600078000000FEFFFFEAFEFFFFEAFEFFFFEA66
10:10007000FEFFFFEAE9FFFFEAFEFFFFEA101111228F
11:100080000007000000070000000700000007000054
12:10009000000700000007000009800100098001003E
13:1000A0005904AC00B1000000200000002000000056
14:1000B000FFFFFF0003000000118005002380070000
15:1000C00004000000F0FF0700FF030000FF0700002E
16:1000D00000000000AA56AAAA0000000000000000CC
17:1000E0000000000000000000000000001A5900009D
18:1000F000000000000000000000000000FF070000FA
19:10010000000000005304A0E3E0109FE5E0209FE51D
20:10011000082080E5042080E5001080E51303A0E3BB
21:1001200078804FE27E0098E8001080E5142080E59A
22:10013000043080E5084080E5105080E50C6080E5E3
23:10014000CCE04FE2FF1F9EE812E3A0E3FF1F8EE822
24:1001500056E4A0E388004FE2002090E5041090E50B
25:1001600020208EE528108EE50000A0E30312A0E316
26:100170000136A0E30400B0E80400A1E8013043E246
27:10018000000053E3FAFFFFCA0302A0E3100F0DEED5
28:10019000101F1DEE5C009FE5DBF021E300D0A0E125
29:1001A000000040E2D7F021E300D0A0E1000040E2EF
30:1001B000D1F021E300D0A0E1000040E2D2F021E341
31:1001C00000D0A0E1800040E2D3F021E300D0A0E124
32:1001D000080040E210F021E300D0A0E101AB4DE2C5
33:1001E00014009FE510FF2FE11400004A20FF0F01CB
34:1001F0003C7C0000B80B0000080500010002000074
35:10020000000000EBE50000EB2C008FE2000C90E812
36:1002100000A08AE000B08BE001704AE20B005AE1D6
37:100220000000001ADD0000EB0F00BAE818E04FE212
38:10023000010013E303F0471003F0A0E1AC05000058
39:10024000BC050000102052E27800B0287800A128F8
40:10025000FBFFFF8A822EB0E13000B0283000A128D9
41:1002600000409045004081450EF0A0E104309FE53C
42:1002700003308FE003F0A0E1480500000C009FE58B
43:100280000C109FE504209FE508309FE51EFF2FE13D
44:1002900080000001800400018000000114009FE53F
45:1002A00014109FE510402DE94C0F81E5030000EB91
46:1002B000100000EBFEFFFFEA1C03000000F00F013E
47:1002C0009510A0E35104A0E3001080E53010A0E3F6
48:1002D000041080E500119FE5181080E50119A0E3E6
49:1002E0001C1080E50A1CA0E3081080E5091CA0E3AF
50:1002F000081080E51EFF2FE10010A0E34A04A0E3F0
51:10030000041080E5082090E57F10A0E3022BC2E3F3
52:10031000082080E50C1080E51EFF2FE13F502DE9FD
53:100320004A04A0E3001090E5021BA0E3001080E562
54:10033000102090E5101080E5A0409FE50010A0E39C
55:10034000041084E5000094E5000050E3C020A00301
56:100350000500000A010050E3A020A0030200000AEB
57:10036000020050E30100001A6020A0E3042084E5AD
58:10037000010080E2020050E3000084E5001084C523
59:10038000040094E55624A0E3240082E5080094E5E7
60:10039000640050E3081084A5080094E50A10A0E367
61:1003A0000050A0E10F0000EB34209FE50030D2E7C1
62:1003B0000203A0E31031C0E50110D2E71211C0E53D
63:1003C000010085E2080084E500000FE18000C0E341
64:1003D00000F021E13F50BDE804F05EE21F4E000056
65:1003E000000000010C00000101C090E12100004A62
66:1003F0000020A0E3A0C071E01A00003A20C271E022
67:100400000F00003A20C471E00100003A0030A0E380
68:10041000200000EAA0C371E0810340200220A2E096
69:1004200020C371E0010340200220A2E0A0C271E0DD
70:10043000810240200220A2E020C271E0010240209F
71:100440000220A2E0A0C171E0810140200220A2E0D0
72:1004500020C171E0010140200220B2E0A0C071E0A3
73:10046000810040200220A2E0011050E00010A031E5
74:100470000200A2E00EF0A0E1022111E200106142B0
75:10048000403032E00000602220C271E01D00003ADE
76:1004900020C471E00F00003A0113A0E120C471E014
77:1004A0003F2382E30B00003A0113A0E120C471E076
78:1004B0003F2682E30700003A0113A0E120C471E067
79:1004C0003F2982E30113A0213F2C822300C071E267
80:1004D0001D00002A2113A021A0C371E08103402048
81:1004E0000220A2E020C371E0010340200220A2E02C
82:1004F000A0C271E0810240200220A2E020C271E08F
83:10050000010240200220A2E0A0C171E08101402050
84:100510000220A2E020C171E0010140200220B2E0EF
85:10052000EBFFFF2AA0C071E0810040200220A2E082
86:10053000011050E00010A0310200A2E0C33FB0E182
87:1005400000006042001061220EF0A0E1C33FB0E164
88:100550000000604201402DE90000A0E30000A0E19E
89:100560000280BDE80EF0A0E10E40A0E11D0000EB0E
90:1005700004E0A0E10D402DE9320000EB0040B0E1C5
91:100580000D40BDE80210B0E10EF0A0E10020B0E1A6
92:1005900010402DE90000B0E30000A0E11080BDE8AC
93:1005A0000000A0E1EFFFFFEB03002DE9780000EB76
94:1005B0000300BDE8340000EB0F002DE9770000EBED
95:1005C0000F00BDE834FFFFEB2B0000EB01402DE9ED
96:1005D0000000A0E1680000EB0140BDE8000000EB76
97:1005E0000000E0E31B0000EB0E50A0E11F0000EB59
98:1005F00005E0A0E10050B0E10D10A0E10A30A0E15B
99:100600000700C0E300D0A0E160D08DE220402DE9DA
100:1006100019FFFFEB2040BDE80060A0E30070A0E3FD
101:100620000080A0E300B0A0E30710C1E305C0A0E193
102:10063000C009ACE8C009ACE8C009ACE8C009ACE846
103:1006400001D0A0E10EF0A0E104009FE50EF0A0E1D2
104:100650000EF0A0E12C0000010C109FE51800A0E3B3
105:10066000563412EF0EF0A0E1440100002600020013
106:1006700000009FE50EF0A0E11C0000010040A0E199
107:100680000000A0E10400A0E1CFFFFFEBC0432DE993
108:100690003E002DE90040A0E10150A0E14C0000EB3C
109:1006A00000408DE50000A0E304508DE50000A0E1CE
110:1006B00008008DE500008DE2EBFEFFEB0040A0E1BD
111:1006C0000150A0E103009DE80270A0E10360A0E1F9
112:1006D0000000A0E10000A0E10000A0E10010A0E304
113:1006E0000100A0E10000A0E10080A0E12F0000EBEC
114:1006F0000010A0E3008080E50090A0E10100A0E1EF
115:100700000000A0E1011080E2041089E50010A0E3E0
116:100710000100A0E10000A0E10010A0E3080089E5CD
117:100720000100A0E10000A0E10010A0E30C0089E5B9
118:100730000100A0E10000A0E1100089E50000A0E1B7
119:100740000000A0E10000A0E10000A0E10000A0E1A5
120:100750000000A0E10000A0E10000A0E10000A0E195
121:100760000CD08DE20400A0E10510A0E10720A0E17B
122:100770000630A0E1F001BDE80082BDE810402DE99F
123:100780000000A0E30000A0E10000A0E10000A0E163
124:100790001080BDE80000E0E30210E0E30EF0A0E10D
125:1007A00010402DE90000A0E11080BDE80EF0A0E1AE
126:1007B00004009FE50EF0A0E10EF0A0E13C00000176
127:1007C0000EF0A0E104009FE50EF0A0E10EF0A0E124
128:1007D0002000000110402DE9F9FFFFEB0010A0E31D
129:1007E000001080E51080BDE8F8070000000000015F
130:1007F0001C00000044020000000000000000000097
131:1008000000000000C0F9A4B0999282F8809088831B
132:04081000C6A1868E69
133:00000001FF
其中,行号是作者添加的。每行均以“:”开头,其结构样式
如下:
:[AA][BBBB][CC][DD...DD][EE]
例如,对于第4行“:100010003CF09FE50000A0E13CF09FE53CF09FE54F”,
这里,
AA=10,表示该行有0x10(即16)个数据。
BBBB=0010,表示该行16个数据存入FLASH中的首地址为0x0010。
CC=00,表示该行中DD…DD位置处的数据类型,00表示写入到FLASH中的数据;如果CC=01,表示Hex文件的结尾,如第133行;CC=04表示数据为32位地址的高16位地址偏置,如第2行;CC=05,表示写入地址的32位基地址,如第1行。
DD…DD为3CF09FE50000A0E13CF09FE53CF09FE5,为该行中的数据。
EE=4F表示该行所有字节数据的加校验和,满足
0x10+0x00+0x10+0x00+0x3C+…+0xE5+0x4F
=0x00(只保留低8位)从第1行可知,32位基地址为0x00000000,从第2行知,高16位地址基址为0x0000,而第3行的16位地址为0x0000,即第3行的字节数据“3CF09FE53CF09FE53CF09FE53CF09FE5”写入FLASH的首地址为“基地址+高16位地址:16位地址”,即为0x00000000;如果基地址为0x00000000,高16位地址基址为0x0010,则此处的首地址为0x00100000。因此,第1行16个数据依次写入FLASH的地址0x0~0xF。同理,第2行数据依次写入地址0x10~0x1F,依次类推。第132行字节数据只有0x04个,即“C6A1868E”,将被写入FLASH地址0x0810~0x0813。第133行中AA=00且CC=01表示该行为Hex文件的结尾。根据上面的介绍,把ex7_2.hex转化为如下的头文件flash.h,即建立一个无符号字符数组FlashDat存放写入FLASH中的所有字节数据,建立一个整型常量iDatN存放数组FlashDat的长度。flash.h代码如下:
1unsignedcharFlashDat[2068]={
20x3C,0xF0,0x9F,0xE5,0x3C,0xF0,0x9F,0xE5,0x3C,
0xF0,0x9F,0xE5,0x3C,0xF0,0x9F,0xE5,
30x3C,0xF0,0x9F,0xE5,0x00,0x00,0xA0,0xE1,0x3C,
0xF0,0x9F,0xE5,0x3C,0xF0,0x9F,0xE5,
40x04,0xD0,0x4D,0xE2,0x00,0x03,0x2D,0xE9,0xB8,
0x91,0x9F,0xE5,0x00,0x90,0x99,0xE5,
50xB4,0x81,0x9F,0xE5,0x09,0x81,0x88,0xE0,0x00,
0x80,0x98,0xE5,0x08,0x80,0x8D,0xE5,
60x00,0x83,0xBD,0xE8,0x04,0x01,0x00,0x00,0x64,
0x00,0x00,0x00,0x68,0x00,0x00,0x00,
70x6C,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x74,0x00,0x00,0x00,
80x78,0x00,0x00,0x00,0xFE,0xFF,0xFF,0xEA,0xFE,0xFF,
0xFF,0xEA,0xFE,0xFF,0xFF,0xEA,
90xFE,0xFF,0xFF,0xEA,0xE9,0xFF,0xFF,0xEA,0xFE,
0xFF,0xFF,0xEA,0x10,0x11,0x11,0x22,
100x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
0x07,0x00,0x00,0x00,0x07,0x00,0x00,
110x00,0x07,0x00,0x00,0x00,0x07,0x00,0x00,0x09
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五版医疗废弃物无害化处理合同3篇
- 2025年度出租车行业规范管理承包协议4篇
- 2025年度个人无息借款合同样本针对各类借款需求4篇
- 2025年度电商跨境支付解决方案合作协议3篇
- 2025年度城市景观带除草与照明工程承包书4篇
- 2025年度电商物流配送服务合同范本12篇
- 智能化施工技术-第2篇-深度研究
- 2025年度家庭园艺设计与家政服务合同范本4篇
- 2025年度拟上公司与会计事务所财务数据安全保密合同4篇
- 二零二五年度商业橱柜销售代理合同模板2篇
- 《电力用直流电源系统蓄电池组远程充放电技术规范》
- 《哪吒之魔童降世》中的哪吒形象分析
- 信息化运维服务信息化运维方案
- 汽车修理厂员工守则
- 六年级上册数学应用题100题
- 个人代卖协议
- 公安交通管理行政处罚决定书式样
- 10.《运动技能学习与控制》李强
- 冀教版数学七年级下册综合训练100题含答案
- 1神经外科分级护理制度
- 场馆恶劣天气处置应急预案
评论
0/150
提交评论