请问PORTC|=(1<<i)|(1<<(i-1));当i=0时,PORTC为什么值?谢谢
如题,在AVR端口赋值中PORTC|=(1<<i)|(1<<(i-1));当i=0时,PORTC为什么值,i为unsigned char 类型。 PORTC |= (1 << 0) | (1 << 255) 不知道是不是这样 浮华一生 发表于 2019-3-29 15:38PORTC |= (1
最终转换为字节呢PORTC=? 秀智商啊!
1 本帖最后由 liuyonguo 于 2019-3-29 19:54 编辑
问的是PORTC=?
答案应该是PORTC=(PORTC|1);
哈哈 楼主牛逼,我司要是有程序猿这么写程序,二话不说,直接拉出去祭天! 用 ICC 搞了一下(MEGA8),的确是 <<255 了,结论应该是 1<<(i-1) 为零
MAIN.C
#include "iom8v.h"
void main(void)
{
unsigned char i= 0;
PORTC= (1<<i)|(1<<(i-1));
}
汇编文件,i 被安排在了 R20,<< 运算就是 lsl8 库,R16 为左操作数(被移数),R17 为右操作数(移数)
汇编 00089 位置显然 R17 直接 R17-=1 了,这样铁定 255,之后 lsl8 就要左移255 次为零了。
ASM.LST
(0001) #include "iom8v.h"
(0002)
(0003) void main(void)
(0004) {
(0005) unsigned char i= 0;
_main:
i --> R20
00087 2744 CLR R20
(0006) PORTC= (1<<i)|(1<<(i-1));
00088 2F14 MOV R17,R20
00089 5011 SUBI R17,1
0008A E001 LDI R16,1
0008B 940E 0096 CALL lsl8
0008D 2E20 MOV R2,R16
0008E E001 LDI R16,1
0008F 2F14 MOV R17,R20
00090 940E 0096 CALL lsl8
00092 2E30 MOV R3,R16
00093 2832 OR R3,R2
00094 BA35 OUT 0x15,R3
00095 9508 RET
lsl8:
00096 2311 TST R17
00097 F019 BEQ 0x009B
00098 0F00 LSL R16
00099 951A DEC R17
0009A CFFB RJMP lsl8
0009B 9508 RET
t3486784401 发表于 2019-3-29 20:57
用 ICC 搞了一下(MEGA8),的确是
谢谢你的讲解,很仔细,奈何自己C语言底子薄{:cry:} dragonlands 发表于 2019-3-29 20:15
楼主牛逼,我司要是有程序猿这么写程序,二话不说,直接拉出去祭天!
{:lol:} 确实有这样写的,我也是看到网上一个步进电机驱动程序是这样写的,当时搞不明白。
程序是驱动四相步进电机,实现单四拍和双四拍驱动。
unsigned char i=0; //转动计数
unsigned char m=1; //驱动方式参数
unsigned char n=0; //转动方向参数
unsigned int zhuansu=61500; //转速数据
/****************************
* 正转操作函数 *
* 入 口:a 三种工作方式 *
****************************/
void bj_fs(unsigned char a)
{
switch(a)
{
case 1: //单四拍方式驱动
PORTC |= 1<<i; //A、B、C、D驱动
i++;
if(i>=4)i=0;
break;
case 2: //双四拍方式驱动
if(i!=4) //AB、BC、CD、DA驱动
PORTC |= (1<<i)|(1<<(i-1));
else
PORTC |= (1<<(i-1))|1;
i++;
if(i>=5)i=1;
break;
case 3: //单双八拍方式驱动
if(i%2) //A、AB、B、BC、C、CD、D、DA驱动
{
if(i!=7)
PORTC |= (1<<(i/2))|(1<<(i/2+1));
else
PORTC |= (1<<(i/2))|1;
}
else
{
PORTC |= 1<<(i/2);
}
i++;
if(i>=8)i=0;
break;
default:break;
}
} 查表不是更简单吗?
页:
[1]