星允派星光召集令星允派F103·

星允派(stm32f103) (一)串口/GPIO操作

meiyaolei

meiyaolei

85 1

第一次来论坛测评,今天先出第一篇,在STM32F103上,就是星允派开发板实现串口和GPIO的使用。

  • 平台:KEIL
  • 实现功能:串口操作、GPIO操作。
  • 串口通信:PA9(TX)和PA10(RX)
  • GPIO操作:按键KEY1接PA2,LED1接PB4
  • 功能需求:串口输出星允派!hello,F103!和按下KEY1时,LED1闪烁

1、硬件连接

KEY1:连接到PA2(输入模式,建议上拉或下拉,防止悬空) LED1:连接到PB4(输出模式,推挽输出) 串口:PA9(TX)、PA10(RX)用于调试输出

2、原理图

按键与LED,从原理图了解LED引脚是受PB4控制,从这个原理图就能得出结果,可以清楚的从CUBEMX进行配置PB4为输出模式。

串口连接IO引脚:

3、STM32CubeMX配置

先配置LED为输出,再设置PB4的模式:

STM32CubeMX 工具配置 PB4 引脚,

  • 引脚功能​​:GPIO_Output(通用输出模式)
  • 输出电平​​:High(初始高电平)
  • 模式​​:Output Push Pull(推挽输出)
  • 上拉/下拉​​:No pull(无上下拉电阻)
  • 最大输出速度​​:High(高速模式)

再配置输入模式按键:

串口配置,定义串口引脚:

根据上图显示,关键引脚配置如下:

​引脚​​功能配置​​模式​​上下拉​​速度​
PA9USART1_TXAlternate Function Push-PullNo pull-up/pull-downHigh
PA10GPIO_OutputOutput Push-PullNo pull-up/pull-downHigh

4、代码

/* USER CODE BEGIN 1 */
    char i;  // 定义一个字符型变量i,用于存储按键状态
/* USER CODE END 1 */

/* MCU Configuration--------------------------------------------------------*/

/* 复位所有外设,初始化Flash接口和系统滴答定时器 */
HAL_Init();

/* USER CODE BEGIN Init */
/* 用户初始化代码区域(当前为空) */
/* USER CODE END Init */

/* 配置系统时钟 */
SystemClock_Config();

/* USER CODE BEGIN SysInit */
/* 系统初始化代码区域(当前为空) */
/* USER CODE END SysInit */

/* 初始化所有已配置的外设 */
MX_GPIO_Init();        // 初始化GPIO
MX_USART1_UART_Init(); // 初始化USART1串口

/* USER CODE BEGIN 2 */
// 串口发送测试数据
unsigned char Sendbuf[] = "星允派!\r\n";  // 定义要发送的字符串
HAL_UART_Transmit(&huart1, Sendbuf, sizeof(Sendbuf), HAL_MAX_DELAY); // 通过UART1发送数据
HAL_Delay(1000);  // 延时1秒

// 使用printf打印测试信息
printf("hello,STM32F103!\r\n");  // 通过串口打印信息
HAL_Delay(1000);  // 延时1秒
/* USER CODE END 2 */

/* 无限循环 */
/* USER CODE BEGIN WHILE */
while (1)
{
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    // 检测KEY按键状态(0表示按下,1表示释放)
    i = HAL_GPIO_ReadPin(K1_GPIO_Port, K1_Pin); // 读取KEY1按键状态
    if (i == 0) 
    { 
        // 按键按下时LED1闪烁三次
        HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET); // LED1亮
        HAL_Delay(300);  // 延时300ms
        HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);   // LED1灭
        HAL_Delay(300);  // 延时300ms
        HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET); // LED1亮
    }
    else
    { 
        // 按键未按下时LED1保持熄灭
        HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
    }
    
    // 检查是否完成串口数据接收
    if(rx_done == 1)  // 如果接收完成标志置位
    {
        rx_done = 0;  // 清除接收完成标志
        
        // 打印接收到的数据长度和内容
        printf("length of rx data: %d!\r\n", rx_cnt);  // 打印接收数据长度
        for(int i = 0; i < rx_cnt; i++) 
            printf("%c", rx_buff[i]);  // 逐个打印接收到的字符
        printf("\r\n");  // 打印换行

        rx_cnt = 0;  // 重置接收计数器
    } 
}
/* USER CODE END 3 */


初始化
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);

  /*Configure GPIO pins : K1_Pin K2_Pin */
  GPIO_InitStruct.Pin = K1_Pin|K2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PA8 */
  GPIO_InitStruct.Pin = GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : LED2_Pin */
  GPIO_InitStruct.Pin = LED2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : LED1_Pin */
  GPIO_InitStruct.Pin = LED1_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct);

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */
/\* USER CODE BEGIN USART1\_Init 2 \*/   
// 启用 UART1 的空闲中断(IDLE)和接收寄存器非空中断(RXNE)   
// UART\_IT\_IDLE: 空闲中断,当检测到总线空闲时触发  
// UART\_IT\_RXNE: 接收数据寄存器非空中断,当接收到数据时触发 
  __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE|UART_IT_RXNE);

  /* USER CODE END USART1_Init 2 */

}

//重映射函数
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
  return ch;
}

5、上面的代码说明:

按键检测​​(K1/K2)与​​LED 控制​​(LED1/LED2) 串口通信​​(USART1)用于调试信息输出和数据接收 中断驱动​​的串口数据接收处理

MX_GPIO_Init()初始化所有 GPIO 引脚: 配置 K1/K2 为输入模式(无上下拉) 配置 LED1/LED2 为推挽输出(上拉,高速)

MX_USART1_UART_Init()初始化 USART1: 波特率 115200,8 位数据,无校验 启用空闲中断和接收中断

SystemClock_Config()配置系统时钟(代码未展示,默认使用 HSI/HSE+PLL)

中断类型​​触发条件​​典型应用​
UART_IT_RXNE接收寄存器非空实时读取单个字节
UART_IT_IDLE检测到总线空闲(停止位后)判定一帧数据接收完成

6、实现效果

串口输出 按键按下时LED闪烁

上面的演示是按键按下,LED闪烁,松开后,就熄灭。

相关文章

优先推荐同专题、同标签和同作者内容,补足热门文章。

评论 1

登录 后参与评论

评论 1

ronger
ronger8月19日 20:32

🤒 注释乱码了