|
在本教程中,我们将一起学习MSP430单片机GPIO的编程方法。本文也适用于Launchpad开发板上使用的MSP430x2xx器件,如MSP430G2553、MSP430G2231等。MSP430单片机上的大多数引脚被分组为最多8个端口, P1到P8。每个端口都是8位宽,并有8个相关的I / O引脚。这些引脚直接映射到相应的端口寄存器,因此可以独立操作I / O引脚。只有端口P1和P2中的引脚支持中断。 此外,每个I / O引脚还具有可配置的上拉和下拉电阻。 每个端口都有一组相关的寄存器,用来操作各个引脚。 位映射和端口分组如下所示:
注意:在编程指南/数据手册中使用的引脚的命令约定是'Px.y',其中'x'对应的是端口号(1到8),'y'对应的是引脚号(0到7) X'。例如:P1.1是指端口1的第1引脚,P2.4是指端口2的第4引脚。您将看到与在MSP430 Launchpad开发板上标记引脚相同的约定。
当前版本的MSP430G2 Launchpad使用的是MSP430G2553和MSP430G2452。旧版本(Rev1.4)使用的是MSP430G2231和MSP430G2211。但是,除非另有说明,对于所有支持的器件,编程方法都是一样的。
MSP430单片机的GPIO寄存器 GPIO模块有许多寄存器。我们只会介绍本教程涉及的一些数字I / O寄存器。我将在其他的教程中介绍与中断相关的寄存器(即PxIFG,PxIES,PxIE)。 1. PxDIR:GPIO方向控制寄存器。将此寄存器中的任何位设置为0将会将相应的引脚[0至7]配置为输入,而将其设置为1将配置为输出。 2. PxIN(只读):用于读取配置为输入的数字I / O引脚的值。 0 =输入为低电平,1 =输入为高电平。 3. PxOUT:当上拉/下拉电阻被禁用时,用于直接将值写入引脚。 0 =输出为低电平,1 =输出为高电平。上拉/下拉电阻使能时:0 =引脚拉低,1 =引脚拉高。 4. RxREN:对于配置为输入的引脚,PxREN用于为给定引脚启用上拉/下拉电阻,PxOUT与PxREN一起用于选择上拉或下拉电阻。将位设置为1将启用相应引脚的上拉/下拉电阻,同时将其设置为0将禁用相同的引脚。 PxDIR | PxREN | PxOUT | I / O配置 | 0 | 0 | X | 输入,禁用电阻 | 0 | 1 | 0 | 使能内部下拉的输入 | 0 | 1 | 1 | 使能内部上拉的输入 | 1 | X | X | 输出, PxREN无效 |
5. PxSEL&PxSEL2:由于大多数端口引脚多达4种不同的功能,我们需要一种机制来选择这些功能。这是使用PxSEL和PxSEL2寄存器来实现的。特定引脚的这些寄存器的位组合将选择特定的引脚功能。位组合如下所示: PxSEL2(第n位) | PxSEL(第n位) | 引脚功能 | 0 | 0 | GPIO(数字I / O)功能 | 0 | 1 | 主要外设功能 | 1 | 0 | 保留。查阅设备特定的数据表。 | 1 | 1 | 辅助外围功能 |
另请注意,PxSEL / PxSEL2寄存器不会根据模块功能的要求更改引脚方向。确保使用PxDIR寄存器按照复用功能的要求设置正确的引脚方向。
使用C / C ++的MSP430的GPIO编程和示例代码 前提条件:在我们开始编程gpio之前,您需要对C / C ++中的二进制和十六进制系统以及按位运算有基本的了解,下面是两个可以参考的教程(或者如果您已经熟悉这些教程,可以跳过这些教程并继续): ● 嵌入式编程的十六进制和二进制数字系统基础知识 ● 教程:嵌入式编程基础C - 位操作
msp430.h是所有MSP430器件的通用头文件。该头文件识别您的器件,并相应地包含器件具体的头文件。每个器件具体的头文件还包括从BIT0到BITF的位定义。其中BITn等于(1 << n),即第n个位的位置是1,其余位是0。
现在让我们看看我们如何给寄存器赋值。我们可以使用十六进制符号和十进制表示法来赋值。如果您的编译器支持其他符号,如二进制符号,也可以使用。比方说,我们要设置Port 1的PIN 6作为输出。它可以通过以下方式完成: - 方式1. P1DIR =(1 << 6); //(二进制左移 - 直接赋值:其他引脚设置为0)
- 方式2. P1DIR | = 0x20; //或0x20; (十六进制 - 或分配:其他引脚不受影响)
- 方式3.P1DIR | =(1 << 6); //(二进制左移 - 或分配:其他引脚不受影响)
- 方式4. P1DIR | = BIT6; //同上,使用标准BIT定义
复制代码
● 在许多情况下,必须避免使用方式1,因为我们直接为寄存器赋值。因此,当我们将P1.6'1'设置为'1'时,其他的被强制分配一个'0',这个'0'可以通过或操作来避免,然后赋值。 ● 如果需要批量更改某些位,则可以使用方式2 ● 方式3和方式4可以在需要改变某些或者一个位时使用。
这里首先要注意的是,十六进制表示法中前面的零可以被忽略,因为它们没有任何意义,因为我们在这里使用了无符号值(仅为正值),它们被分配给寄存器。 例如。0x4和0x04表示的意思一样。 请注意,位7是最左边的MSB,位0是最右边的LSB,它代表Big Endian格式。 因此,位0是右边的第一位,位1是右边的第二位,依此类推。 BIT和PIN码是基于零的索引值。
使用C / C++的基本示例代码 示例 1) 假设我们希望将端口1的引脚0(即P1.0)配置为输出并希望将其驱动为高电平。可以使用下面的方法: - P1DIR | = BIT0; //与(1 << 0)和0x1相同,将P0.1配置为输出
- P1OUT | = BIT0; // P1.0输出高电平
复制代码
示例 2) 将引脚P1.4配置为输出,并单独设置为低电平而不影响其他位,可以通过以下方式: - P1DIR | = BIT4; //将P1.4配置为输出
- P1OUT&=〜BIT4; //只有P1.4变低
复制代码
示例3) 将P1.4和P1.6配置为输出并将它们设置为高电平: - P1DIR | = BIT4 | BIT6; //将P1.4和P1.6配置为输出
- P1OUT | = BIT4 | BIT6; //驱动P1.4和P1.6的HIGHT
复制代码
示例 4) 配置端口1的所有引脚(P1.0至P1.7)为输出并将其设置为高电平: - P1DIR = 0xFF; //将P1的所有引脚配置为输出
- P1OUT = 0xFF; //将所有引脚驱动为高电平
复制代码
示例 5) 在此示例代码中,我们将配置引脚P1.3作为内部上拉的输入: - P1DIR&=〜BIT3; //配置P1.3作为输入(复位后也总是输入)
- P1REN = BIT3; //为P1.3启用上拉/下拉
- P1OUT = BIT3; //为P1.3选择上拉电阻
复制代码
示例 6) 我们可以检查上面配置的输入引脚P1.3的当前状态,如下所示: - if(P1IN & BIT3)
- {
- //P1.3为高电平
- }
- else
- {
- //P1.3为低电平
- }
复制代码
示例 7) 假设我们已经配置P1.4作为输入,并且启用上拉电阻,我们要连续扫描P1.4,直到出现一个低电平的引脚。这可以实现如下: - P1DIR &= ~BIT4; //Configure P1.4 as Input
- P1REN = BIT4; //Enable Pullup/down for P1.4
- P1OUT = BIT4; //Select Pullup resistor for P1.4
- if(..)
- {
- while( !(P1IN & BIT4) ); //等待,直到P1.4为低电平
- /*do something after loop terminates*/
- }
复制代码
|