艾巴生活网

您现在的位置是:主页>科技 >内容

科技

atmega16a引脚定义(ATmega芯片以及I/O引脚的简单说明)

2024-12-04 18:20:11科技帅气的蚂蚁
示意图AVR内核大部分ATmega设备的核心是AVR CPU,被描述为RISC CPU。但是,尽管是RISC CPU,AVR核可以说是非常强大的,与竞争设备(如Mic

atmega16a引脚定义(ATmega芯片以及I/O引脚的简单说明)

示意图

AVR内核

大部分ATmega设备的核心是AVR CPU,被描述为RISC CPU。但是,尽管是RISC CPU,AVR核可以说是非常强大的,与竞争设备(如Microchip PIC系列)相比有很多优势。

例如,AVR内核包含通用8位寄存器,可以配对创建16位存储器位置指针。另外,AVR内核有130多条指令,很多都是单周期的(由于一级流水线的原因),没有方案。

然而,AVR设备特别容易阻塞。用户开始使用保险丝(特定芯片选项),这就是为什么强烈建议你手头有多个AVR设备。AVR设备的另一个问题是,如果他们不这样做,他们很难对芯片编程(例如与PICKIT3相比)。不要买官方程序员。

然而,AVR已经成为最受欢迎的微控制器之一。感谢Arduino 的发明,其核心包含ATmega。事实上,Arduino只是一个AVR微控制器,带有一些特殊的启动加载代码和USB到串行转换器。

以下是典型ATmega设备的内部架构(在我们的示例中为ATmega168)。

输入输出端口

它了解微控制器的内部工作原理是很好的,但是它it’知道如何让芯片与外界通信很好。大多数(如果不是全部)微控制器都包含允许设备从外部电路读取和写入数字值的引脚。例如,LED可以连接到I/O(通过串联电阻),这将允许微控制器打开和关闭LED。另一个例子是开关,它可以连接在引脚和电源之间,微控制器可以在检测到开关被按下时执行动作。

当然,微控制器可以连接到几乎任何电路,并以你可以想象的任何方式与之交互。但要做到这一点,我们需要了解AVR设备上的I/O口是如何工作的,以及如何正确使用!

I/O端口包含三个寄存器:

DDRx-端口X的数据方向寄存器

PINx-从端口x读取。

PORTx-写端口x

数据流向寄存器

方向寄存器(DDR)可能是您配置的第一个寄存器,因为DDR寄存器决定特定端口上的引脚是输入还是输出。DDR寄存器长8位,每一位对应I/O端口的引脚。

例如,DDRB的第一位(位0)将决定PB0是输入还是输出,最后一位(位7)将决定PB7是输入还是输出。

在PIC设备中,值1用于输入,值0用于输出,但对于AVR设备则相反;1表示输出,0表示输入。因此,假设我们要将端口B上的所有引脚配置为输出,我们只需使用以下代码:

DDRB=0x ff;

或者

DDRB=0b 11111111;

第一个示例使用十六进制,而第二个示例使用二进制。虽然通常的做法是使用十六进制,但二进制版本可以更清楚地使用端口中的哪些位作为输入或输出。如果我们想将端口B上的所有引脚转换为输入引脚,那么我们可以使用。

DDRB=0x 00;

或者

DDRB=0b 00000000;

来点更复杂的怎么样?假设您希望前两个引脚为输出(PB0和PB1),其余引脚为输入。下面的代码可以解决这个问题:

DDRB=0x 03;

或者

DDRB=0b 00000011;

PINx寄存器

我们的DDR寄存器被整理出来,它是时候学习如何将现实世界中的数字值读入微控制器了。这通过寄存器PINx来实现,其中x是要读取的寄存器。从端口读取非常容易,如下面的代码示例所示:

数据值=PINB;

执行此操作时,端口B上的所有引脚都被读入dataValue,dataValue中的每一位现在都对应于读取时每个引脚上的数字电平。虽然这可能是有用的,但我们有时可能希望同时测试单个位而不是所有位。在图片中。bits成员可用于访问各种位,但这不适用于AVR设备。相反,访问单个位涉及一些操作(原谅双关语),包括使用逻辑AND、OR和XOR。

为了测试一个位是否开启(逻辑1),下面两个可以使用语句。这些功能对引脚寄存器和位执行逻辑“与”(表示为8位)。如果结果为零,则不会执行If语句,因为if语句只会在条件非零时执行。第一条语句使用二进制值来表示要测试的位,而第二条语句使用逻辑移位指令来创建表示要测试的位的位掩码。逻辑移位版可以说可读性更强,所以更容易理解。但是,执行此指令可能比第一次需要更长的时间(取决于优化)。

如果(PINB & amp;(0b00000001))

或者

如果(PINB & amp;(1 《

在主测(!)

如果(!(PINB & amp;(0b00000001)))

或者《之前使用否定运算符可以轻松地测试逻辑0 br》 if(!(PINB & amp;(1 《

PORTx寄存器

现在,我们可以读取整个端口和各个引脚。我们如何写端口和单独的引脚?这就是PORTx寄存器的用武之地。写入该寄存器(其中X代表要写入的端口)将导致输出引脚打开或关闭。记住,物理输出引脚只有PORTx寄存器的IF对应的数字电平,只有对应的DDR位设置为输出!

向端口写入值非常容易:

PORTB=0xFF

或者

PORTB=0b11111111

但是个人座位呢?这也是使用按位运算符完成的,设置/清除位稍微复杂一些。这是因为我们需要保存端口寄存器中其他位的值,否则它们可能会被更改,如果它们连接到外部设备(如LED、监视器、IC等。),它们可能会导致意想不到的行为。

要打开特定的位,我们可以使用OR逻辑运算符:

PORTB=PORTB |(0b 00000001);开放位0

或者

PORTB=PORTB | (1

为了关闭一个特定的位,我们使用AND运算符和NOT运算符():

PORTB=PORTB & amp(0b00000001);关闭位0

或者

PORTB=PORTB & amp(1 《

要转换一位(以便与之前相反),我们可以使用XOR运算符:

波特布=波特布^(0b00000001);开关位0

手术室

^(1港

Pin名称

使用数字来表示pin可能会导致一些不可读的代码,这就是为什么WinAVR足以包含一些我们可以使用的定义。请参见以下示例:

PORTB=PORTB & amp(1 《

if(pinc & amp;(1 《

简单的例子

在我们的示例中,当连接到PD1的开关被按下时,我们将制作一个电路来切换连接到PD0的LED。

/*

* AVR IO.c

*

*创建时间:2018年3月1日11时25分21秒

*作者:RobinLaptop

*/

#定义F_CPU 1000000UL

#包括

#包括

int main(void)

{

//将端口D的位0配置为输出,位1配置为输入

DDRD=0b 00000001;

//主程序循环

while (1)

{

//等待直到在PIND1(位1)上找到开关

如果(PIND (1《品1》)

{

//切换PIND0上的LED

波特德=波特德^(1《品多》);

//strong制延迟以防止反跳!

_ delay _ ms(100);

//等待按钮被释放

而PIND (1《品1》);

}

}

}

结论

既然我们可以控制I/O引脚,我们没有理由不能不要在可以使用复杂控制器的项目中使用AVR。使用本文中的知识,您可以创建一个键盘输入系统、一个复杂的7段显示控制器、一个音乐系统,甚至是一台基本的80年代风格的计算机。