可以发现MSP432主控板外接了一个接口板,接口板与另外的模块之间有连接。包括红外循迹,电机驱动以及电源模块,碰撞开关的接入。
碰撞开关指的是在小车前端的六个可触碰开关。这里的需求是【当6个碰撞开关其中任意一个遭受撞击后,接口板上的灯开始闪烁起提示作用,但需要是不同颜色】
由于接口板和主控板已经封装好,碰撞模块又算的上外设,所以这里的输入为P4.0-P4.7中的6个接口。输出当然是LED灯
至于以不同的颜色闪烁,考虑到此主控板上LED2.0-LED2.2是不同的颜色,且可以单色三灯+任意两个三原色进行排列组合,这样就可以达到预期效果。
具体实现流程大致为:
定义输出LED → \rightarrow → 定义输入包含上拉电阻的接口 → \rightarrow → 当按下(低电平有效时)将灯点亮(即加一段延时),注意点亮灯地址的分配
需要用到的函数:
GPIO_setAsOutputPin()——将端口设置为输出
GPIO_setAsInputPinWithPullUpResistor()——将端口定义为上拉电阻输入
GPIO_INPUT_PIN_LOW()——表示GPIO接口低电平时
GPIO_getInputPinValue()——检测高低电平的函数
注意要用一个大循环给框着
具体代码如下:
/* DriverLib Includes */
#include
/* Standard Includes */
#include
#include
volatile uint32_t ui32Loop;
/**
* main.c
*/
void main(void)
{
//关闭看门狗
WDT_A_holdTimer();
//配置输出,P2.0三个接口判断亮灭
GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0);
GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN1);
GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN2);
//配置上拉
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN0);
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN2);
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN3);
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN5);
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN6);
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN7);
while(1)
{
//P4.0
if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN0))
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN0);
for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
{
}
while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN0));
}
//P4.2
if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN2))
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
{
}
while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN2));
}
//p4.3对应
if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN3))
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
{
}
while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN3));
}
//P4.5对应
if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN5))
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
{
}
while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN5));
}
//P4.6对应
if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN6))
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN3);
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
{
}
while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN6));
}
//P4.7对应
if(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN7))
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN3);
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
{
}
while(GPIO_INPUT_PIN_LOW==GPIO_getInputPinValue(GPIO_PORT_P4, GPIO_PIN7));
}
}
}
有些凌乱。定义引脚依旧了最前面。
现在考虑用中断相关知识来实现这个效果。因为对中断过程不了解,现找出相应的例程函数看看
/* DriverLib Includes */
#include
/* Standard Includes */
#include
#include
int main(void)
{
/* Halting the Watchdog */
MAP_WDT_A_holdTimer();
/* P1.0口输入 */
MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
/*MAP函数可以自动决策这部分的存储空间,是用FLASH还是RAM*/
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);//1.1设置为输出
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);//清理中断标志
MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);//使能中断端口
MAP_Interrupt_enableInterrupt(INT_PORT1);//端口总使能
/* Enabling SRAM Bank Retention */
MAP_SysCtl_enableSRAMBankRetention(SYSCTL_SRAM_BANK1);
/* Enabling MASTER interrupts */
MAP_Interrupt_enableMaster();
/* Going to LPM3 */
while (1)
{
MAP_PCM_gotoLPM3();
}
}
//这是端口中断的中断服务程序
void PORT1_IRQHandler(void)
{
uint32_t status;//设置状态
status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);//一次性获取状态
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);
if(status & GPIO_PIN1)
{
MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);//对端口的电平反向
}
}
同样的包括引脚设置,中断请求,中断服务程序三项。
中断请求这里包括设置上拉电阻,清理中断标志位和打开中断允许端口三项
这里解释一下什么是中断标志位。一般中断程序执行有两个必要条件,一个是标志位置1,另外一个是中断允许端口打开。而中断允许端口日常打开,中断程序中也有相应的ENABLE指令,为:
MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);
具体怎么搞,根据给出的模板套应该就行了。大致分为这几个部分,且很多地方是不变的。
现在给出相应的通过中断实现的代码:
/*
* 文件说明: rslk碰撞开关的相关函数
*
* */
/* DriverLib Includes */
#include
/* Standard Includes */
#include
#include
int main(void)
{
//停用看门狗
MAP_WDT_A_holdTimer();
//p1.0 p2.0 p2.1 p2.2
//LED引脚设置为输出
GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN0 + GPIO_PIN1 + GPIO_PIN2);
//输出低电平,led灯熄灭
GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
GPIO_setOutputLowOnPin(GPIO_PORT_P2, GPIO_PIN0 + GPIO_PIN1 + GPIO_PIN2);
//设置碰撞开关引脚为输入,使能内部上拉,启用中断
//P4.0 p4.2 p4.3 p4.5 p4.6 p4.7
//P4.0
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4,GPIO_PIN0);//给输入端上拉电阻
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN0);//清理中断标志位
MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN0);//中断使能
//P4.2
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN2);
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN2);
MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN2);
//P4.3
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN3);
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN3);
MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN3);
//P4.5
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN5);
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN5);
MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN5);
//P4.6
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN6);
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN6);
MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN6);
//P4.7
MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P4, GPIO_PIN7);
MAP_GPIO_clearInterruptFlag(GPIO_PORT_P4, GPIO_PIN7);
MAP_GPIO_enableInterrupt(GPIO_PORT_P4, GPIO_PIN7);
//启用中断
MAP_Interrupt_enableInterrupt(INT_PORT4);
//使能中断
MAP_Interrupt_enableMaster();
while (1)
{
}
}
//GPIO中断处理函数
//出现了中断,程序会自动执行中断服务程序
void PORT4_IRQHandler(void)
{
uint32_t status;
//读取GPIO口的中断标志位,如果发生了中断,那么相关的引脚会被 置1.
//这个函数,一次都会P4端口所有引脚的中断
status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P4);
//将相应的中断标志清除
//好好理解下输入参数status。 假设有多个置1的位,那么这些位都会清零
GPIO_clearInterruptFlag(GPIO_PORT_P4, status);
if(status & GPIO_PIN0)
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN0);
}
if(status & GPIO_PIN2)
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
}
if(status & GPIO_PIN3)
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
}
if(status & GPIO_PIN5)
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN2);
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
}
if(status & GPIO_PIN6)
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN3);
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
}
if(status & GPIO_PIN7)
{
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN3);
GPIO_setOutputHighOnPin(GPIO_PORT_P2, GPIO_PIN1);
}
}
`