[AVR单片机] 新手请教 AVR怎样实现位操作?

[复制链接]
8045|11
 楼主| luqiang6ch 发表于 2008-1-8 14:55 | 显示全部楼层 |阅读模式
请教各位大侠,在C51中这样的位操作
uchar bdata transdata;
sbit transbit7 = transdata^7;
sbit transbit6 = transdata^6;
sbit transbit5 = transdata^5;
sbit transbit4 = transdata^4;
sbit transbit3 = transdata^3;
sbit transbit2 = transdata^2;
sbit transbit1 = transdata^1;
sbit transbit0 = transdata^0;

在AVR中如何实现?
xwj 发表于 2008-1-8 15:16 | 显示全部楼层

用PORTA.5=1;这样的格式,但只能对地址小于$1F的寄存器使用

大于$1F的寄存器,AVR 芯片本身就不支持位操作,什么语言都一样,只能用操作RAM的方式来处理



CodeVisionAVR 像 BASCOM-AVR一样支持寄存器如 DDRB.5=1 这样的位操作语句. 

但是要注意的一点就是如下面的语句中:(假设ABCD是一个字符字节变量) 

 ABCD.5=1;  //CVAVR不支持变量的位的直接操作,BASCOM-AVR却支持 
 SPSR.5=1;  //SPSR的IO地址是$0E (小于$1F) 
 OCR2.5=1;  //OCR2的IO地址是$23 (大于$1F) 

第一句的注释已经说明清楚 

第二句由于SPSR的IO地址小于$1F,所以CVAVR支持这个寄存器的位的直接操作 

第三句由于OCR2的IO地址大于$1F,所以CVAVR不支持这个寄存器的位的直接操作 

所以,在CVAVR中如果想对寄存器的位进行操作,请先看一下芯片的数据手册,看看该寄存器的IO地址是否小于$1F 

同样 

 while(SPSR.5); 
 while(OCR2.5); 

上面的中第一句合法,第二句不能通过编译 

------------------------------------------------------- 
bit b1; //位变量必须是全局变量,不能是局部变量 



xwj 发表于 2008-1-8 15:18 | 显示全部楼层

几个位操作的小函数[引文]

AVR的位操作只能对地址小于$1F的寄存器使用 

大于$1F的寄存器,AVR 芯片本身就不支持位操作,什么语言都一样,只能用操作RAM的方式来处理 
 



几个位操作的小函数,经过了CVAVR的编译(其他编译器也是一样的),AVRStudio的模拟调试。结果是正确的,但运行时间约10uS,有兴趣的网友可以来交流。 
1 测试指定的位 
unsigned char BitTst(unsigned char *Pa,char b)  //Pa为被测试的对象的地址,b值为指定的位 

    return *Pa & (1<<b); 


用法: 
unsigned char x,y; 
    y=0x4F; 
    x=BitTst(&y,3); 

2 将指定的位置“1” 
void BitSet(unsigned char *Pa,char b)  //Pa为置位对象的地址,b值为指定的位 

    *Pa|=1<<b; 


用法:BitSet(&x,6); 

3 将指定的位清“0” 
void BitClr(unsigned char *Pa,char b)  //Pa为清零位对象的地址,b值为指定的位 

    *Pa&=~(1<<b); 


用法:BitClr(&x,6); 

4 将指定的位取反 
void BitCpl(unsigned char *Pa,char b)  //Pa为取反位对象的地址,b值为指定的位 

    *Pa^=1<<b; 


用法:BitCpl(&x,6); 
 
写成宏的方式吧,速度快点! 
#define BitSet(a,b)     (a |= (1<<b)) 
#define BitClr(a,b)     (a &= ~(1<<b)) 
 楼主| luqiang6ch 发表于 2008-1-8 15:41 | 显示全部楼层

非常感谢

jmpxwh 发表于 2008-1-14 15:25 | 显示全部楼层

非常感谢!

shalixi 发表于 2008-1-19 19:20 | 显示全部楼层
txh353012 发表于 2008-1-20 08:45 | 显示全部楼层

XWJ,就是高

我从手册上看到AVR不好位操作,
但是,经大师指点,茅塞顿开.
感谢.
学习
txh353012 发表于 2008-1-20 09:25 | 显示全部楼层

ICC 支持吗?

ICC 支持 地址小于$1F的寄存器用PORTA.5=1;这样的格式吗?
su_mj000 发表于 2008-1-20 09:33 | 显示全部楼层

任何CPU上都能实现位操作

区别只在效率上。如使用C/C++语言编程,这个问题基本可以忽略。

从理论上讲,CPU只要具有与、或、非三种功能,就能实现一切操作。
oahzhao 发表于 2008-1-21 15:49 | 显示全部楼层

我所知得AVR是可以位操作得

一个是#Define宏定义,一个是 << 运算符。
dudongdao 发表于 2008-1-22 00:41 | 显示全部楼层

就跟编译器有关了,其他的没关系

    楼主是不是觉得没有51那么操作简单~~  我觉得就跟编译器有关,和AVR或者51没关系,如果编译器支持那么用,那就OK,具体如何实现我们不用管,都是用C写,编译成汇编是什么样子不用管,它一条汇编实现也好,十条汇编实现也好,那是编译器的事,反映到C上就一句,编译器检测到这种格式自己去转换,那不就OK了,我也觉得没有KEIL C方便.
huanan_ 发表于 2008-1-22 16:33 | 显示全部楼层

宏,很方便

同意3楼用法,宏,很方便
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

23

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部