ATmega芯片以及I/O引脚的简单说明

原理图
avr core
大多数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) 。
i/o端口
了解微控制器的内部工作情况很好,但知道如何让芯片与外界交流是很好的。大多数微控制器(如果不是全部)都包含引脚,允许器件读取和写入外部电路的数字值。例如,led可以连接到i/o(带有串联电阻),这将允许微控制器打开和关闭led。另一个例子是一个开关,它可以连接在引脚和电源之间,微控制器可以在检测到开关被按下时执行动作。
当然,微控制器可以连接到几乎任何电路,并以您可能想象的任何方式与它进行交互。但要做到这一点,我们需要了解i/o端口如何在avr设备上工作以及如何正确使用它们!
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表示输入。因此,假设我们想要将port b上的所有引脚配置为输出,我们只需使用以下代码:
ddrb = 0xff;

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

ddrb = 0b00000000;
更复杂的事情怎么样?假设您希望前两个引脚为输出(pb0和pb1),其余引脚为输入。以下代码可以解决这个问题:
ddrb = 0x03;

ddrb = 0b00000011;
pinx寄存器
我们的ddr寄存器排序out,是时候学习如何从现实世界中将数字值读入微控制器。这是使用寄存器pinx完成的,其中x是要读取的寄存器。从端口读取相当容易,如下面的代码示例所示:
datavalue = pinb;
执行此操作时,port b上的所有引脚都被读入datavalue,并且datavalue中的每个位现在将对应于读取时每个引脚上的数字电平。虽然这可能很有用,但我们有时可能希望同时测试单个位而不是所有位。在pic中,.bits成员可用于访问各个位,但avr设备不是这种情况。相反,访问单个位涉及一些操作(原谅双关语),包括使用逻辑and,or和xor。
要测试一个位是否打开(逻辑1),以下两个可以使用语句。这些函数对pin寄存器和位执行逻辑and(表示为8位数)。如果结果为零,则不会执行if语句,因为if语句仅在条件为非零时执行。第一个语句使用二进制值来表示要测试的位,而第二个语句使用逻辑移位指令来创建位掩码,该掩码表示要测试的位。逻辑移位版本可以说更具可读性,因此更容易理解。但是,执行该指令可能需要比第一次更长的时间(取决于优化)。
if(pinb&(0b00000001))

if(pinb&(1 《
在主要测试(!)
if(!(pinb&(0b00000001)))
或《之前使用否定运算符可以轻松地测试逻辑0 br》 if(!(pinb&(1 《
portx寄存器
现在我们可以读取整个端口和各个引脚,我们如何写入端口和单个引脚?这是portx寄存器的用武之地。写入该寄存器(其中x表示要写入的端口)将导致输出引脚打开或关闭。请记住,物理输出引脚只有与portx寄存器if对应的数字电平,只有相应的ddr位被设置为输出!
将值写入端口非常容易:
portb = 0xff;

portb = 0b11111111;
但个别位怎么样?这再次使用按位运算符完成,并且设置/清除位稍微复杂一些。这是因为我们需要保留port寄存器中其他位的值,否则它们可能会被更改,如果它们连接到外部设备(如led,显示器,ic等),可能会导致意外行为。
要打开特定位,我们可以使用or逻辑运算符:
portb = portb | (0b00000001);打开位0

portb = portb | (1 《
要关闭特定位,我们使用and运算符和not运算符(〜):
portb = portb& 〜(0b00000001);关闭位0

portb = portb& 〜(1 《
要切换一点(以便它与以前相反)我们可以使用xor运算符:
portb = portb ^(0b00000001);切换位0
o r
portb = portb ^(1 《
引脚名称
使用数字来表示引脚可能会导致某些不可读代码,这就是为什么winavr足够好,可以包含一些我们可以使用的定义。请参阅以下示例:
portb = portb& 〜(1 《
如果(pinc&(1 《
一个简单的例子
在我们的例子中,我们将制作一个电路当按下连接到pd1的开关时,切换连接到pd0的led。
/*
* avr io.c
*
* created: 03/01/2018 11:25:21
* author : robinlaptop
*/
#define f_cpu 1000000ul
#include
#include
int main(void)
{
// configure port d bit 0 to an output and bit 1 to an input
ddrd = 0b00000001;
// main program loop
while (1)
{
// wait until the switch found on pind1 (bit 1)
if(pind & (1 《《 pind1))
{
// toggle the led found on pind0
portd = portd ^ (1 《《 pind0);
// force a delay to prevent de-bounce!
_delay_ms(100);
// wait until the button is released
while(pind & (1 《《 pind1));
}
}
}
结论
现在我们可以控制i/o引脚了,没有理由不能在复杂控制器可以使用的项目中开始使用avr。使用本文中的知识,您可以创建一个键盘输入系统,一个复杂的7段显示控制器,一个音乐系统,甚至是一个基本的80年代风格的计算机。

吉时利宣布推出了最新的4225-PMU超快I-V测试模块
创新科技欲与中国的高科技公司共同推动绿色高科新洪流
被“电子扫码”所困扰的中老年人该如何应付数字化趋势?
上汽集团将与地平线合作打造并量产其下一代自动驾驶技术
XG-500型X线机增设主可控硅损坏保护电路的新方法
ATmega芯片以及I/O引脚的简单说明
【地平线旭日X3派试用体验】变身红白机玩转NES游戏
逆变器输出电压低维修方法介绍
GooglePlay 应用商店曝104个恶意软件 下载时将在全部页面显示广告
消费升级拓展市场空间 PCB行业发展前景怡人
荣耀智慧屏一款搭载鸿蒙OS系统的智能电视
基于TX4208芯片制作的DEMO演示板
国际先进水平?智能电网调度技术支持系统通过验收
2014年LED市场回暖 或将带来六大变革
有R型电源变压器,再也不怕电压不合适!
安晟培半导体Ampere Altra处理器推出,应用于云和边缘计算数据中心中
在smt生产的过程中如何来目测
熔断器UL认证和熔断器TUV认证标准有什么不同?
浪潮分布式存储 夯实国家电网电路智能巡检数据底座
全球化布局优势凸显,佰维存储斩获印度“消费级存储领域杰出成就奖”