写一段stm32单片机程序,要求如下编写主程序与中断程序, 采用固件库编程方式(40分),具各如下功能: 需要2个按键,4个LED灯; 按下按键1,奇数灯亮,偶数灯灭; 按下按键2,奇数灯灭,偶数灯亮;
时间: 2024-03-01 16:52:50 浏览: 77
好的,以下是符合要求的stm32单片机程序,包含主程序和中断程序:
```c
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "misc.h"
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
// 配置按键1
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 下拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置按键2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 下拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置LED灯
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
// 配置中断线
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);
// 配置按键1中断
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; // 上升沿和下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
// 配置按键2中断
EXTI_InitStructure.EXTI_Line = EXTI_Line1;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; // 上升沿和下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
// 配置中断优先级
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
while (1)
{
// 主程序不需要做什么
}
}
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
{
static uint8_t odd_led_on = 1;
if (odd_led_on)
{
GPIO_SetBits(GPIOC, GPIO_Pin_0 | GPIO_Pin_2);
GPIO_ResetBits(GPIOC, GPIO_Pin_1 | GPIO_Pin_3);
}
else
{
GPIO_SetBits(GPIOC, GPIO_Pin_1 | GPIO_Pin_3);
GPIO_ResetBits(GPIOC, GPIO_Pin_0 | GPIO_Pin_2);
}
odd_led_on = !odd_led_on;
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
void EXTI1_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line1) != RESET)
{
static uint8_t even_led_on = 1;
if (even_led_on)
{
GPIO_SetBits(GPIOC, GPIO_Pin_0 | GPIO_Pin_2);
GPIO_ResetBits(GPIOC, GPIO_Pin_1 | GPIO_Pin_3);
}
else
{
GPIO_SetBits(GPIOC, GPIO_Pin_1 | GPIO_Pin_3);
GPIO_ResetBits(GPIOC, GPIO_Pin_0 | GPIO_Pin_2);
}
even_led_on = !even_led_on;
EXTI_ClearITPendingBit(EXTI_Line1);
}
}
```
在这个程序中,我们首先开启了GPIOA和GPIOC的时钟,并分别配置了PA0、PA1和PC0~PC3的工作模式。PA0和PA1被配置为下拉输入,PC0~PC3被配置为推挽输出。
接着,我们配置了PA0和PA1的中断线,并将它们的触发方式设置为上升沿和下降沿触发。然后,我们配置了EXTI0_IRQn和EXTI1_IRQn的中断优先级,并将它们的中断处理函数分别定义为`EXTI0_IRQHandler`和`EXTI1_IRQHandler`。
在两个中断处理函数中,我们分别判断中断是否来自于对应的按键,并根据当前灯的状态来控制LED灯的亮灭。
最后,在主程序中我们只需要一个死循环即可,因为所有的逻辑都在中断处理函数中完成。
希望这个程序能够满足你的要求!
阅读全文