IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 【MSP430G2553】图形化开发笔记(3) GPIO -> 正文阅读

[嵌入式]【MSP430G2553】图形化开发笔记(3) GPIO

平台:
Code Composer Studio 6.2.0 + Grace 2.2.0
MSP430G2553 LaunchPad? Development Kit (MSP-EXP430G2ET)


??以下大部分内容摘自《LaunchPad口袋实验平台 —— MSP-EXP430G2篇》傅强、杨艳 编著(TI大学计划嵌入式微控制器技术丛书)

概述

??这是 MSP430G2553 单片机P1.0-P1.2 的原理框图,其他 IO 口的结构还不完全一样。
在这里插入图片描述
??为什么 IO 口需要这么复杂的构造呢,我们来列举一下:

  1. 对集成电路来说,input 和 output 就是需要两套电路来实现的,并不是像一根导线那样信号能左右互通。这两套电路要有切换装置,否则输入输出会互相矛盾,于是有了 IO 方向寄存器 PxDIR。
  2. IO 口作为输入口时,如何把输入信号“告诉”CPU 呢?需要通过外部电路将寄存器PxIN 置位或复位,这样 CPU 就能随时读取寄存器 PxIN 的值了。
  3. CPU 如何命令 IO 口输出某一电平呢?CPU 需要去写寄存器 PxOUT,然后会有相应的缓冲电路将 PxOUT 的信号传递到单片机的外部引脚处。
  4. 数字电路中实现高低电平有多种方式,上拉(强 0 弱 1)、下拉(强 1 弱 0)还是图腾柱(强 1 强 0)的性质有很大差别,PxREN 寄存器用于控制内部上下拉电阻。
  5. 所有 MSP430 单片机的 P1 和 P2 口是带中断的。中断可不是“吱一声”就能有的,需要复杂的配套电路,这就有了是否允许 IO 中断寄存器 PxIE,中断标志位寄存器PxIFG,中断的边沿选择寄存器 PxIES。
  6. 对于高性能单片机,IO 口是高度复用的。何为复用呢,就是本来某功能最好是自己长出个引脚出来,现在被迫与 IO 共用引脚了。所以又需要选择开关了,PxSEL 和PxSEL2 寄存器就是干这个的。
  7. 部分 MSP430 单片机的 IO 口带振荡器,可以在不附加任何外部器件的情况下,实现电容触摸按键的识别,最流行的电容触摸也可以有。

??以上总总迹象表明,IO 口没有最复杂只有更复杂,我们不关心用了多少硬件电路才实现了 IO 的这些功能,我们关心怎么配置寄存器去享用这些功能。

IO 的一般读写控制

??读写 IO 口前,必须先设置 PxDIR,PxDIR 高电平代表 IO 是输出,低电平代表 IO 口是输入。CPU 读 IO,实际上是读 PxIN 寄存器。CPU 写 IO,实际是写 PxOUT 寄存器。
??提示:作为高阻输入 IO 时,务必关掉内部上下拉电阻开关 PxREN,否则输入就不是高阻
态了。

IO 的输出类型

??数字电路的输出有高电平 1、低电平 0 和高阻态 z。决定高低电平的是 VCC 和 GND,在初学者映像中,VCC 算电源,GND 不算电源,这样的理解不够准确和深刻。GND 也是电源,一样得有吞吐电流的能力,没有 GND 也就没有 VCC。准确的说 VCC 和 GND 都是电压源,所以 GND 经常用 VSS 来代替。根据输出电平的“强弱”分类,可将 IO 输出分为图腾柱输出、上拉电阻输出、下拉电阻输出 3 种。

图腾柱输出

??图腾柱、推挽/推拉、Push and Pull、Totem Pole 指的都是同一种电路。下图是图腾柱输出电路简图,图中的开关是受控电子开关,可以由三极管或场效应管构成。由两个开关分别连接 VCC 和 VSS 构成的输出电路称为图腾柱输出,此电路输出为强 1,强 0。
在这里插入图片描述

  1. 如 (a) 所示,无论OUTPUT被接在什么电路上,OUTPUT一定是高电平1,这就是所谓的输出强1。
  2. 如 (b) 所示,无论OUPUT被接在什么电路上,OUTPUT一定是低电平0,这就是所谓输出强0。
  3. 如 ? 所示,输出为高阻Z,这代表不会对其他电路造成影响。当作为输入口时,OUTPUT 应置为高阻态。

??有人可能有疑问,OUTPUT 为强 1 输出接在外部电路的 GND 上会怎样?会短路。那么这种情况下到底还是不是输出 1 呢,这个问题是典型的“自相矛盾”。对于理想电压源VCC,接在哪都得是 VCC,同样对于理想的地,谁接在上面都是 0V,短路情况下到底电压是多少伏,那要看 VCC 和 GND 哪个先“扛不住”了。
??初学者还有一个观点,编程并不会“实质性”损坏硬件电路,这也是不确切的。如下图(b)所示,当两个 IO 口相连(这是极其正常普遍的),且两个 IO 是图腾柱输出的话,编程就可以造成硬件损坏

??1) 当程序使得器件 1 输出强 0,器件 2 输出强 1,短路便发生了,是否会永久损坏硬件视短路持续时间的长短。
??2) 如果像下图(b)那样,两个图腾柱 IO 都设置为输出,发生短路是迟早的事情。正确的做法是像下图(a)那样,将器件 2 的图腾柱输出变为高阻态,仅作为输入口使用。
??3) 现在的新型单片机的 IO 口,多数属于图腾柱输出,所以,在使用 IO 口前正确配置IO 方向尤为重要。从安全考虑,CPU 上电后所有 IO 一般都会设置为下图(a)器件2 那样的输入状态,也就是图腾柱输出为高阻。
在这里插入图片描述

下拉电阻输出

??下图所示为下拉电阻输出,该电路为强 1 弱 0 电路。
??下图(a)输出为弱 0,为什么叫弱 0 呢?因为实际 OUTPUT 输出电平是不是 0 还取决于接什么样的负载。
在这里插入图片描述
??1) 如上图(c)所示,器件 1“打算”输出 0 给器件 2,但是器件 2 不是高阻输入结构(比如 TTL 电平器件),那么器件 2 是否能正确识别输入为 0 电平,取决于 R1 和R2 的比值,以及器件 2 的 1/0 识别门限值。
??2) 下拉电阻 R1 越小,电平逻辑错误就越不易发生,但是这是以功耗为代价的。

??上图(b)的输出为强 1,无论 OUTPUT 接什么负载,均输出高电平 1。这就是强 1 弱 0 的由来。
??与图腾柱输出不同,两个下拉电阻输出的 IO 口相连,永远不会发生短路(前提是两 IO 的 VCC 必须等电位)。

上拉电阻输出

??下图所示为上拉电阻输出,该电路为强 0 弱 1 电路。
??下图(a)输出为弱 1,为什么叫弱 1 呢?
??1) 如果 OUTPUT 接的是高阻负载,输出肯定是 1。
??2) 其他负载情况则需根据负载和上拉电阻的分压关系来计算。
??3) 如下图?所示,要根据负载情况合理设定上拉电阻的取值。
??下图(b)的输出为强 0,无论 OUTPUT 接什么负载,均输出低电平 0。这就是强 0 弱 1的由来。
??同样两个上拉电阻输出的 IO 口相连,永远不会发生短路(前提是两 IO 的 VSS 必须等电位)。
在这里插入图片描述
??上拉电阻输出的应用范围非常广泛:

  1. 上拉电阻输出可用于两种供电电压器件之间的电平匹配。如下图所示,器件 1 供电电压为 VCC1,器件 2 的供电电压为 VCC2。通过外置上拉电阻到 VCC2,器件 1 可实现与器件 2 的输出电平匹配。这种输出方式的芯片,说明书中会称为集电极开路输出(OC 输出)或漏极开路输出(OD 输出),两者区别是开关使用的是三极管还是场效应管。凡是 OC 或 OD 输出的数字器件,一定要外接上拉电阻到 VCC,否则器件将无法得到高电平。
    在这里插入图片描述
  2. 上拉电阻输出还广泛用于实现“线与”逻辑。如下图所示,所有器件输出和输入同时进行(图腾柱无法做到这一点),任何一个器件都可以将公共总线电平拉低,但只有所有器件输出都为“高”,公共总线的电平才能为高,这就是“线与”逻辑“线与”逻辑更独特之处在于,所有器件都可以通过输入缓冲一直“监视”总线电平的高低,这样就能知道总线电平是否与“自己期望电平”一致,从而判断是否有别的器件在与自己争夺总线。“线与”逻辑广泛用干多机总线通信中。
    在这里插入图片描述

MSP430 单片机的 IO 输出

IO 的内部电阻

??MSP430 单片机的内部电阻构造如下图所示:
在这里插入图片描述

  1. PxREN.y 控制位决定了是否引入内部电阻。默认值 PxREN.y=0 时,不接入内部电阻。
  2. 当配置 PxREN.y=1 时,内部电阻被接入电路。电阻一端固定接在了 IO 输出端,至于另一端是接在 VCC(DVCC)还是 GND(DVSS),则由 PxOUT.y 决定。
  3. PxOUT.y 在图 5.8 中,即决定 IO 输出电平,又决定上下拉电阻的接法,要特别注意

注:芯片说明书中,PxOUT(PxREN)中的 x 代表端口号,如 P1 和 P2。PxOUT.y(
PxREN.y)中 y 的意思是某个具体的 IO,例如 P1.3 中的 3。

??MSP430 的 IO 口内部电阻与 5.3 节的“上拉输出”还是“下拉输出”本质不同,因为图腾柱输出并联上拉下拉电阻丝毫不会改变输出电平值!所以,MSP430 只有一种输出方式——图腾柱输出。
??那 MSP430 的内部电阻有什么用呢?

  1. 当IO口设为输入口时,内部电阻可通过写PxOUT.y 位固定配置为上拉或是下拉,这样就可以作为输入按键的上下拉电阻使用。
  2. 如下图(a)所示,按键电路输入高电平1是可靠的,但是输入低电平0则不可靠因为按键不按下时输入被悬空,电平浮动。
  3. 下图 (b) 所示电路中,启用了内部电阻R并置于下拉,这样一来,输入低电平就是稳定的。
  4. 同理,也可将开关接在VSS端,使用上拉电阻的方式构建按键电路。

在这里插入图片描述

线与逻辑的实现

在这里插入图片描述
??线与逻辑在总线通信中非常有用,普通 51 单片机的 IO 口类似上图中的器件,为上拉电阻输出,天生具备线与逻辑功能。MSP430 的 IO 输出只能是图腾柱输出,如何实现“线与”呢?MSP430 单片机模拟线与逻辑输出:

  1. 如下图所示,首先外接上拉电阻 R。这里要注意,一定不能使用单片机 IO 内部电阻充当上拉电阻,因为内部电阻在 IO 处于输出状态是无法固定为上拉的(输出高电平时为上拉,输出低电平时为下拉)。
  2. 当需要输出线与逻辑 1 时,把 MSP430 IO 设为输入状态即可。
  3. 当需要输出线与逻辑 0 时,则正常输出低电平即可。

在这里插入图片描述
??在实际编程中,可以用宏定义来消除“模拟”线与逻辑带来的不便。例如,将 P1.0 设为线与逻辑输出,可以用如下宏定义来描述:

#define P10_ON P1DIR &= ~BIT0 // IO设为输入,相当于线与输出1
#define P10_OFF P1DIR |= BIT0; P1OUT &= ~BIT0 // IO 设为输出,输出 0

??注:宏定义是完全替换代码的意思,所以要注意分号的使用。
??这样在后续的程序中,就可以用 P10_ON 和 P10_OFF 代替输出高低电平代码。使用宏定义来消除“硬件差异”的做法是极其有用的编程思想。

MSP430 单片机的 IO 输入中断

IO 外部中断使用方法

??高级单片机的全部 IO 口都带外部中断功能,比如 ARM 系列。MSP430 单片机只有 P1和 P2 口带外部中断功能。要使用外部中断,遵循以下步骤:

  1. 通过 PxDIR 将 IO 方向设为输入。
  2. 通过写 PxIES,决定中断的边沿是上升沿、下降沿或两种情况均中断。
  3. 如果是机械按键输入,可以通过 PxREN 启用内部上下拉电阻,根据按键的接法,设定 PxOUT(决定最终是上拉电阻还是下拉电阻)。
  4. 通过配置 PxIE 寄存器开启 IO 中断,通过“_enable_interrupts();”开启总中断。
  5. 在中断子函数中,通过 if 语句查询具体中断的 IO 口,如果是机械按键输入,还需有消抖代码。
  6. 根据具体 IO 的输入,编写事件处理函数。
  7. 退出中断前,使用“PxIFG = 0;”来清除 IO 中断标志位。

机械按键的消抖

??如下图所示,机械按键按下和弹起时,会有毛刺干扰。在一次按键过程中,会有若干次下降沿,只有①是真正的按键事件。如何避免其他几次下降沿“中断”的影响呢?
在这里插入图片描述

  1. 检测到下降沿①和④后用延时可以消灭②、③、⑤。
  2. ①延时后,电平仍然是 0,④延时后,电平会变成 1。据此用 if 语句可判断出④不是按下,而是弹起的毛刺。

Grace中配置GPIO

点击GPIO模块,如Port P1,
在这里插入图片描述

GPIO-Overview

在这里插入图片描述
??该页部分内容机翻如下:

介绍

??MSP430器件最多可以实现八个数字I/O端口,即P1至Px。每个端口有八个I/O引脚。每个I/O引脚都可以单独配置为输入或输出方向,并且每个I/O线都可以单独读或写。端口P1和P2具有中断能力。在一些设备上有更多的中断能力的引脚。P1和P2 I/O线的每个中断可以单独启用和配置,以便在输入信号的上升沿或下降沿提供中断。所有的P1 I/O线的来源是一个单一的中断向量,而所有的P2 I/O线的来源是一个不同的单一中断向量。
??请注意,在Grace中,通过直接操作GPIO模块的引脚配置应该最后进行,因为Grace管理的外设模块会自动执行所需的引脚设置。

用例:端口引脚配置为输出方向

??在引脚被配置为I/O功能和输出方向的情况下,每个PxOUT寄存器中的个别位代表相应I/O引脚的输出值。在这种模式下,内部上拉/下拉电阻被禁用。位=0时,输出被设置为低电平,位=1时,输出被设置为高电平。

??Grace配置

  1. 在GPIO模块中选择适用器件封装的Pinout View
  2. 从P1.5和P1.7的下拉框中,选择GPIO输出选项
  3. 要选择GPIO输出的高电平或低电平状态,请导航到Power User视图来配置

??用户代码:

// Drive P1.5, P1.7 output high
P1OUT |= (BIT5 + BIT7);

// Drive P1.5, P1.7 output low
P1OUT &= ~(BIT5 + BIT7);

用例:端口引脚配置为输入方向

??在引脚被配置为I/O功能和输入方向的情况下,每个PxIN寄存器中的个别位代表相应I/O引脚的输入值。PxIN寄存器是只读寄存器。位=0表示外部输入信号为低,位=1表示为高。

??Grace配置

  1. 在GPIO模块中选择适用器件封装的Pinout View
  2. 从P1.5的下拉框中,选择GPIO输入选项

??用户代码:

// Check P1.5 input status
if (P1IN & BIT5) {
    // P1.5 input level = logic high
    // >>>>>>>> Fill-in user code here <<<<<<<<
}

// Check P1.5 input status
if (!(P1IN & BIT5)) {
    // P1.5 input level = logic low
    // >>>>>>>> Fill-in user code here <<<<<<<<
}

用例:使用轮询对端口输入引脚进行事件捕获

?? 端口引脚P1.5被配置为I/O功能,输入方向。P1.5被轮询,直到读取逻辑高电平作为输入电平。

??Grace配置

  1. 在GPIO模块中选择适用器件封装的Pinout View
  2. 从P1.5的下拉框中,选择GPIO输入选项

??用户代码:

// Loop until P1.5 input level = logic high
while (!(P1IN & BIT5));

// P1.5 input level = logic high
// >>>>>>>> Fill-in user code here <<<<<<<<

用例:使用中断对端口输入引脚进行事件捕获

??端口P1和P2的每个引脚都有中断能力。每个PxIFGx位是其对应的I/O引脚的中断标志,当选定的输入信号边沿在该引脚发生时,该标志被置位。每个PxIFG端口的中断标志必须用软件复位。
??例子:端口引脚P1.5被配置为I/O功能,输入方向,端口中断与适当的端口中断边沿选择(低到高或高到低转换)一起被启用。在等待端口1中断时,器件被置于LPM状态。P1.5引脚上的适当信号边沿触发了端口中断,端口1中断服务例程被用来处理用户固件中的这一事件。

??Grace配置

  1. 在GPIO模块中选择适用器件封装的Pinout View
  2. 从P1.5的下拉框中,选择GPIO输入选项
  3. Power User视图中,选择中断启用下拉框,并选择下降沿或上升沿触发的中断启用。

??用户代码:

// Enter LPM with global interrupt enabled
__bis_SR_register(LPM0_bits + GIE);

// On P1.5 rising edge capture event, device wakes up to service Port ISR
// >>>>>>>> Fill-in user code here <<<<<<<<

导航到InterruptVectors_init.c文件,在Port1 ISR的用户代码部分之间添加以下代码。

    /* USER CODE START (section: PORT1_ISR_HOOK) */

    // Rising edge captured on P1.5 input pin
    P1IFG &= ~BIT5; // Clear P1.5 IFG

    // >>>>>>>> Fill-in user code here <<<<<<<<
    /* USER CODE END (section: PORT1_ISR_HOOK) */

Pinout View模式

框内为不同封装的配置视图
在这里插入图片描述

Pinout 32-QFN

在这里插入图片描述

Pinout 20-TSSOP/20-PDIP

在这里插入图片描述

Pinout 28-TSSOP

在这里插入图片描述

Power User模式

在这里插入图片描述
??该页部分内容机翻如下:

??在这个Power User视图选择中,你可以将每个单独的GPIO引脚启用上拉/下拉电阻和/或使能上升/下降沿的GPIO中断启用。
??注1:对于最低功率配置,将所有未使用的GPIO引脚设置为输出端口方向。。.
??注2:只有当GPIO被配置为输入方向的引脚时,上拉/下拉电阻的配置才在设备上可用。

??中断处理程序的启用可以独立于中断启用。然而,当中断被启用时,中断处理程序会自动启用,以确保正确的运行时执行。要启用每个GPIO端口中断处理程序,请单击下面相应的处理程序按钮。

在这里插入图片描述

寄存器模式

在这里插入图片描述
??该页部分内容机翻如下:

??备注:通过启用中断处理程序,Grace在src文件夹下的InterruptVectors_init.c文件中生成了一个完全工作的中断服务程序。用户可以在ISR的指定区域内插入代码,并且代码被保留下来。当用户禁用中断处理程序时,用户插入的代码会保留在文件的底部,如果用户重新启用中断处理程序,会自动重新插入。当不再需要时,用户也可以手动删除这些代码。

上机实战

??参照【MSP430G2553】图形化开发笔记(1) 配置环境建立工程。

目标

??实现LED1闪烁,LED2由S1控制翻转。

在这里插入图片描述
在这里插入图片描述

配置Grace

??配置电压:
在这里插入图片描述
??配置主频为16MHz
在这里插入图片描述
??配置两个LED引脚 P1.0、P1.6为GPIO Output,
??由于按键S1 的P1.3未按下时由上拉电阻保持为高电平,按下后接地为低电平,故设为下降沿触发:
在这里插入图片描述

编程

main.c

??主循环:以1s为周期闪烁D1:

/*
 * ======== Standard MSP430 includes ========
 */
#include <msp430.h>

/*
 * ======== Grace related includes ========
 */
#include <ti/mcu/msp430/Grace.h>


#define MCLK_IN_HZ      16000000

#define delay_us(x)     __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x)     __delay_cycles((MCLK_IN_HZ/1000*(x)))

/*
 *  ======== main ========
 */
int main(void)
{
    Grace_init();                   // Activate Grace-generated configuration
    
    // >>>>> Fill-in user code here <<<<<
    while(1)
    {
    	P1OUT |= BIT0;
    	delay_ms(500);
    	P1OUT &= (~BIT0);
    	delay_ms(500);
    }
//    return (0);
}

InterruptVectors_init.c

在这里插入图片描述

#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR_HOOK(void)
{
    /* USER CODE START (section: PORT1_ISR_HOOK) */
    /* replace this comment with your code */

#define MCLK_IN_HZ      16000000

#define delay_us(x)     __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x)     __delay_cycles((MCLK_IN_HZ/1000*(x)))

	if(P1IFG & BIT3)
	{
		P1IFG &= ~BIT3; // Clear P1.3 IFG
		delay_ms(20);
		if((P1IN & BIT3) == 0)
		{
			if(P1OUT & BIT6)
				P1OUT &= ~BIT6;
			else
				P1OUT |= BIT6;
			while((P1IN & BIT3) == 0);
			delay_ms(20);
		}
	}
    /* USER CODE END (section: PORT1_ISR_HOOK) */
}

现象

烧录后可见LED1闪烁,LED2可由S1控制翻转。

在这里插入图片描述
在这里插入图片描述

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-10-08 20:58:04  更:2022-10-08 20:59:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 20:36:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码