单片机 IO 结构
21ic 2021-11-08

AVR的IO是真正双向IO结构,由于大部分网友都是从标准51转过来的,受标准51的准双向IO和布尔操作概念影响,没能掌握AVR的IO操作,所以有必要撰文说明一下

其实采用真正双向IO结构的新型MCU很多,常用的有 增强型51,PIC,AVR等

先简单的回顾一下标准51的准双向IO结构


这种准双向IO结构的特点是

1 输出结构类似 OC门,输出低电平时,内部NMOS导通,驱动能力较强(800uA);输出高电平靠内部上拉电阻,驱动能力弱(60uA)。

2 永远有内部电阻上拉(P0口除外),高电平输出电流能力很弱,所以即使IO口长时间短路到地也不会损坏IO口

(同理,IO口低电平输出能力较强,作低电平输出时不能长时间短路到VCC)

3 作输入时,因为OC门有"线与"特性,必须把IO口设为高电平(所以按键多为共地接法)

4 作输出时,输出低电平可以推动LED(也是很弱的),输出高电平通常需要外接缓冲电路(所以LED多为共阳接法)

5 软件模拟 OC结构的总线反而比较方便-----例如 IIC总线

* P0口比较特殊,做外部总线时,是推挽输出,做普通IO时没有内部上拉电阻,所以P0口做按键输入需要外接上拉电阻。

* OC门:三极管的叫集电极开路,场效应管的叫漏极开路,简称开漏输出。具备"线与"能力,有0得0。

* 为什么设计成输出时高电平弱,低电平强----是考虑了当年流行的TTL器件输入特性

AVR的真正双向IO结构就复杂多了,单是控制端口的寄存器也有4个 PORTx.DDRx,PINx,SFIOR(PUD位),不过功能也强劲多了

作为通用数字I/O 使用时,所有AVR I/O 端口都具有真正的读- 修改- 写功能。

这意味着用SBI 或CBI 指令改变某些管脚的方向( 或者是端口电平、禁止/ 使能上拉电阻) 时不会无意地改变其他管脚的方向( 或者是端口电平、禁止/ 使能上拉电阻)。

输出缓冲器具有对称的驱动能力,可以输出或吸收大电流,直接驱动LED。

所有的端口引脚都具有与电压无关的上拉电阻。

并有保护二极管与VCC 和地相连。

* (很多数字器件都有保护二极管,在低功耗应用时要考虑保护二极管的电流倒灌的影响)

每个端口都有三个I/O 存储器地址:

数据寄存器 – PORTx

数据方向寄存器 – DDRx

端口输入引脚 – PINx。

数据寄存器PORTx和数据方向寄存器DDRx为读/ 写寄存器,而端口输入引脚PINx为只读寄存器。

但是需要特别注意的是,对PINx 寄存器某一位写入逻辑"1“ 将造成数据寄存器相应位的数据发生"0“ 与“1“ 的交替变化。

当寄存器MCUCR 的上拉禁止位PUD置位时所有端口引脚的上拉电阻都被禁止。

在( 高阻态) 三态({DDxn, PORTxn} = 0b00) 输出高电平({DDxn, PORTxn} = 0b11) 两种状态之间进行切换时,

上拉电阻使能({DDxn, PORTxn} = 0b01) 或输出低电平({DDxn,PORTxn} = 0b10) 这两种模式必然会有一个发生。

通常,上拉电阻使能是完全可以接受的,因为高阻环境不在意是强高电平输出还是上拉输出。

如果使用情况不是这样子,可以通过置位SFIOR 寄存器的PUD 来禁止所有端口的上拉电阻。

在上拉输入和输出低电平之间切换也有同样的问题。

用户必须选择高阻态({DDxn,PORTxn} = 0b00) 或输出高电平({DDxn, PORTxn} = 0b10) 作为中间步骤。

不论如何配置DDxn,都可以通过读取PINxn 寄存器来获得引脚电平

PINxn寄存器的各个位与其前面的锁存器组成了一个同步器。

这样就可以避免在内部时钟状态发生改变的短时间范围内由于引脚电平变化而造成的信号不稳定。

其缺点是引入了延迟。

AVR IO具备多种IO模式:

1 高阻态 ,多用于高阻模拟信号输入,例如ADC数模转换器输入,模拟比较器输入

2 弱上拉状态(Rup=20K~50K),输入用。为低电平信号输入作了优化,省去外部上拉电阻,例如按键输入,低电平中断触发信号输入

3 推挽强输出状态,驱动能力特强(>20mA),可直接推动LED,而且高低驱动能力对称.

使用注意事项:

写用PORTx,读取用PINx

实验时,尽量不要把管脚直接接到GND/VCC,当设定不当,IO口将会输出/灌入 80mA(Vcc=5V)的大电流,导致器件损坏。

作输入时:

1通常要使能内部上拉电阻,悬空(高阻态)将会很容易受干扰。(表面看好像是51的抗干扰能力强,是因为51永远有内部电阻上拉,)

2尽量不要让输入悬空或模拟输入电平接近VCC/2,将会消耗太多的电流,特别是低功耗应用场合------CMOS电路的特点

3读取软件赋予的引脚电平时需要在赋值指令out 和读取指令in 之间有一个时钟周期的间隔,如nop 指令。

4功能模块(中断,定时器)的输入可以是低电平触发,也可以是上升沿触发或下降沿触发。

5用于高阻模拟信号输入,切记不要使能内部上拉电阻,影响精确度。例如ADC数模转换器输入,模拟比较器输入

作输出时:

采用必要的限流措施,例如驱动LED要串入限流电阻

复位时:

复位时内部上拉电阻将被禁用。如果应用中(例如电机控制)需要严格的电平控制,请使用外接电阻固定电平

休眠时:

作输出的,依然维持状态不变

作输入的,一般无效,但如果使能了第二功能(中断使能),其输入功能有效。例如 外部中断的唤醒功能。

AVR的C语言IO操作:

AVR的C语言基于ANSI C,没有像51那样扩展了位操作(布尔操作),虽然汇编指令里面有SBI/CBI/SBIC/SBIS指令

所以需要采用 位逻辑运算 来实现,这是必须要掌握的。

IO口和功能寄存器的操作方法一样,但对于部分功能寄存器的读写有特殊要求,请参看手册。

不必考虑代码效率的问题,如果可能,GCCAVR会自动优化为SBI/CBI/SBIC/SBIS指令,跟汇编的效率是一样的。

例如 iom16.h 里面定义了 #define PA7 7

(这标准头文件定义了MCU的所有官方定义(包括寄存器,位,中断入口等),但管脚的第二功能没有定义)

想PA7为1 PORTA|=(1<

想PA7为0 PORTA&=~(1<

想PA7取反 PORTA^=(1<

想检测PA7是否为1 if (PINA&(1<

想检测PA7是否为0 if !(PINA&(1<

* << 为左移运算符,不懂的就要好好复习C语言基础了。

注意IO操作的顺序:

//上电默认DDRx=0x00,PORTx=0x00 输入,无上拉电阻

假设PA口驱动LED的负极,低电平灯亮

初始化方法1:

PORTA=0xFF; //内部上拉,高电平

DDRA=0xFF; //输出高电平---------灯一直是灭的

初始化方法2:

DDRA=0xFF; //输出低电平--------灯被错误点亮了

PORTA=0xFF; //输出高电平--------马上被熄灭了,时间很短(1个指令不到uS时间),灯闪了一下,眼睛无法察觉

但要是这个IO口是控制炸药包的点火信号呢?工控场合要考虑可靠性的问题

模拟OC结构的IIC总线的技巧:

虽然AVR大多带有硬件IIC接口,但也有需要使用软件模拟IIC的情况

可以通过使用外部上拉电阻+控制DDRx的方法来实现OC结构的IIC总线。

IIC的速度跟上拉电阻有关,内部的上拉电阻阻值较大(Rup=20K~50K),只能用于低速的场合

#define SDA 0 //PC0

#define SCL 1 //PC1

(程序初始化设定 SDA和SCL都是 PORT=0,DDR=0)

#define SDA_0() DDRA|=(1<

#define SDA_1() DDRA&=~(1<

#define SCL_0() DDRA|=(1<

#define SCL_1() DDRA&=~(1<

使用上面的SDA_0()/SDA_1()/SCL_0()/SCL_1()宏即可,直观,而且效率跟汇编是一样的。 

声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 【7.24 深圳】2025国际AI+IoT生态发展大会/2025全球 MCU及嵌入式技术论坛


  • 相关技术文库
  • 单片机
  • 嵌入式
  • MCU
  • STM
  • 3AT89C51单片机引脚说明及引脚图

    AT89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU...

    前天
  • 51单片机对LCD1602液晶的驱动设计

    51单片机——LCD1602 1、1602液晶读写时序 (1)、读状态 RS=L,R/W=H,E=H。(判断忙完毕后释放总线) (2)、读数据 RS=H,R/W=H,E=H。 (3)、写指令 RS=L,R/W=L,D0~D7=指令码,E=高脉冲 (4)、写数据 RS=H,R/W=L,D0~D...

    前天
  • 单片机串口如何接收不定长数据的?

    我们在使用其他STM32的单片机的时候,会发现有些困难,会发现常用的方法并不能用,在还没有接收完数据的时候,就解决不了。于是,只能用通用的方法来解决了。 这个通用的方法,其实原理和使用IDLE的原理一样:...

    前天
  • ARM处理器的选型原则

    鉴于ARM微处理器的众多优点,随着国内外嵌入式应用领域的逐步发展,ARM微处理器必然会获得广泛的重视和应用。但是,由于ARM微处理器有多达十几种的内核结构,几十个芯片生产厂家,以及千变万化的内部功能配置组合,...

    07-10
  • 有哪些低功耗设计方法?单片机系统低功耗设计要点介绍

    功耗,已经是一个老生常谈的话题了。对于功耗,大家多多少少有所了解。目前,很多产品的宣传里便带有低功耗噱头。为增进大家对功耗的认识,本文将基于两点介绍功耗:1.低功耗主要设计方法,2.单片机系统低功耗设计...

    07-10
  • 8位32位MCU如何选择?如何选择合适的MCU?

    MCU,对于普通人而言,是一个高大上的存在。但是,在工业中,MCU确实常见产品。为增进大家对MCU的认识,本文将基于两点介绍MCU:1.8位MCU和32位MCU如何选择?2.如何选择合适的MCU。如果你对MCU具有兴趣,不妨继续往...

    07-09
  • ARM开发:一 ARM微处理器概述

    1.1ARM-Advanced RISC Machines ARM(Advanced RISC Machines),既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。 1991年ARM公司成立于英国剑桥,主要出售芯片设计技术...

    07-08
  • 分析C51单片机的一些误区和注意事项

    简介:常看见初学者要求使用_at_,这是一种谬误,把C当作ASM看待了。在C中变量的定位是编译器的事情,初学者只要定义变量和变量的作 用域,编译器就把一个固定地址给这个变量。怎么取得这个变量的地址?要用指针。 1) C...

    07-08
  • 51单片机几个延时程序

    简介:51单片机几个精确延时程序:在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响. 一. 500ms延时子程序(晶振12MHz,一个机器周期1us.) 程...

    07-08
  • 总结单片机软件抗干扰的几种办法

    简介:在提高硬件系统抗干扰能力的同时,软件抗干扰以其设计灵活、节省硬件资源、可靠性好越来越受到重视。下面以MCS-51单片机系统为例,对微机系统软件抗干扰方法进行研究。 1、软件抗干扰方法的研究 在工程实践中...

    07-08
  • 基于C51单片机实现汽车座椅自动控制系统的软硬件设计

    引言 随着人们生活水平的提高,对汽车座椅的舒适性要求也越来越高,要求对汽车座椅地调节能够更加简单、方便、快捷。目前,汽车座椅位置的调节多采用基于手动调节方式的机械和电动控制两种方式。汽车座椅位置的调节...

    07-02
  • MCS51单片机程序设计时堆栈的计算方法解析

    用C语言进行MCS51系列单片机程序设计是单片机开发和应用的必然趋势。Keil公司的C51编译器支持经典8051和8051派生产品的版本,通称为Cx51。应该说,Cx51是C语言在MCS51单片机上的扩展,既有C语言的共性,又有它自己...

    07-02
下载排行榜
更多
评测报告
更多
广告