用C编程微控制器Atmega2560

时间:2016-02-12 14:42:02

标签: c microcontroller

这是一个程序,它读取端口A的引脚2到5,并将这些引脚的状态复制到端口B的输出引脚3到6,而不使用AVR库。该程序有效,但我需要一些帮助,了解它是如何工作的。我以他理解的方式评论它。提前谢谢!

PS:有用的信息: 0x21 - 端口A数据方向寄存器 0x24 - 端口B数据方向寄存器 0x20 - 端口A输入引脚地址 0x25 - 端口B数据寄存器

DDRx,数据方向寄存器,用于确定端口的引脚是配置为输入还是输出;

PORTx是用于设置输出引脚值的寄存器;

PINx是读取输入引脚值的寄存器。

int main (void){

unsigned char *ptr,data;

ptr =(unsigned char*)0x21;                    //Points ptr to 0x21, which is the DDRA
*ptr &=~((1<<2)|(1<<3)|(1<<4)|(1<<5));        //*1

ptr =(unsigned char*)0x24;                    //Points ptr to 0x24, which is the DDRB
*ptr |=(1<<3)|(1<<4)|(1<<5)|(1<<6);           //*2

for(;;){
    ptr=(unsigned char*)0x20;                 //Points ptr to 0x20, which is the PINA
    data=*ptr;                                //Saves the data from 0x20 to 'data'

    data &= ~((1<<0)|(1<<1)|(1<<6)|(1<<7));   //*3
    data <<=1;                                //*4

    ptr=(unsigned char*)0x25;                 //Points ptr to 0x25, which is the PORTB
    *ptr=(*ptr &~((1<<3)|(1<<4)|(1<<5)|(1<<6)))|data;    //*5
}
return(0);
}

* 1:程序是否使用0x21和字节00111100的位进行AND运算?这样答案就像00????00。我也不理解'~'

* 2:程序是否使用0x24和字节01111000的位进行OR运算?这样答案就像?1111???。为什么他不使用AND代替OR?

* 3:程序是否使用&#39;数据&#39;中的位进行AND操作?和字节11000011?这样答案就像是0000 ??这样做的重点是什么?

* 4:为什么他将'data'向左移一次?这样的答案就像是?0000 ?? 0。

* 5:程序是否使用0x25和字节01111000(结果为0 ???? 000)的位进行AND运算,然后对其结果进行OR运算和来自数据的位?这样答案就像00000000!?!?!?

1 个答案:

答案 0 :(得分:1)

1:程序正在构建位字段0b00111100,然后用〜运算符将其改为0b11000011,然后将该值与ptr指向的地址的内容进行AND运算,然后将结果存储到指向的地址中。 PTR。它清除数据方向寄存器的第2位到第5位,而其他位保持不变。据推测,位值为0表示引脚是输入。

2:程序正在构建位字段0b01111000,然后将该值与ptr指向的地址的内容进行或运算,然后将结果存储到ptr指向的地址中。它设置数据方向寄存器的第3位到第6位,而其他位保持不变。据推测,位值为1表示引脚是输出。

3:程序将从数据地址读取的值与0xb00111100进行AND运算,以清除0,1,6和7位。程序仅涉及位2到5,忽略其他位。

4:程序正在将第2位到第5位的值向左移位1位,以便将其移入第3位到第6位。

5:程序正在读取数据寄存器的内容,清除从数据寄存器读取的第3位到第6位,然后在将数据写回数据寄存器之前对第3位到第6位的新值进行“或”操作。 。换句话说,它更新位3到6的值而不改变位0,1,2和7的值。

这些操作很常见:

data &= ~(bitfield)清除bitfield指定的位而不更改其他位。

data |= bitfield设置bitfield指定的位而不更改其他位。