要读取ATmega16上的数字输入(按钮),我该怎么办?我必须启用上拉电阻还是可以使用10 kohm电阻?一些简单的代码是什么?只需简单的“在按下时打开LED指示灯”即可。
有初学者的教程吗?我曾尝试使用谷歌搜索和AVR Freaks,但是所有事情都演变成一场战斗,我没有得到答案。我真的还没有找到关于这些东西的任何教程。大量的特定信息,但是关于我的AVR微控制器却并非如此简单...
要读取ATmega16上的数字输入(按钮),我该怎么办?我必须启用上拉电阻还是可以使用10 kohm电阻?一些简单的代码是什么?只需简单的“在按下时打开LED指示灯”即可。
有初学者的教程吗?我曾尝试使用谷歌搜索和AVR Freaks,但是所有事情都演变成一场战斗,我没有得到答案。我真的还没有找到关于这些东西的任何教程。大量的特定信息,但是关于我的AVR微控制器却并非如此简单...
Answers:
巴西的问候!
首先,感谢乔比的例子。其次,他的例子只有一个小错误。数字0x20不正确。它应该是0x04。另外,作为建议,我不会在代码中使用十六进制数字,例如0xFB,0x20或0x04。我建议使用io.h中找到的PIN端口定义以及头文件引用的其他端口定义。我在下面重写了乔比的示例,并为初学者提供了一些注释。
# include <avr/io.h>
int main (void)
{
// set all pins on PORTB for output
DDRB = 0xFF;
// set port pin PORTD2 as input and leave the others pins
// in their originally state (inputs or outputs, it doesn't matter)
DDRD &= ~(1 << PD2); // see comment #1
while (1)
{
if (PIND & (1<<PD2)) // see comment #2
PORTB |= (1<<PB2); // see comment #3
else
PORTB &= ~(1<<PB2); // see comment #4
}
return 0;
}
/ *
评论#1:(1 << PD2)生成二进制00000100。操作“〜”翻转所有数字,即二进制现在为11111011。最后,&=在DDRD和11111011之间应用逻辑“ AND”,并再次放置结果在DDRD内存中。注意:运算符“ AND”对DDRD存储器中的每个位进行操作,并将其与上述二进制数进行比较。如果DDRD中的位为0,并且二进制位中同一位的位为1,则结果位为0;如果DDRD为1,二进制中的位为1,则结果位为1;如果DDRD中的位为1或0,二进制中的位为0,则结果位始终为0。总而言之,命令DDRD&=〜(1 << PD2)仅将位PD2更改为零,而其他位(零或一个)保持不变。这似乎有点复杂,但是在您习惯了它之后,这是在不改变其他位的情况下改变一个位的最佳方法。
注释#2:(1 << PD2)生成二进制00000100。使用注释#1中描述的相同逻辑“与”,命令“ PIND&0000100”仅检查PIND2(我们连接按钮的输入引脚)设置为高)。由于二进制位设置为0,且所有其他引脚将为FALSE,并且由于二进制位#2设置为1,因此只有在PD2输入设置为高电平时IF语句才为TRUE,而在PD2输入设置为FALSE时则为FALSE。设置为低。
注释3:遵循注释1中解释的逻辑,此命令将端口PORTB中的输出引脚PINB2设置为高电压。如果您的LED用约300欧姆的电阻正确连接到了此引脚端口,并且该电阻已接地,则LED应该亮起。
注释4:LED指示灯应出于前面注释中所述的相同原因关闭。
最终考虑因素:
a)为避免在未按下按钮(开路)时输入引脚PD2中的电压振荡,强烈建议放置一个下拉电阻(1 kOhm或更高),以免LED意外亮起到这种随机的电压振荡。
b)免责声明:此处描述的思想仅用于教育目的,在咨询电子专家之前,不得在任何实际系统中使用它们。
* /
https://www.mainframe.cx/~ckuethe/avr-c-tutorial/
https://www.mainframe.cx/~ckuethe/avr-c-tutorial/#digital-in
#include <avr/io.h>
/*
* Assumptions:
* - LED connected to PORTB.2
* - Switch connected to PORTD.2
*/
int main (void)
{
/* set PORTB for output*/
DDRB = 0xFF;
/* set PORTD for input*/
DDRD &= 0xFB;
PORTD |= 0x04;
while (1) {
if (PIND & 0x04)
PORTB &= ~0x20;
else
PORTB |= 0x20;
}
return 0;
}
Hackaday为AVR编程撰写了大量文章,其中包含许多有用的信息,可以帮助您
http://hackaday.com/2010/11/19/avr-programming-04-writing-code-etc/
http://hackaday.com/2010/11/05/avr-programming-03-reading-and-compiling-code/
http://hackaday.com/2010/10/25/avr-programming-02-the-hardware/
http://hackaday.com/2010/10/23/avr-programming-introduction/
嗯,这是针对ATMega的AT90Usb1287,但基本的按钮设置应该大致相同。只需更改IO名称。