STM32 HAL库空闲中断与回调函数接收16进制数据

最近今天在学习hal库编写stm32的程序,对于串口,使用了回调函数,但是上一个例子中,接收是判断帧尾数据,来获取这一帧数据,怎么利用帧开始的数据,比判断帧尾数据更常用。
因此采用了空闲中断与回调函数相结合的方式,来进行程序设计。

usart.c

#include "sys.h"
#include "usart.h"    
//      
//如果使用ucos,则包括下面的头文件即可.
#if SYSTEM_SUPPORT_OS
#include "includes.h"                    //ucos 使用      
#endif
//     

//加入以下代码,支持printf函数,而不需要选择use MicroLIB      
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
    int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
    x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
    while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
    return ch;
}
#endif 


//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误       
u8 USART1_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.

u8 Count=0;       //接收状态标记      

u8 aRxBuffer[RXBUFFERSIZE];//HAL库使用的串口接收缓冲
UART_HandleTypeDef UART1_Handler; //UART句柄
  
//初始化IO 串口1 
//bound:波特率
void uart_init(u32 bound)
{    
    //UART 初始化设置
    UART1_Handler.Instance=USART1;                        //USART1
    UART1_Handler.Init.BaudRate=bound;                    //波特率
    UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;   //字长为8位数据格式
    UART1_Handler.Init.StopBits=UART_STOPBITS_1;        //一个停止位
    UART1_Handler.Init.Parity=UART_PARITY_NONE;            //无奇偶校验位
    UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;   //无硬件流控
    UART1_Handler.Init.Mode=UART_MODE_TX_RX;            //收发模式
    HAL_UART_Init(&UART1_Handler);                        //HAL_UART_Init()会使能UART1
    
    __HAL_UART_ENABLE_IT(&UART1_Handler, UART_IT_IDLE);          //使能空闲中断
    
    HAL_UART_Receive_IT(&UART1_Handler, (u8 *)aRxBuffer, RXBUFFERSIZE);
    //该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
  
}

//UART底层初始化,时钟使能,引脚配置,中断配置
//此函数会被HAL_UART_Init()调用
//huart:串口句柄

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_Initure;
    
    if(huart->Instance==USART1)//如果是串口1,进行串口1 MSP初始化
    {
        __HAL_RCC_GPIOA_CLK_ENABLE();            //使能GPIOA时钟
        __HAL_RCC_USART1_CLK_ENABLE();            //使能USART1时钟
        __HAL_RCC_AFIO_CLK_ENABLE();
    
        GPIO_Initure.Pin=GPIO_PIN_9;            //PA9
        GPIO_Initure.Mode=GPIO_MODE_AF_PP;        //复用推挽输出
        GPIO_Initure.Pull=GPIO_PULLUP;            //上拉
        GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);           //初始化PA9

        GPIO_Initure.Pin=GPIO_PIN_10;            //PA10
        GPIO_Initure.Mode=GPIO_MODE_AF_INPUT;    //模式要设置为复用输入模式!    
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);           //初始化PA10
        

        HAL_NVIC_EnableIRQ(USART1_IRQn);                //使能USART1中断通道
        HAL_NVIC_SetPriority(USART1_IRQn,3,3);            //抢占优先级3,子优先级3
    }
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)

{


if(huart->Instance==USART1)

{
//	GPIO_InitTypeDef GPIO_Initure;

//DEBUG_USART_RCC_CLK_DISABLE();
		__HAL_RCC_USART1_CLK_DISABLE();			//使不能USART1时钟

/**USART1 GPIO Configuration    
    PA9     ------> USART1_TX
    PA10     ------> USART1_RX 
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);

		HAL_NVIC_DisableIRQ(USART1_IRQn);

}

else if(huart->Instance==USART2)

 {

		__HAL_RCC_USART2_CLK_DISABLE();			//使不能USART1时钟

    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);

		HAL_NVIC_DisableIRQ(USART2_IRQn);

 }

}


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)  //回调函数
{
    if(huart->Instance==USART1)//如果是串口1
    {

            Count++;
       USART1_RX_BUF[Count-1]=aRxBuffer[0];    
       HAL_UART_Receive_IT(&UART1_Handler,(uint8_t *)aRxBuffer,1);//接收完了一个数据,再打开

    }
}
 
//串口1中断服务程序
void USART1_IRQHandler(void)                    
{ 
    u32 timeout=0;
#if SYSTEM_SUPPORT_OS         //使用OS
    OSIntEnter();    
#endif
    
    HAL_UART_IRQHandler(&UART1_Handler);    //调用HAL库中断处理公用函数
    
    if(RESET != __HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_IDLE)) //判断空闲中断标志
{
  __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);               //清除空闲中断标志

    
        if(USART1_RX_BUF[0]==0x55)    //一帧数据的开始的一个字节,
      
     {
        printf("Count=%d\r\n",Count); 
        for(int i=0;i<Count;i++){
        printf("USART1_RX_BUF[%d] = 0x%x\r\n",i,USART1_RX_BUF[i]); 
                }
             HAL_UART_Transmit(&UART1_Handler, (uint8_t*)USART1_RX_BUF,sizeof(USART1_RX_BUF),100); //接收完了,再发送出去
               while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET);          //等待发送结束


         memset(USART1_RX_BUF,0,sizeof(USART1_RX_BUF));  //清空缓存数组
        Count=0;  //清空接收长度
      }
         
}

#if SYSTEM_SUPPORT_OS         //使用OS
    OSIntExit();                                               
#endif
} 
usart.h

#ifndef __USART_H
#define __USART_H
#include "stdio.h"    
#include "sys.h" 
//     

#define USART_REC_LEN              200          //定义最大接收字节数 200
      
extern u8  USART1_RX_BUF[USART_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 
extern u16 USART_RX_STA;                     //接收状态标记    
extern UART_HandleTypeDef UART1_Handler;     //UART句柄

#define RXBUFFERSIZE   1                     //缓存大小
extern u8 aRxBuffer[RXBUFFERSIZE];            //HAL库USART接收Buffer

//如果想串口中断接收,请不要注释以下宏定义
void uart_init(u32 bound);
#endif

下载链接:https://download.csdn.net/download/petertang1975/86484441

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值