title
收藏本站
联系站长
关于本站
首页 信息发布 产品宣传 论坛交流 学习文章 技术人生 项目源码 技术资料 人才收录
 今天是: 2010年7月10日 星期 六
欢迎光临!单片机群号:25930265(新) 71062262 21829895 64584393 26583231(只限加一群)  
热门文章推荐


当前位置:首页>>>单片机学习文章>> AVR单片机ICCAVR应用的一些小技巧
AVR单片机ICCAVR应用的一些小技巧
作者:md9给他留言 [转载] 字体:
发表于:
2009-07-18 21:16:58
1.在汇编里面位造作用  SEI  PORTA  3,把PORTA的第三位置1 , 
在C里面,可以用&与|表达: 
PORTA=PORTA|0x08,  简写为PORTA|=(0x08);   
PORTA=PORTB&(0xF7) 简写为PORTA&=0xF7 
以上是对寄存器的某一位操作,当然也可以同时操作几个位, |0x0F ,则低四位置1; 
在很多地方,如ATMEL的文档里我们会看到像TCCR1A|=(1<<COM1A0);//A比较匹配, 
这样的操作,这是怎么回事呢?    
首先要知道<<  ,>>的意思,这是左移,右移操作,(A<<3)是把A的二进制数向左移3位,即乘以2的三次方. 
COM1A0是TCCR1A的第6位,这是ATMEL给TCCR1A寄存器第6位取的名字,  在ICCAVR编译器的头文件iom16v.h里可以找到这样的定义"#define OCR1A0   6"  ,所以TCCR1A|=(1<<OCR1A0)的意思是把TCCR1A寄存器的第6位置1, 如果TCCR1A|=(1<<OCR1A0)|(1<<WGM10),那么WGM10同时也被置1; 
而TCCR1A&=~(1<<OCR1A0)把第6位清零.  之所以我们要这样写而不写作TCCR1A|=0x40我想一是便于记忆,只记每一位的名字,不记在哪位,这样不容易错,便于对照DATAsheet检查程序.此外还更好移植,从一个系列的一个单片机到另一个单片机,只要控制某功能的位的名字不变,例如OCR1A0不管在哪个位置,此语句都实现OCR1A0置一的功能. 
以上是某一个或几个位置一或清零操作,当然可以直接赋值,例如PORTA=0X0F,则是把低四位置1,高四位清零,这样看起来最简单但是对于我们想要改变某些位而不影响其它位的场合是不行的,例如1602液晶操作E和RS,还有数据等等,有严格的时间顺序,彼此要独立,按4data线统统接到PORTA,则无法用=直接赋值. 

2.ICCAVR 的macros.h里定义了一些有用的宏,如SEI(),其实是"asm("SEI") ",   此外还有CLI(),NOP()  等等,大家可以去看看,顺便说说,ICCAVR嵌入汇编的格式是asm("汇编指令"); 
C 里面我们把一些宏定义,函数的声明等写到.h头文件,而.c则是函数具体实现,当程序比较大时可以把一般函数和main函数分开,一起ADD到Project里面,便于管理.  
3.ICCAVR里面的中断用#pragma interrupt_handler INTTERRUPT_NAME:INTERRUPT_NUM,        INTERRUPT_NAME是自己取的中断函数名, 
INTERRPT_NUM是所选中断的中断号,在DATAsheet里有..在这之后就可以写自己的中断函数体了. 

4.在嵌入式的C程序编写里边,尽量少用float,double等等数据类型,可以用整数运算,到最后一步再除以10的多少次方得到所要的数.此外像sin,  log这样的高级函数,虽然C编译器自动给你生成,不想汇编那样自己用加减移位来编写,但是对于这样的函数,C编译器会比较大的代码,所以尽量少用.除法运算若被除数是2的次方,可以用移位操作代替. 
以上是我个人感觉写C时要注意的问题,希望对初写C的人有一些帮助 
(本文引自www.mcujl.com/article.asp?conID=404)


---------------------------------------------------------------------------------------------------
[打印文章] [关闭本页] [返回顶部]
本网站部分资料转自网上,如有侵权请来信告明,我们会尽快删除  | 网站地图
Copyright @ 2007-2010 深圳单片机交流网.版权所有
网站创办者:詹长亮,周发辉,李林盛
网站支持:zcl843@163.com QQ:380476830 13723787271詹长亮