




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、ARM C语言,2,一、文件包含伪指令,#include #include “头文件名.h” #include 宏标识符,3,#include ,#include #include ,4,2#include “头文件名.h”,#include “2410lib.h” #include “2410b.h” #include “./LCD/lcd_test.h” #include “.LCDlcd_tmp.h”,5,3#include 宏标识符,#define LCDINCLUDE “c:/2410s/examble/lcd_def.h” #include LCDINCLUDE 展开后: #inc
2、lude “c:/2410s/examble/lcd_def.h”,6,二#define 宏标识符 宏体,#define LED8ADDR (*(volatile unsigned char *) (0 x2140000) void Digit_Led_Symbol(int value) if(value=0) /* 预处理器将LED8ADDR 替换为地址0 x2140000的内存单元*/ ,7,#include / ARM 2410S的LED程序 #include #include /ZLG7290 addr, take the addr as the cmd in the ioctl to
3、o. #define ZLG7290_ADDR_FlashOnOff 0 x0c #define ZLG7290_ADDR_ScanNum0 x0d #define ZLG7290_ADDR_DpRam00 x10 #define ZLG7290_ADDR_DpRamBaseZLG7290_ADDR_DpRam0 #define ZLG7290_ADDR_DpRam1 (ZLG7290_ADDR_DpRamBase+0 x01) #define ZLG7290_ADDR_DpRam2 (ZLG7290_ADDR_DpRamBase+0 x02) #define ZLG7290_ADDR_DpR
4、am3 (ZLG7290_ADDR_DpRamBase+0 x03) #define ZLG7290_ADDR_DpRam4 (ZLG7290_ADDR_DpRamBase+0 x04) #define ZLG7290_ADDR_DpRam5 (ZLG7290_ADDR_DpRamBase+0 x05) #define ZLG7290_ADDR_DpRam6 (ZLG7290_ADDR_DpRamBase+0 x06) #define ZLG7290_ADDR_DpRam7 (ZLG7290_ADDR_DpRamBase+0 x07) #define ZLG7290LED_DEV /dev/i
5、2c/zlg7290/0,8,static int fd = -1; #define DEBUG #ifdef DEBUG #define DPRINTF(x.)printf(Debug:#x) #else #define DPRINTF(x.) #endif struct LED_REG unsigned char addr;/寄存器接口方式 unsigned char ctrl; _attribute_ (packed) ; struct LED_MAP char map;/显示内容 unsigned char raw;/映射段码 ;,9,struct LED_MAP ledmap = 0
6、, 0 xfc, 1, 0 x60, 2, 0 xda, 3, 0 xf2, 4, 0 x66, 5, 0 xb6, 6, 0 xbe, 7, 0 xe0, 8, 0 xff, 9, 0 xfb, ; unsigned char led_map_table128; unsigned char led_map(char map); int led_clear(int fd, unsigned char addr); #define CYCLE_LEFT(1) #define CYCLE_RIGHT(2),10,三函数及函数库,函数的定义格式 函数的原型说明格式,11,函数的定义格式,存储类说明符
7、类型说明符修饰符标识符(参数表)函数体 存储类说明符:static和extern 类型说明符:void、char 修饰符:interrupt、near、far、huge 标识符:函数名、*函数名、(*函数名)、*(*函数名),12,)存储类说明符,static 表示在本文件定义前和非本函数定义文件中,该函数将不能使用。提高了函数的安全性。 extern 在C中,函数是全局的,全程序可见。但在该函数定义之前调用该函数时,需要加原型说明;而且在多源文件的程序中,非定义该函数的文件中需要调用该函数时,必须在原型说明中使用extern。,13,2)类型说明符,简单类型 int、char、float l
8、ong double等。 复合类型 struct、union 指针类型 无类型 void,14,3)参数表,类型说明符 变量名 void 空,15,4)修饰符对函数起修饰作用,interrupt 将函数修饰为中断函数。中断函数的特点是返回值类型和参数均必须为void。经interrupt修饰的函数,编程时只需要编写中断服务程序的主体部分,中断服务的保护现场前缀段和恢复现场的后缀段,均由编译程序完成。另外,编译程序还把ret指令改为reti指令。 near、far、huge 规定函数的地址类型。覆盖存储模式规定的函数缺省地址类型,指明函数与被调用函数的距离。near为近调用(16位段内地址);f
9、ar为远调用(32位段间地址);huge为规范化远调用(32位段间规范地址)。,16,2函数的原型说明格式,存储类说明符类型说明符修饰符标识符(参数表)函数体; int led_clear(int fd, unsigned char addr); int led_clear(int , unsigned char); int led_cycle(int fd, int direction); int led_cycle(int , int);,17,int led_cycle(int fd, int direction); struct LED_REG reg8; int main(int a
10、rgc, char* argv) int i,j,k; if(fd=open(ZLG7290LED_DEV, O_RDWR)0) printf(Error opening %s ZLG7290 devicen, ZLG7290LED_DEV); return 1; led_map_init();/led 段码映射 for(i=0; i=7; i+) /clear all leds led_clear(fd, ZLG7290_ADDR_DpRam0+i); for(i=0; i=7; i+) regi.addr=ZLG7290_ADDR_DpRam0+i; regi.ctrl=led_map(0
11、+i);/设定LED显存内容 write(fd, ,18,int led_map_init() int i; for(i=0;isizeof(ledmap)/sizeof(ledmap0);i+) led_map_tableledmapi.map=ledmapi.raw; return 0; unsigned char led_map(char map) return led_map_tablemap; int led_clear(int fd, unsigned char addr) struct LED_REG reg; reg.addr=addr; reg.ctrl=0; ioctl(f
12、d, reg.addr, reg.ctrl); ,19,int led_cycle(int fd, int direction) /led 左右移位函数 struct LED_REG temp, * preg; int i; preg= ,20,四变量修饰符,const volatile near、far,21,1 const,常量修饰符,指示被修饰的变量或指针变量是常量。在C语言中,单独开辟一个常量区域用于存放const变量。被修饰的变量必须被赋予初值,变量一旦被const修饰后值就不能再改变了。如: const int x20; x50; /错误被赋值 指针的修饰有下列两种方式,含义是不同
13、的。 const int *ptr=/指针常量,说明指针本身是常量,22,2volatile易变的、反复无常的(性格),易失性修饰符。所定义的变量或指针变量是可以被多种原因修改的(如可以在中断服务程序中被修改,会被I/O口修改),这种修改是随机的。因此使用volatile修饰符禁止对该变量的任何形式的优化,禁止该变量作为寄存器变量。防止它被随机改变。 编译器有一种技术是数据流分析,分析程序中的变量在哪里赋值,在哪里使用,在哪里失效。分析结果可以用于常量合并、常量传播等优化。当它判定你的代码没有修改变量的值时,它就可能提供上次访问变量时提供的缓存值,以提高程序的效率。但有时这种优化会带来问题,特
14、别是对于硬件寄存器操作的程序,此时可以使用volatail关键词禁止做这些优化。,23,int nn,mm,which_int which_int=rEXTENTPND; nn=which_int; which_int=rEXTENTPND; mm=which_int; 但这样的优化结果可能导致错误。rEXTENTPND寄存器的内容在执行第1次读操作后可能会被外部中断写入新值,那么第2次读操作读出的内容与第1次的不同,变量mm和nn的值就会不同。但优化后的代码中mm和nn是肯定相同的。因此可以使用volatile来防止优化。正确的写法为: volatile int which_int;,左边的
15、代码会被优化为: int nn,mm,which_int which_int=rEXTENTPND; nn=which_int; mm=which_int;,24,volatile的作用,不会在两个操作之间把volatile变量缓存在寄存器中。在多任务、中断处理程序中,变量可能被其他程序改变,编译器自己无法知道。volatile就是告诉编译器不要优化,不要使用缓存值。 不做常量合并、常量传播等优化,所以下面的代码: volatile int i=1; if(i0)printf(“d”,i); if的条件不会当做无条件真。因为变量i被说明为volatile类型就是说该变量可能会被意想不到随时改变
16、。 对volatile变量的读写不会被优化掉。如果一个变量赋值后但后面没有用到,编译器常常可以忽略那个赋值操作,然而对有些硬件寄存器的处理是不能这样优化的。,25,使用volatile变量的场合,硬件寄存器通常要加volatile,因为每次对它的读写都可能有不同的意义。如下列为中断屏蔽寄存器的定义: #define rINTMSK (*(volatile unsigned *)0 x1e0000c) 在中断服务程序中修改的其他程序检测的变量需要加volatile。如: volatile int which_int; 多任务环境下各任务间共享的标志应该加volatile。在多线程访问某变量时,希
17、望这些访问能读到变量的最新值,同时写到变量的操作能够立即实现。声明字段的时候如果加上了volatile,那么对该字段的任何请求,包括读和写操作,都会立刻得到执行。,26,五_ _irq,为了方便使用高级语言编写异常处理函数,ARM编译器对异常处理函数作了特定扩展,只要使用关键词_irq,编译出来的函数就满足异常响应对现场保护和恢复的需要。,27,六访问绝对地址的内存位置,对于定义 #define pISR_EINT4567 (*(unsigned*)(_ISR_STARTADDRESS+0 x74) 把无符号数“_ISR_STARTADDRESS+0 x74”强制转换为指针,指向RAM中的地址
18、空间,可以用下面的方法访问它。 pISR_EINT4567(int)Eint4567ISR; 为了访问一个绝对地址,把一个整型数强制转换(typecast)为一个指针就可以了。,28,编写中断服务程序的基本原则,避免在中断服务中做浮点运算。编写中断服务程序应该遵循短而有效(SS,Simple and Short)的原则。若在中断服务程序中做浮点运算严重违背这一原则,有些处理器/编译器不允许在中断服务程序中做浮点运算。 中断服务程序不能有返回值,所以中断服务程序的返回值类型都是void。 中断服务程序不能传递参数,所以中断服务程序的参数列表void。 void _irqEint4567Isr(void),29,七定义变量时的技巧,char a; short b; char c; int d;,char a; char c; short b; int d;,说明:pad为无效数据。,30,八使用循环时的技巧,int fact1(int n) float ti=1; for(i=1;in;i+) ti=fact*i ,int fact2(int n) float ti=1; for(i=n;i!=0;i-) ti=fact*i ,Fact1: 0 x000010: MUL
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论