900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > c语言移位函数intrins 单片机C语言实现NOP 循环移位

c语言移位函数intrins 单片机C语言实现NOP 循环移位

时间:2019-08-18 14:19:10

相关推荐

c语言移位函数intrins 单片机C语言实现NOP 循环移位

原标题:单片机C语言实现NOP 循环移位

首先声明:我学习 单片机C语言还不到半年,所以我还是菜鸟,我贴出的东西或许你们都知道,但我只想把我学习的经历给记录下来,希望你能找到你所想要的.

我记得做学单片机做的第一个实验就是做循环彩灯的实验,如果用汇编RL和RR很容易实现 循环移位,但是C语言编程的移位指指令不能循环,移了后以0填充。

如果用C实现循环移位呢?

我的思路是:

比如将a=0x45循环左移二位。

a循环左移n位,即将原来右面(8-n)位左移n位,而将原来左端的n位移到最右面n位。

1、将a的左端n位先放到b中的高n位中

b=>>(8-n);

2、将a左移n位,其右面高n位被补0

c=<

3、将b,c进行或运算

a=c|b;

程序如下:

main()

{

unsigned char a=0x45,b,c;

unsigned int n=2;

b=a>>(8-n)

c=a<

a=c|b;

}

记得我才学单片机的时候做的第一个实验就是循环彩灯(那时候用的汇编)

学单片机C语言的时候,第一个实验当然也就是循环彩灯了,C没有直接循环移位的指令没关系,用上面的语句即可实现。:)

如果用keil C的话,它的内部函数_cror_, _crol_实现了这个,包含即可,由于是intrins函数,步步生成函数调用代码,效率很高

用C51自己编一个多字节的循环移位是一件比较麻烦的事,自己可以嵌入汇编的方

法,但是这给编程者容易隐含错误,特别是对于汇编语言不熟的人用汇编是一件

难事。其实在KEIL C51中有这样一个库,其头文件为intrins.h在C51INC目录下

,有以下几个操作,它不是函数,但象函数,它们有入口出口,但是,没有返回R

ET语句,如果有这些操作,用disassembly窗口可以看到是将代码直接嵌入到你的

代码中,其效率很高,比如一个空操作,_nop_() 嵌入的代码就是一个NOP指令。

在这个库中,有如下操作:

unsigned char _chkfloat_(float val) 检查浮点数状态

返回值:0: standard floating-point numbers

1: Floating-point value 0

2:+INF (positive overf low)

3:-INF (Not a number) error status

unsigned char _crol_( //字节的多次循环左移

unsigned char c, //C左移的字符

unsigned char b);//b左移的位数

unsigned char _cror_( //字节的多次循环右移

unsigned char c, //C右移的字符

unsigned char b);//b右左移的位数

unsigned int _irol_ ( //字的循环左移

unsigned int c, //c左移的字

unsigned char b);//b左移的次数

unsigned int _iror_ ( //字的循环右移

unsigned int c, //c右移的字

unsigned char b);//b右移的次数

unsigned long _lrol_ ( //4字节(双字)的循环左移

unsigned long c,//c左移的双字

unsigned char b);//b左移的次数

unsigned long _lror_ ( //4字节(双字)的循环右移

unsigned long c,//c右移的双字

unsigned char b);//b右移的次数

void _nop_ (void); //NOP 8051中的空操作

bit _testbit_ (bit b);//8051中的JBC指令,测试b,然后清0,返回b的值。

下面是我自己以前写的东西

汇编的移位操作很容易 RR RRC RL RLC

C51中,移出很容易,<< >> ;移入操作中的左移入也容易,困难在右移入

一:IC读写应用

1:送数

送两个单独字节的数据的程序,左送 &0x80 右送 &0x01

bit out;

out = low & 0x01;

low >>= 1;

low |= (high & 0x01)<<7;

high >>= 1;

2:取数(不管怎么移入,第一次操作之后获取的那一位数据必须在接受数据的最高位或

者最低位上,从而选择是先取数还是先移位)

a:如果是先接受高位后接受低位 则先左移一位后接受一位数据(i2c总线)

uchar i;

uchar temp = 0;

uchar date = 0x82;

for (i = 0; i < 8; i++)

{

temp <<= 1; //左移

temp |= (bit)(date & 0x80);

date <<= 1;

}

b:如果是先接受低位,后接受高位 则先接受一位数据后循环右移一位

uchar i;

uchar temp = 0;

uchar date = 0x82;

for (i = 0; i < 8; i ++)

{

temp |= (bit)(date & 0x01);

date >>= 1;

temp = _cror_(temp,1);

//循环右移,应用_cror_()需要包含头文件

}

如果不用函数

则for循环应该这样写

for (i = 0; i < 8; i ++)

{

temp >>= 1;

temp |= (date & 0x01) << 7;

date >>= 1;

}

三:任意一位的置位或者取反运算

置位运算

low |= 0x01; (置最低位为1)

取反运算

low |= ~low & 0x01;

四:合并和拆分数据

1:合并两个单字节数据为一个双字节数据

int len;

uchar low;

uchar high;

Len |= high;

Len <<= 8;

Len |= low;

2: 拆分一个双字节数据为两个单字节数据

int len;

uchar low;

uchar high;

low |= len;

high |= len >> 8;

责任编辑:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。