用STM32用按键/LED/UART实现抢答器实验代码
时间: 2023-07-18 08:32:33 浏览: 148
好的,以下是使用STM32实现抢答器的实验代码,仅供参考:
```c
#include "stm32f10x.h"
#include <stdio.h>
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
USART_InitTypeDef USART_InitStructure;
// 定义按键和LED的引脚号
#define KEY1_PIN GPIO_Pin_0
#define KEY2_PIN GPIO_Pin_1
#define KEY3_PIN GPIO_Pin_2
#define KEY4_PIN GPIO_Pin_3
#define LED1_PIN GPIO_Pin_4
#define LED2_PIN GPIO_Pin_5
#define LED3_PIN GPIO_Pin_6
#define LED4_PIN GPIO_Pin_7
// 定义串口接口
#define USARTx USART1
#define USARTx_IRQn USART1_IRQn
// 定义命令
#define CMD_REQ 'R' // 抢答命令
#define CMD_STOP 'S' // 关闭抢答命令
#define CMD_ACK 'A' // 抢答成功命令
// 定义全局变量
uint8_t g_flag = 0; // 抢答标志
uint8_t g_index = 0; // 抢答者编号
// 初始化GPIO口
void GPIO_Configuration(void)
{
// 使能GPIOA和GPIOB时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
// 配置KEY1~KEY4为输入引脚
GPIO_InitStructure.GPIO_Pin = KEY1_PIN | KEY2_PIN | KEY3_PIN | KEY4_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 配置LED1~LED4为输出引脚
GPIO_InitStructure.GPIO_Pin = LED1_PIN | LED2_PIN | LED3_PIN | LED4_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
// 初始化外部中断
void EXTI_Configuration(void)
{
// 使能AFIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
// 配置KEY1~KEY4为外部中断
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource2);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource3);
EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1 | EXTI_Line2 | EXTI_Line3;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_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 = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_Init(&NVIC_InitStructure);
}
// 初始化串口
void USART_Configuration(void)
{
// 使能USART1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// 配置USART1引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART1参数
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USARTx, &USART_InitStructure);
// 使能USART1接收中断
USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE);
// 配置优先级
NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// 使能USART1
USART_Cmd(USARTx, ENABLE);
}
// 外部中断服务函数
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
{
// 触发抢答
if (!g_flag)
{
g_flag = 1;
g_index = 1;
GPIO_SetBits(GPIOA, LED1_PIN);
USART_SendData(USARTx, CMD_REQ);
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
void EXTI1_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line1) != RESET)
{
// 触发抢答
if (!g_flag)
{
g_flag = 1;
g_index = 2;
GPIO_SetBits(GPIOA, LED2_PIN);
USART_SendData(USARTx, CMD_REQ);
}
EXTI_ClearITPendingBit(EXTI_Line1);
}
}
void EXTI2_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line2) != RESET)
{
// 触发抢答
if (!g_flag)
{
g_flag = 1;
g_index = 3;
GPIO_SetBits(GPIOA, LED3_PIN);
USART_SendData(USARTx, CMD_REQ);
}
EXTI_ClearITPendingBit(EXTI_Line2);
}
}
void EXTI3_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line3) != RESET)
{
// 触发抢答
if (!g_flag)
{
g_flag = 1;
g_index = 4;
GPIO_SetBits(GPIOA, LED4_PIN);
USART_SendData(USARTx, CMD_REQ);
}
EXTI_ClearITPendingBit(EXTI_Line3);
}
}
// 串口接收中断服务函数
void USARTx_IRQHandler(void)
{
if (USART_GetITStatus(USARTx, USART_IT_RXNE) != RESET)
{
uint8_t data = USART_ReceiveData(USARTx);
if (data == CMD_ACK)
{
// 抢答成功
g_flag = 0;
switch (g_index)
{
case 1:
GPIO_ResetBits(GPIOA, LED1_PIN);
break;
case 2:
GPIO_ResetBits(GPIOA, LED2_PIN);
break;
case 3:
GPIO_ResetBits(GPIOA, LED3_PIN);
break;
case 4:
GPIO_ResetBits(GPIOA, LED4_PIN);
break;
}
}
USART_ClearITPendingBit(USARTx, USART_IT_RXNE);
}
}
int main(void)
{
// 初始化GPIO口
GPIO_Configuration();
// 初始化外部中断
EXTI_Configuration();
// 初始化串口
USART_Configuration();
while (1)
{
}
}
```
以上代码仅供参考,具体实现可能需要根据实际情况进行调整和优化。
阅读全文