注意:
(1)使用库函数之前,要导入MSP430Ware。
(2)如果只想看中断部分,直接看实验2。
(3)因为部分库函数MSP430F5529不支持(列在下面),所以我就不讲。
GPIO_setAsPeripheralModuleFunctionOutputPin()
GPIO_setAsPeripheralModuleFunctionInputPin()
GPIO_setAsOutputPin()
函数声明
void GPIO_setAsOutputPin(uint8_t selectedPort, uint16_t selectedPins);
作用
让指定引脚为输出
参数
selectedPort
selectedPort表示哪个端口,可选参数如下
//! - \b GPIO_PORT_P1 //! - \b GPIO_PORT_P2 //! - \b GPIO_PORT_P3 //! - \b GPIO_PORT_P4 //! - \b GPIO_PORT_P5 //! - \b GPIO_PORT_P6 //! - \b GPIO_PORT_P7 //! - \b GPIO_PORT_P8 //! - \b GPIO_PORT_P9 //! - \b GPIO_PORT_P10 //! - \b GPIO_PORT_P11 //! - \b GPIO_PORT_PA //! - \b GPIO_PORT_PB //! - \b GPIO_PORT_PC //! - \b GPIO_PORT_PD //! - \b GPIO_PORT_PE //! - \b GPIO_PORT_PF //! - \b GPIO_PORT_PJ
selectedPins
selectedPins表示哪个具体的Pin,可选参数如下
//! - \b GPIO_PIN0 //! - \b GPIO_PIN1 //! - \b GPIO_PIN2 //! - \b GPIO_PIN3 //! - \b GPIO_PIN4 //! - \b GPIO_PIN5 //! - \b GPIO_PIN6 //! - \b GPIO_PIN7 //! - \b GPIO_PIN8 //! - \b GPIO_PIN9 //! - \b GPIO_PIN10 //! - \b GPIO_PIN11 //! - \b GPIO_PIN12 //! - \b GPIO_PIN13 //! - \b GPIO_PIN14 //! - \b GPIO_PIN15 //! - \b GPIO_PIN_ALL8 //! - \b GPIO_PIN_ALL16
修改的寄存器
修改了PxDIR ,PxSEL
使用
现在我们让P1.0为输出
//P1.0为输出 GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN0)
与GPIO_setAsOutputPin()参数一致的函数
GPIO_setOutputHighOnPin()
让指定引脚输出高电平,例如让P1.0输出高电平
寄存器修改了PxOUT
1. //P1.0输出高电平 2. GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN0);
GPIO_setOutputLowOnPin()
让指定引脚输出低电平,例如让P1.0输出低电平
寄存器修改了PxOUT
//P1.0输出低电平 GPIO_setOutputLowOnPin(GPIO_PORT_P1,GPIO_PIN0);
GPIO_toggleOutputOnPin()
反转指定引脚电平,引脚如果为高电平,使用函数之后就是低电平。引脚如果为低电平,使用函数之后为高电平。例如让P1.0电平反转。
寄存器修改了PxOUT
//反转P1.0电平 GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0);
GPIO_setAsInputPin()
让指定引脚为输入,例如让P2.1为输入。
寄存器修改了PxDIR ,PxREN ,PxSEL
//P2.1为输入 GPIO_setAsInputPin(GPIO_PORT_P2,GPIO_PIN1);
GPIO_setAsInputPinWithPullDownResistor()
让指定引脚为上拉输入。注意,使用这个函数之前,不需要先使用GPIO_setAsInputPin()让引脚为输入。我们与GPIO_setAsInputPin()对比发现,他多修改了一个PxOUT寄存器
寄存器修改了PxDIR ,PxOUT,PxSEL ,PxREN
让P2.1为下拉输入。
//P2.1为下拉输入 GPIO_setAsInputPinWithPullDownResistor(GPIO_PORT_P2,GPIO_PIN1);
GPIO_setAsInputPinWithPullUpResistor()
与GPIO_setAsInputPinWithPullDownResistor()几乎一致,不过他这个PxOUT设置的是上拉。
作用就是让指定引脚为上拉输入。
让P2.1为下拉输入。
//P2.1为上拉输入 GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P2,GPIO_PIN1);
GPIO_getInputPinValue()
获取引脚输入值,比如说按键按下为低电平,那么我们读取电平就要使用这个函数。
没有修改寄存器,而是读取PxIN寄存器。如果为高电平返回GPIO_INPUT_PIN_HIGH(值为1),低电平返回GPIO_INPUT_PIN_LOW(值为0)。
例如检测P2.1电平
if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN1) == GPIO_INPUT_PIN_HIGH) { ... } else { ... }
GPIO_enableInterrupt()
使能指定引脚上的中断。例如使能P2.1上中断
寄存器修改了PxIE
//使能P2.1引脚中断 GPIO_enableInterrupt(GPIO_PORT_P2,GPIO_PIN1);
GPIO_disableInterrupt()
与GPIO_enableInterrupt()一致,不过是失能中断。例如失能P2.1上中断
//失能P2.1引脚中断 GPIO_disableInterrupt(GPIO_PORT_P2,GPIO_PIN1);
GPIO_getInterruptStatus()
获取中断状态,并且返回相应的Pin。比如我现在设置了P2.1为上升沿中断,现在P2.1接收到一个上升沿之后。我们使用GPIO_getInterruptStatus()函数读取P2.1中断标识位,会返回GPIO_PIN1。如果P2.1没有发生上升沿,则返回一个0。
举例,我们读取P2.1,P1.1,P2.2三个引脚的中断标志位。你有两种写法,第一种更加规范,第二种也可以,因为0000 0010也是非0,也可以进入if语句。
//读取P2.1中断标志位 if(GPIO_getInterruptStatus(GPIO_PORT_P2,GPIO_PIN1) == GPIO_PIN1) { } if(GPIO_getInterruptStatus(GPIO_PORT_P2,GPIO_PIN1)) { } //读取P1.1中断标志位 if(GPIO_getInterruptStatus(GPIO_PORT_P1,GPIO_PIN1) == GPIO_PIN1) { } if(GPIO_getInterruptStatus(GPIO_PORT_P1,GPIO_PIN1)) { } //读取P2.2中断标志位 if(GPIO_getInterruptStatus(GPIO_PORT_P2,GPIO_PIN2) == GPIO_PIN2) { } if(GPIO_getInterruptStatus(GPIO_PORT_P2,GPIO_PIN2)) { }
GPIO_clearInterrupt()
清除中断标志位,操作的寄存器为PxIFG 。例如清除P2.1的中断标志位
//清除P2.1中断标志位 GPIO_clearInterrupt(GPIO_PORT_P2,GPIO_PIN1);
GPIO_selectInterruptEdge()
函数声明
void GPIO_selectInterruptEdge(uint8_t selectedPort, uint16_t selectedPins,uint8_t edgeSelect)
作用
选择指定引脚进行中断检测,只能上升沿或下降沿检测,无法进行双边沿检测。
注意,使用中断之前要将引脚设置为输入,同时要使能中断。
参数
selectedPort和selectedPins
selectedPort和selectedPins参数与GPIO_setAsOutputPin()一致
edgeSelect
选择上升沿触发或者下降沿触发,无法进行双边沿检测。可选参数如下
GPIO_HIGH_TO_LOW_TRANSITION //下降沿触发 GPIO_LOW_TO_HIGH_TRANSITION //上升沿触发
修改寄存器
仅修改了PxIES
使用
让P2.1为上升沿触发,注意,如果是上升沿触发,需要设置为下拉输入。如果是下降沿触发,需要提前设置为上拉输入。
//P2.1为上升沿触发 GPIO_selectInterruptEdge(GPIO_PORT_P2,GPIO_PIN1,GPIO_LOW_TO_HIGH_TRANSITION);
GPIO_setDriveStrength()
函数声明
void GPIO_setDriveStrength(uint8_t selectedPort, uint16_t selectedPins,uint8_t driveStrength)
作用
增强IO口驱动能力
参数
selectedPort和selectedPins
selectedPort和selectedPins参数与GPIO_setAsOutputPin()一致
driveStrength
设置强驱动还是弱驱动。系统默认的是弱驱动能力。参数如下
GPIO_REDUCED_OUTPUT_DRIVE_STRENGTH //弱驱动 GPIO_FULL_OUTPUT_DRIVE_STRENGTH //强驱动
修改寄存器
寄存器修改了PxDS
使用
例如让P1.1为强驱动
//P1.0为强驱动 GPIO_setDriveStrength(GPIO_PORT_P1,GPIO_PIN0,GPIO_FULL_OUTPUT_DRIVE_STRENGTH);
实操
开发板和库函数文件
我们以TI官方的MSP430F5529开发板作为例子实操,原理图在最上面链接里面有。导入库函数文件,使用MSP430Ware中找到Empty开头的那个例程。
目的
实验1:让LED1和LED2闪烁。LED1闪烁频率为1s1次,LED2为2s一次。
实验2:按下s1并且松开,LED1亮。按下s1不松开,再按下s2,LED2亮(以中断方式实现)。
这两个实验将会把上述所说的绝大多数函数包含,少部分不怎么使用或者两者类似的的不说。
代码
实验1
自己看代码研究,我上面库函数已经说的很清楚了,还看不懂就是你自己的问题。
#include "driverlib.h" #define CPU_F ((double)1000000) #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0)) //****************************************************************************** //! //! Empty Project that includes driverlib //! //****************************************************************************** void main() { //Stop WDT WDT_A_hold(WDT_A_BASE); //P1.0为输出 GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN0); //P4.7为输出 GPIO_setAsOutputPin(GPIO_PORT_P4,GPIO_PIN7); while(1) { //反转P1.0电平 GPIO_toggleOutputOnPin(GPIO_PORT_P4,GPIO_PIN7); //P1.0输出高电平 GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN0); delay_ms(1000); //P1.0输出低电平 GPIO_setOutputLowOnPin(GPIO_PORT_P1,GPIO_PIN0); delay_ms(1000); } }
中断服务函数
实验2
#include "driverlib.h" #define CPU_F ((double)1000000) #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0)) //****************************************************************************** //! //! Empty Project that includes driverlib //! //****************************************************************************** void main (void) { //Stop WDT WDT_A_hold(WDT_A_BASE); //P1.0为输出 GPIO_setAsOutputPin(GPIO_PORT_P1,GPIO_PIN0); //P4.7为输出 GPIO_setAsOutputPin(GPIO_PORT_P4,GPIO_PIN7); //P2.1为上拉输入 GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P2,GPIO_PIN1); //P1.1为下降沿触发 GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1,GPIO_PIN1); GPIO_selectInterruptEdge(GPIO_PORT_P1,GPIO_PIN1,GPIO_HIGH_TO_LOW_TRANSITION); GPIO_enableInterrupt(GPIO_PORT_P1,GPIO_PIN1); GPIO_clearInterrupt(GPIO_PORT_P1,GPIO_PIN1); _BIS_SR(GIE);//开启中断使能 while(1) { if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN1) == GPIO_INPUT_PIN_LOW) { delay_ms(20); if(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN1) == GPIO_INPUT_PIN_LOW) GPIO_toggleOutputOnPin(GPIO_PORT_P1,GPIO_PIN0); while(GPIO_getInputPinValue(GPIO_PORT_P2,GPIO_PIN1) == GPIO_INPUT_PIN_LOW); } } } #pragma vector=PORT1_VECTOR __interrupt void Port_1 (void) { //读取P1.1中断标志位 if(GPIO_getInterruptStatus(GPIO_PORT_P1,GPIO_PIN1)) { if(GPIO_getInputPinValue(GPIO_PORT_P1,GPIO_PIN1) == GPIO_INPUT_PIN_LOW) { delay_ms(20); if(GPIO_getInputPinValue(GPIO_PORT_P1,GPIO_PIN1) == GPIO_INPUT_PIN_LOW) GPIO_toggleOutputOnPin(GPIO_PORT_P4,GPIO_PIN7); while(GPIO_getInputPinValue(GPIO_PORT_P1,GPIO_PIN1) == GPIO_INPUT_PIN_LOW); } GPIO_clearInterrupt(GPIO_PORT_P1,GPIO_PIN1); } }