单片机按键控制流水灯 按一个键改变一种流水灯方式 代码怎么编写
时间: 2023-10-22 20:09:29 浏览: 156
好的,以下是一个基于STM32F1单片机和Keil uVision5编写的代码示例,可以实现通过按键控制流水灯方式的切换。注释中有相应的说明,请详细阅读。
```
#include "stm32f10x.h"
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
uint8_t flag=0;//标志位,用于记录当前流水灯的方式
/* 延时函数 */
void Delay(__IO uint32_t nCount)
{
while(nCount--)
{
}
}
/* 初始化按键 */
void KEY_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //使能复用功能时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA0
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //PA0中断线
EXTI_InitStructure.EXTI_Line = EXTI_Line0; //LINE0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能LINE0
EXTI_Init(&EXTI_InitStructure); //配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //外部中断0
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //响应优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //配置
}
/* 初始化LED */
void LED_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; //PB5、PB6、PB7
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB5、6、7
}
/* 流水灯方式1 */
void LED_Flash1(void)
{
GPIO_SetBits(GPIOB,GPIO_Pin_5);//PB5亮
Delay(0xfffff);//延时
GPIO_ResetBits(GPIOB,GPIO_Pin_5);//PB5灭
GPIO_SetBits(GPIOB,GPIO_Pin_6);//PB6亮
Delay(0xfffff);//延时
GPIO_ResetBits(GPIOB,GPIO_Pin_6);//PB6灭
GPIO_SetBits(GPIOB,GPIO_Pin_7);//PB7亮
Delay(0xfffff);//延时
GPIO_ResetBits(GPIOB,GPIO_Pin_7);//PB7灭
}
/* 流水灯方式2 */
void LED_Flash2(void)
{
GPIO_SetBits(GPIOB,GPIO_Pin_5);//PB5亮
Delay(0xffff);//延时
GPIO_ResetBits(GPIOB,GPIO_Pin_5);//PB5灭
GPIO_SetBits(GPIOB,GPIO_Pin_6);//PB6亮
Delay(0xffff);//延时
GPIO_ResetBits(GPIOB,GPIO_Pin_6);//PB6灭
GPIO_SetBits(GPIOB,GPIO_Pin_7);//PB7亮
Delay(0xffff);//延时
GPIO_ResetBits(GPIOB,GPIO_Pin_7);//PB7灭
}
/* 流水灯方式3 */
void LED_Flash3(void)
{
GPIO_SetBits(GPIOB,GPIO_Pin_5);//PB5亮
GPIO_ResetBits(GPIOB,GPIO_Pin_6);//PB6灭
GPIO_ResetBits(GPIOB,GPIO_Pin_7);//PB7灭
Delay(0xffff);//延时
GPIO_ResetBits(GPIOB,GPIO_Pin_5);//PB5灭
GPIO_SetBits(GPIOB,GPIO_Pin_6);//PB6亮
GPIO_ResetBits(GPIOB,GPIO_Pin_7);//PB7灭
Delay(0xffff);//延时
GPIO_ResetBits(GPIOB,GPIO_Pin_6);//PB6灭
GPIO_SetBits(GPIOB,GPIO_Pin_7);//PB7亮
GPIO_ResetBits(GPIOB,GPIO_Pin_5);//PB5灭
Delay(0xffff);//延时
}
/* 外部中断0处理函数 */
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET) //判断是否为LINE0中断
{
EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0中断标志位
flag++;
if(flag > 2) flag = 0; //标志位循环
switch(flag)
{
case 0:
LED_Flash1();//流水灯方式1
break;
case 1:
LED_Flash2();//流水灯方式2
break;
case 2:
LED_Flash3();//流水灯方式3
break;
default:
break;
}
}
}
int main(void)
{
KEY_Init(); //初始化按键
LED_Init(); //初始化LED
while(1)
{
//循环执行
}
}
```
以上代码中,我们通过外部中断0来实现按键的检测和处理,每次按下按键都会触发中断。在中断处理函数中,我们使用一个标志位`flag`来记录当前流水灯的方式,按下按键后改变标志位并执行相应的流水灯程序。在`main`函数中,我们初始化按键和LED,并进入一个无限循环。