Noob问题:PORTD | =(1<< PORTD1)是什么意思; //将PD1驱动为高电平 [英] Noob question: what does this mean PORTD |= (1<<PORTD1); // drive PD1 high

查看:175
本文介绍了Noob问题:PORTD | =(1<< PORTD1)是什么意思; //将PD1驱动为高电平的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我正在使用ATMEL微控制器,并研究了一些代码示例.不久前,我在一堂课中学到了有关Micro的知识,我想不起来这个例子中的1< PORTD1是什么

Hi guys, i''m working with an ATMEL microcontroller and looking into some codes example. I learned about micro in a class a while ago and can''t recall what this 1<<PORTD1 means in this example

int main() {
    DDRD |= (1<<DDD1);          // set LED pin PD1 to output
    while (1) {
        PORTD |= (1<<PORTD1);   // drive PD1 high
        _delay_ms(100);         // delay 100 ms
        PORTD &= ~(1<<PORTD1);  // drive PD1 low
        _delay_ms(900);         // delay 900 ms
    }
}




也是1 << DDD1.
我想这看起来不像是一个转变.
你们能启发我吗?
#######################
我知道| =并转移.只是不确定为什么PORTD1等于1或我们尝试设置的任何位(即,如果在这里使用PORTD3,那意味着我们想从右开始设置第3位.我们如何知道PORTD3等于3?)




also that 1<<DDD1 too.
Doesn''t look like a shift, I think.
Could you guys enlighten me ?
#######################
I know |= and shift. Just not sure why the PORTD1 would equal to 1 or whatever bit we are trying to set (i.e., if PORTD3 is used here instead,then it means we''d like to set the 3rd bit from right. How would we know that PORTD3 equals to 3? ) . Maybe this question is too AVR specific.

推荐答案

您好,

与我的评论相同,但如建议一样,现在作为解决方案发布(这样一来,它就不再显示为未回答的问题":

"PORTD等于1左移PORTD1值的次数",即PORTD = PORTD | (1<< PORTD1);
X<< Y左移X,Y次,例如1<< 5个左移1次,进行5次运算,得到00010000b,即32.在Wolfram Alpha中添加一些示例,您就会明白.

希望这会有所帮助,
埃德

为了消除对此与"//将PD1驱动为高电平"的关系的困惑:

无论您使用哪种微控制器硬件,术语都是相同的.如果您有输出引脚,例如使该引脚上的输出电压为+ ve的PORTD1被称为将其驱动为高电平",即,如果绘制该引脚的电压图,则该线将变为高电平.在代码中,将输出电压驱动为高电平意味着将引脚的输出设置为1.将引脚驱动为低电平意味着使其变为0的电压,即将输出设置为0.我们使用驱动"一词是因为微控制器实际上迫使引脚电压达到该电平,而不是仅仅允许引脚达到它自己的电平(不是最好的解释,但希望足够简单).

因此,声明:

PORTD |= (1<<PORTD1);

(如对我的答案的评论中指出的那样)使用位掩码来打开位,该位是从左侧开始的PORTD1位置.由于PORTD1实际上是指PORTD寄存器中的第二位,因此它将为0或1.因此,该语句实际上等于以下任意一个:

PORTD = PORTD | (1<<0);,它将始终导致: PORTD = PORTD | 1(注意:PORTD指的是PORTD中的所有位,其中PORTD1指的只是第一位.因此,如果所有位都设置为0,则PORTD的值为:00000000b在PORTD中是8位).

或结果为:
PORTD = PORTD | (1<<1);.但是,由于它是我们首先测试的第二位,因此它对PORTD输出没有影响. (因为代码基本上意味着:如果PORTD1为1,则将PORTD1设置为1,因此没有变化.)

因此,似乎要使用的代码很奇怪.因此,我建议OP用更简单的方式代替它(除非我错过了什么?):

Hi there,

Same as my comment but as suggested, now posted as a solution (so that this stops showing as an "Unanswered question":

"PORTD OrEquals 1 left shifted the number of times of the value of PORTD1" i.e. PORTD = PORTD | (1<<PORTD1);
X << Y left shifts X, Y times e.g. 1 << 5 lefts shifts 1, 5 times giving 00010000b i.e. 32. Put some examples into Wolfram Alpha and you''ll get the idea.

Hope this helps,
Ed

To clear up the confusion of how this is related to "// drive PD1 high":

Regardless of what micro-controller hardware you are using, the terminology is the same. If you have an output pin e.g. PORTD1, making the output voltage on that pin +ve is called "driving it high" i.e. if you drew a graph of the voltage of that pin, the line would go high. In code, to drive the output voltage high means setting the pin''s output to 1. Driving a pin low means making it go to 0 voltage i.e. setting the output to 0. We use the word "drive" because the micro-controller actually forces the pin voltage to that level rather than just allowing the pin to reach that level of it''s own accord (not the best explanation but hopefully simple enough).

So the statement:

PORTD |= (1<<PORTD1);

(As pointed out in a comment on my answer) uses a bit mask to turn on the bit which is PORTD1 positions from the left. Since PORTD1 actually refers to the second bit in the PORTD register, it will either be 0 or 1. Thus the statement really equates to either of the following:

PORTD = PORTD | (1<<0); which will always result in: PORTD = PORTD | 1 (Noteably: PORTD refers to all the bits in PORTD where as PORTD1 refers to just the first bit. Thus the value of PORTD is: 00000000b if all bits are set to 0 and there are 8 bits in PORTD).

or it results in:
PORTD = PORTD | (1<<1);. However, since it was the second bit that we tested for in the first place, it will have no effect on the PORTD output. (Since the code basically means: if PORTD1 is 1, set PORTD1 to 1 thus no change.)

It seems like a pretty odd piece of code to be using therefore. So I would suggest the OP replaces it with something a little simpler (unless I have missed something???):

if(PORTD1 == 0)
{
    PORTD |= 1;
}



希望这可以消除一些困惑(或引发一些新的有趣的问题),
埃德

改进的代码版本(现在我已经看过原始文章):



Hope this clears up some of the confusion (or creates some new, interesting questions),
Ed

Improved version of code (now that I have seen the original article):

int main() {
    DDRD |= (1<<DDD1);          // set LED pin PD1 to output
    PORTD = 0b00000000;         //Clear PORTD. 
    while (1) {
        //Bit mask on bit 2 of PORTD i.e. PD1 
        //    - sets PD1 to 1 and leaves other bits the same.
        PORTD |= 0b00000010;   // drive PD1 high
        
        _delay_ms(500);        // delay 500 ms
        
        //Bit mask on bit 2 of PORTD i.e. PD1 
        //    - sets PD1 to 0 and leaves other bits the same.
        PORTD &= 0b11111101;   // drive PD1 low
        
        _delay_ms(500);        // delay 500 ms

        //500ms delays should create a flash with:
        //Up time 0.5 seconds and down time 0.5s
    }
}



使用〜"运算符可以使它更紧凑(这个名字让我无所适从),但是为了简单起见,我只是使用位掩码来切换PORTD的第二位.

我认为原始代码试图根据PORTD1是否打开来进行切换而变得太聪明了.它极大地增加了代码的复杂度...特别是对于初学者的教程而言.甚至对于实际应用来说……



This could probably be made more compact using "~" operator (the name has slipped my mind) but for simplicity sake I have simply used to bit masks to toggle the second bit of PORTD.

The original code, I think, was trying to be too clever with toggling based on whether PORTD1 was already on or not. It significantly overcomplicated the code...especially for a beginners'' tutorial. Or even for practical application really...


好,提供了 PORTD1 = 1;
您应该能够在包含的头文件之一(我想在avr/pinports.h中)中找到#define PORTD1 1.
这种方式(如Ed所示)
OK, that makes sense provided PORTD1 = 1;
You should be able to find #define PORTD1 1 in one of the included header files (I suppose in avr/pinports.h).
This way (as Ed already showed)
PORTD |= (1 << PORTD1);


1 of port <code>D位设为ON,因为1 << 1 = 00000010B



turns ON bit 1 of port <code>D, because 1 << 1 = 00000010B

While

PORTD &= ~ (1 << PORTD1); 


因为 ~(1 << 1) = 11111101B,所以将其清零(置为OFF).


clears (turns OFF) bit 1, because ~(1 << 1) = 11111101B.


这篇关于Noob问题:PORTD | =(1&lt;&lt; PORTD1)是什么意思; //将PD1驱动为高电平的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆