建议不是很了解寄存器的看完我的MSP430F5529学习笔记
目录
GPIO_setAsOutputPin()
函数声明
作用
参数
selectedPort
selectedPins
修改的寄存器
使用
与GPIO_setAsOutputPin()参数一致的函数
GPIO_setOutputHighOnPin()
GPIO_setOutputLowOnPin()
GPIO_toggleOutputOnPin()
GPIO_setAsInputPin()
GPIO_setAsInputPinWithPullDownResistor()
GPIO_setAsInputPinWithPullUpResistor()
GPIO_getInputPinValue()
GPIO_enableInterrupt()
GPIO_disableInterrupt()
GPIO_getInterruptStatus()
GPIO_clearInterrupt()
GPIO_selectInterruptEdge()
函数声明
作用
参数
selectedPort和selectedPins
edgeSelect
修改寄存器
使用
GPIO_setDriveStrength()
函数声明
作用
参数
selectedPort和selectedPins
driveStrength
修改寄存器
使用
实操
开发板和库函数文件
目的
代码
实验1
中断服务函数
实验2
注意:
(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
//P1.0输出高电平
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为上升沿触发
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);
}
}