stm32f103c8t6串口接收中断回调函数及其主函数

uint8_t buf=0;

//定义最大接收字节数 200,可根据需求调整
#define UART1_REC_LEN 200

// 接收缓冲, 串口接收到的数据放在这个数组里,最大UART1_REC_LEN个字节
uint8_t UART1_RX_Buffer[UART1_REC_LEN];

//  接收状态
//  bit15,      接收完成标志
//  bit14,      接收到0x0d
//  bit13~0,    接收到的有效字节数目
uint16_t UART1_RX_STA=0;

// 接收完成回调函数,收到一个数据后,在这里处理
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    // 判断中断是由哪个串口触发的
    if(huart->Instance == USART1)
    {
        // 判断接收是否完成(UART1_RX_STA bit15 位是否为1)
        if((UART1_RX_STA & 0x8000) == 0)
        {
            // 如果已经收到了 0x0d (回车),
            if(UART1_RX_STA & 0x4000)
            {
                // 则接着判断是否收到 0x0a (换行)
                if(buf == 0x0a)
                    // 如果 0x0a 和 0x0d 都收到,则将 bit15 位置为1
                    UART1_RX_STA |= 0x8000;
                else
                    // 否则认为接收错误,重新开始
                    UART1_RX_STA = 0;
            }
            else    // 如果没有收到了 0x0d (回车)
            {
                //则先判断收到的这个字符是否是 0x0d (回车)
                if(buf == 0x0d)
                {
                    // 是的话则将 bit14 位置为1
                    UART1_RX_STA |= 0x4000;
                }
                else
                {
                    // 否则将接收到的数据保存在缓存数组里
                    UART1_RX_Buffer[UART1_RX_STA & 0X3FFF] = buf;
                    UART1_RX_STA++;
                    
                    // 如果接收数据大于UART1_REC_LEN(200字节),则重新开始接收
                    if(UART1_RX_STA > UART1_REC_LEN - 1)
                        UART1_RX_STA = 0;
                }
            }
        }
        // 重新开启中断
        HAL_UART_Receive_IT(&huart1, &buf, 1);
    }
}

int fputc(int ch, FILE *f)
{      
    unsigned char temp[1]={ch};
    HAL_UART_Transmit(&huart1,temp,1,0xffff);  
    return ch;
}

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

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

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
    // 开启接收中断
    HAL_UART_Receive_IT(&huart1, &buf, 1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
        //判断判断串口是否接收完成,数据位会影响其数据接收(0x8000不能写成0x800)
        if(UART1_RX_STA & 0x8000)
        {
            printf("收到数据:");
            // 将收到的数据发送到串口
            HAL_UART_Transmit(&huart1, UART1_RX_Buffer, UART1_RX_STA & 0x3fff, 0xffff);
            // 等待发送完成
            while(huart1.gState != HAL_UART_STATE_READY);
            printf("\r\n");
            // 重新开始下一次接收
            UART1_RX_STA = 0;
        }
        printf("hello liangxu\r\n");
        HAL_Delay(1000);

  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
 

主函数加入的是开启中断while中加入的是将接收数据发送

### STM32F103C8T6 UART 接收中断实现 STM32F103C8T6 是一款基于 ARM Cortex-M3 的微控制器,其串口中断功能可以通过 HAL 库或者标准外设库来实现。以下是通过 HAL 库实现 UART 接收中断的一个典型示例。 #### 配置步骤概述 为了启用 UART 接收中断,需要完成以下几个配置项: - 初始化 USART 外设。 - 启用 NVIC 中的对应中断向量。 - 编写并注册中断服务函数 (ISR)。 - 使用回调机制处理接收到的数据。 #### 示例代码 以下是一个完整的 UART 接收中断实现的例子: ```c #include "stm32f1xx_hal.h" // 定义全局变量用于存储接收到的数据 uint8_t receivedData; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); // 配置系统时钟 MX_GPIO_Init(); // GPIO初始化 MX_USART1_UART_Init();// USART初始化 // 注册UART接收完整回调函数 HAL_UART_Receive_IT(&huart1, &receivedData, 1); while (1) { // 主循环可以执行其他任务 } } /** * @brief USART1 Initialization Function */ static void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 9600; // 波特率设置为9600bps huart1.Init.WordLength = UART_WORDLENGTH_8B;// 字符长度为8位 huart1.Init.StopBits = UART_STOPBITS_1; // 停止位为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(); } } /** * @brief UART Receive Callback function */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { // 当数据接收完成后触发此回调函数 // 可在此处对接收到的数据进行进一步处理 printf("Received Data: %c\n", receivedData); // 继续等待下一个字符的到来 HAL_UART_Receive_IT(&huart1, &receivedData, 1); } } ``` 以上代码展示了如何利用 HAL 库中的 `HAL_UART_Receive_IT` 函数启动接收中断[^1]。当一个字节被成功接收后,会自动调用 `HAL_UART_RxCpltCallback` 回调函数,在其中可以对数据进行后续处理。 #### 关键点说明 - **波特率**:在本例中设定为 9600 bps,可以根据实际需求调整。 - **回调函数**:`HAL_UART_RxCpltCallback` 是 HAL 提供的标准接口,无需手动编写 ISR 即可轻松管理中断逻辑[^1]。 - **NVIC 设置**:如果未使用 HAL,则需自行配置 NVIC 来使能对应的中断线。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值