《ARM原理与C程序设计》课件第七章_第1页
《ARM原理与C程序设计》课件第七章_第2页
《ARM原理与C程序设计》课件第七章_第3页
《ARM原理与C程序设计》课件第七章_第4页
《ARM原理与C程序设计》课件第七章_第5页
已阅读5页,还剩168页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第七章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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论