超声波相关——串口发送数据用DMA传输

串口使用DMA发送数据时的数据覆盖问题
https://blog.csdn.net/qq_40452910/article/details/80022619

stm32串口DMA方式发送数据

https://blog.csdn.net/zfchen819/article/details/78635131

DMA发送数据

在数据发送缓冲区内放好要发送的数据(此数据缓冲区的首地址必须要在DMA初始化时写入到DMA配置中去)
将数据缓冲区内要发送的数据字节数传给DMA通道(串口发送和接收不是同一个通道)
开启DMA,一旦开启,则DMA开始发送数据,
等待数据发送完成标志!
判断数据发送完成:

启动DMA并发送完成后,产生DMA发送完成中断,在DMA中断服务函数中执行以下操作:

清DMA发送完成标志
关闭串口发送DMA通道
给前台(应用)程序设置一个软件标志位,说明数据发送完成。

DMA接收数据

串口接收DMA在初始化时就处于开启状态,一直等待数据的到来,串口中断IDLE在串口一直没有数据时,是不会产生的,产生的条件是:当清除IDLE标志位后,必须有接收到第一个数据后才触发,一旦接收的数据断流,即产生IDLE中断。
这里判断接收数据完成是通过串口的空闲方式实现,即当串口的数据流停止后,就会产生IDLE中断,在中断里做:

关闭串口接收的DMA通道。一是防止又有数据接收到,产生干扰;二是便于DMA重新配置赋值。
清除DMA中断标志位
从DMA寄存器中获取接收到的数据字节数(对于上层应用很有必要)
重新设置DMA下次需要接收到的数据字节数(必须大于预期的接收值长度,否则计数减到0时又会复位,覆盖接收缓冲区中的数据,导致数据丢失!)
开启DMA通道,等待下一次的数据接收
可以设置信号量,通知应用程序数据接收完成,传递接收的数据长度,便于应用程序对数据的处理。

有待思考的
!!! 此处的接收缓冲区时来自哪里? uart1的数据缓冲区,还是DMA的接收数据缓冲区,最大支持多少个字节???

!!! DMA发送数据,网上也有看到将配置封装在发送函数中,如
uart1_dma_send_data(uint8_t* buf, uint32_t len),这个好处是,可以变化mem地址(buf数组,以及长度可以适当配置变化),不错!

!!! DMA接收函数,应用DMA中断判断接收完成只能依赖于DMA配置中字节长度,支持DMA传输完成,传输过半,传输错误,但对于不固定长度接收数据,this is a question.
注意:

DMA外设和DMA通道有对应关系,需要参考stm32手册
这里写图片描述
在这里插入图片描述
DMA传输数据时,需要明确传输的字节数目
DMA使能情况下,不能配置传输字节数到DMA寄存器,所以也不会产生DMA数据传输(因为传输字节数目为0)

  1. hal_uart_dma.c

    #include “includes.h”

    /*
    DMA方式介绍
    DMA使用流程:
    1. 配置
    外设端:
    - 串口引脚GPIO配置
    - 串口功能参数配置(数据位格式,波特率等),此处还需要配置对应的DMA请求允许。
    - 如果有中断,还需要配置中断优先级
    DMA端:
    - DMA功能配置
    - 初始化DMA通道DMA_Init(DMA1_Channel4,&DMA_InitStructure);
    。 DMA源(Memory)/目的(外设)地址
    。 DMA的传输方向
    。 DMA的buffer size
    。 DMA外设(DISABLE)/Memory(ENABLE)地址自增使能配置
    。 DMA传输字节格式(支持byte,half-word,word)
    。 DMA传输方式(Normal和Circle)
    。 DMA传输优先级(共有四种,)
    。 DMA m2m使能/失能配置(此处不是用于m2m所以配置为DISABLE)
    - 清除中断标志位
    - 此处应DISABLE DMA通道,否则配置完成即会产生DMA数据传输(非期望数据)
    - 使能DMA发送完成中断

    -DMA中断服务函数
    发送数据完成后,即关闭DMA通道,发送信号量到应用程序

外设部分配置
2. 使能(使用)
应用程序需要发送数据时:
- 将要发送的数据准备好,并且要知道发送多少单位数据(发送字节数)
- 配置DMA要发送的字节数,使能DMA即可.
*/

//#define DMA_USART1_DR_Base      (USART1_BASE + 0x4) //0x40013804
#define DMA_USART1_DR_Base          0x40013804

//1. 串口1端口配置

void hal_debug_gpio_config(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    //DBTX  PA9  uart1_tx
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    //DBRX  PA10   uart1_rx
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

}

//2. 串口功能配置

void hal_debug_func_config(void)
{
    USART_InitTypeDef  USART_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_Init(USART1,&USART_InitStructure);
//config uart DMA request
USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);//enable usart1 dma send request
USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //enable usart1 dma recieve request
USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); //enable usart1 idle interrupt
USART_Cmd(USART1,ENABLE);
}
//
void hal_debug_nvic_config(void){
    NVIC_InitTypeDef  NVIC_InitStructure;
    //uart1 interrupt
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
//dma interrupt
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;   //
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;     //
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);
}

//3. 串口初始化

void hal_debug_init(void)
{
    hal_debug_gpio_config();

hal_debug_func_config();

hal_debug_nvic_config();

}

//DMA config/
//1. uart dma configs

void uart_dma_init(void){
    DMA_InitTypeDef DMA_InitStructure;
//Tx DMA CONFIG
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //enable DMA1 clock
DMA_Cmd(DMA1_Channel4,DISABLE);                                     //close DMA Channel
DMA_DeInit(DMA1_Channel4);

DMA_InitStructure.DMA_PeripheralBaseAddr = DMA_USART1_DR_Base;  //(uint32_t)(&USART1->DR)
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_Tx_Buf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = USART1_TX_BSIZE; 
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; 
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 

DMA_Init(DMA1_Channel4,&DMA_InitStructure);
DMA_ClearFlag(DMA1_FLAG_GL4);  // clear all DMA flags
//DMA_Cmd(DMA1_Channel4,ENABLE); // close DMA Channel
DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);  //open DMA send inttrupt

//Rx DMA CONFIG 
DMA_Cmd(DMA1_Channel5, DISABLE);   //                       
DMA_DeInit(DMA1_Channel5);  

DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART1->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_Rx_Buf;        
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                    
DMA_InitStructure.DMA_BufferSize = USART1_RX_BSIZE;                     
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;       
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;        
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                           
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;               
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                           

DMA_Init(DMA1_Channel5, &DMA_InitStructure);            
DMA_ClearFlag(DMA1_FLAG_GL5);                              
DMA_Cmd(DMA1_Channel5, ENABLE);  
}

///uart dma send//

void DMA1_Channel4_IRQHandler(void)
{
    if(DMA_GetITStatus(DMA1_FLAG_TC4)==SET)
    {
            DMA_ClearFlag(DMA1_FLAG_GL4);        
            DMA_Cmd(DMA1_Channel4, DISABLE);  
            OSMboxPost(mbLumModule_Tx, (void*)1); 
    }
}
void uart_dma_send_enable(uint16_t size)
{
    DMA1_Channel4->CNDTR = (uint16_t)size; 
    DMA_Cmd(DMA1_Channel4, ENABLE);       
}

void uart1_dma_send_data(void)
{
    uint8_t err;
        uint16_t i;
    uint16_t USART1_Tx_Index=0;
        for(i=0;i<8;i++){
            USART1_Tx_Buf[USART1_Tx_Index++]=i;
        }
    uart_dma_send_enable(USART1_Tx_Index);
    OSMboxPend(mbLumModule_Tx, 5000, &err);
}

///uart dma send//

///uart dma recv//

void uart1_dma_recv_data(void)
{
    uint16_t index = 0;
    DMA_Cmd(DMA1_Channel5, DISABLE);      
    DMA_ClearFlag(DMA1_FLAG_GL5);          
    //index = USART1_RX_BSIZE - DMA_GetCurrDataCounter(DMA1_Channel5); 
    DMA1_Channel5->CNDTR = USART1_RX_BSIZE;   
    DMA_Cmd(DMA1_Channel5, ENABLE);       

//OSMboxPost(mbLumModule_Rx,USART1_Rx_Buf);
}
void USART1_IRQHandler(void)
{
    if(USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)  
    {
        uart1_dma_recv_data();
        USART_ClearITPendingBit(USART1,USART_IT_IDLE);      
    }
}

///uart dma recv//

  1. app_test.c
    该文件为app_test线程,用于1s发送一次串口数据,其中发送串口数据中应用了信号量,如果没有等待到信号量,最大等待时间为5s(加上此处的1s周期则为6s)。

#include “includes.h”

OS_STK gTest[APP_TEST_STK_SIZE];

uint8_t USART1_Tx_Buf[USART1_TX_BSIZE] = {0};
OS_EVENT *gSemEvent1 = NULL;
OS_EVENT *mbLumModule_Tx = NULL;

void app_test(void* p_arg){
    (void)p_arg;
    //create new event
    gSemEvent1 = OSSemCreate(2);
    mbLumModule_Tx = OSMboxCreate((void*)0);
    while(1){
        //OSSemPost(gSemEvent1); 
        OSTimeDly(1000);
        //printf("hello world!\r\n");
        uart1_dma_send_data();
    }
}

ucos_main.c
该函数用于创建ucos任务,一个main函数,一个创建任务的任务函数。
其中app_test任务就是这边uart DMA发送数据的任务。

#include "includes.h"

/*
    1. 主函数
         用于启动ucos-ii操作系统,启动第一个启动任务
    2. 启动任务启动其他的任务
*/
static OS_STK gTaskStartStk[APP_TASK_START_STK_SIZE];               //定义栈 
static void App_TaskStart(void *p_arg);
static void app_task_create (void);

//1. main
int main(void){
    INT8U  os_err;

    OSInit();   
    os_err = OSTaskCreateExt((void (*)(void *)) App_TaskStart,  /* Create the start task.                               */
                             (void          * ) 0,
                             (OS_STK        * )&gTaskStartStk[APP_TASK_START_STK_SIZE - 1],
                             (INT8U           ) APP_TASK_START_PRIO,
                             (INT16U          ) APP_TASK_START_PRIO,
                             (OS_STK        * )&gTaskStartStk[0],
                             (INT32U          ) APP_TASK_START_STK_SIZE,
                             (void          * )0,
                             (INT16U          )(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK));
#if (OS_TASK_NAME_SIZE >= 11)
    OSTaskNameSet(APP_TASK_START_PRIO, (INT8U *)"Start Task", &os_err);
#endif

    OSStart();  
}       

//2. start task

static void App_TaskStart(void *p_arg)
{       
    (void)p_arg;

/*hal init*/
hal_dirvers_init();

//printf("uCos-II V2.86 FM.\r\n");

#if (OS_TASK_STAT_EN > 0)
  OSStatInit();                                         /* Determine CPU capacity.*/
#endif
//printf("Create App Task.\r\n");   
/*creat other app*/
app_task_create();

while(1){
    OSTimeDly(1000);
    hal_led_toggle(1);   //led_toggle   
}   
}
/*
Create APP Task
*/
static void app_task_create (void){
    INT8U  os_err;

//test task
os_err = OSTaskCreate(app_test,
                                            (void *)0,
                                            &gTest[APP_TEST_STK_SIZE-1],
                                            APP_TEST_PRIO);
#if (OS_TASK_NAME_SIZE >= 20)
        OSTaskNameSet(APP_TEST_PRIO, (INT8U *)"test task", &os_err);    
#endif

//led toggle task
/*****************************************************************************************/ 
    os_err = OSTaskCreate((void (*)(void *))app_led_toggle,
                            (void*)0,
                                                (OS_STK*)&gTaskLedToggle[APP_TASK_LED_STK_SIZE-1],
                                                (INT8U)APP_TASK_LED_PRIO                                             
                         );
    #if (OS_TASK_NAME_SIZE >= 20)
    OSTaskNameSet(APP_TASK_LED_PRIO, (INT8U *)"led_toggle", &os_err);
  #endif
/*****************************************************************************************/                                             

#if 0
    //task 1
/*****************************************************************************************/ 
        os_err = OSTaskCreate(app_task1,
                                                    (void*)0,
                                                    &gTask1[APP_TASK1_STK_SIZE-1],
                                                    APP_TASK1_PRIO);                                                    

/*****************************************************************************************/                                                 
    //task 2
/*****************************************************************************************/ 
        os_err = OSTaskCreate(app_task2,
                                                    (void*)0,
                                                    &gTask2[APP_TASK2_STK_SIZE-1],
                                                    APP_TASK2_PRIO);                                            

/*****************************************************************************************/                                         
    //task 3
/*****************************************************************************************/ 
        os_err = OSTaskCreate(app_task3,
                                                    (void*)0,
                                                    &gTask3[APP_TASK3_STK_SIZE-1],
                                                    APP_TASK3_PRIO);
/*****************************************************************************************/                                                 
#endif
}

STM32 使用HAL库做串口的DMA发送和中断接收

https://blog.csdn.net/queqiongtao/article/details/78828798
HAL串口中断接收
HAL库使用起来太不灵活,限制太多,后面如有时间,将使用寄存器和HAL库混合操作的方式。
如使用串口中断接收,在接收到数据后,库里做了关闭接收非空中断RXNEIE,如下
在这里插入图片描述

HAL库DMA发送
目前,我用的是DMA发送,本来向直接将数据扔给DMA,不想开发送DMA的中断,但是,HAL库考虑的比较周详,使用HAL库的DMA发送API,就会使用了DMA句柄中的相关标志位,这些标志位得你开了中断后,在DMA发送完成后,才会做相应的清除,并且,使用了__HAL_LOCK(),这样你用了他的库发送,剩下的其他处理你也得用他的库;前面说的,用了库的DMA发送,不开中断,就会因为上次是__HAL_LOCK()状态,导致无法继续执行,并且用了DMA发送后,还会标志几个标志位为BUSY状态,你如果不开中断,也得清除,总的来说,使用起来还是挺麻烦的,平白无故的多开了一个中断。

以下代码为STM32F7串口1的DMA发送和串口接收中断程序

实现代码

/**
  ******************************************************************************
  * @file    driver_uart.c
  * @author  Quentin.Que
  * @version V.0
    * @date    2017-12-14
  * @brief   所有串口底层的配置 
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "common_config.h"
#include "stm32f7xx_hal.h"  
#include "driver_uart.h"
/* Macros ------------------------------------------------------------------*/


/* Enumerations ------------------------------------------------------------------*/    


/* Type Definitions ------------------------------------------------------------------*/    
#define DEF_UART1_RX_BUF_SIZE   1   
#define DEF_UART1_DMA_TX_BUF_SIZE   200 

/* Private variables ---------------------------------------------------------*/
static UART_HandleTypeDef m_Uart1Handler;
static DMA_HandleTypeDef    m_DmaUart1Handler;
static INT8U Uart1RxBuf[DEF_UART1_RX_BUF_SIZE];
static INT8U Uart1DmaTxBuf[DEF_UART1_DMA_TX_BUF_SIZE];
static UART_RECEIVE_CALLBACK pFunUart1Callback = NULL;

/* Private function prototypes -----------------------------------------------*/    




/***********************************************************************
* @brief  初始化串口1
* @param  baudrate:波特率   
* @retval NONE
***********************************************************************/    
static void DRIVER_Uart1Init(INT32U baudrate)
{
    m_Uart1Handler.Instance = USART1;
    m_Uart1Handler.Init.BaudRate = baudrate;
    m_Uart1Handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    m_Uart1Handler.Init.Mode = UART_MODE_TX_RX;
    m_Uart1Handler.Init.Parity = UART_PARITY_NONE;
    m_Uart1Handler.Init.StopBits = UART_STOPBITS_1;
    m_Uart1Handler.Init.WordLength = UART_WORDLENGTH_8B;

    HAL_UART_Init(&m_Uart1Handler); /* 串口初始化 */
    HAL_UART_Receive_IT(&m_Uart1Handler, (INT8U *)Uart1RxBuf, DEF_UART1_RX_BUF_SIZE);  /* 开中断,设置接收buf和大小 */

}   

/**************************************************************************************
  * @brief  设置串口1接收中断
  * @param  revice_callback:接收回调函数
  * @retval NONE
**************************************************************************************/
static void DRIVER_Uart1SetReviceCallback(UART_RECEIVE_CALLBACK revice_callback)    
{
    pFunUart1Callback = revice_callback;
}   

/***************************************************************************************
* @brief  DRIVER_UART1SendData
* @param  串口1发送
* @retval NONE
***************************************************************************************/    
static BOOLEAN DRIVER_UART1SendData(INT8U* pdata, INT16U len)
{
    INT16U real_len = 0;
    real_len = len > DEF_UART1_DMA_TX_BUF_SIZE ? DEF_UART1_DMA_TX_BUF_SIZE : len;  /* 强制截取 不能超过定义的缓存大小 */
    memcpy(Uart1DmaTxBuf, pdata,real_len);
    while(0 != __HAL_DMA_GET_COUNTER(&m_DmaUart1Handler))  /* 等待发送完成 */
    {
    }
  do 
    {
    }while(HAL_OK != HAL_UART_Transmit_DMA(&m_Uart1Handler, Uart1DmaTxBuf, real_len)); 

    return TRUE;
}

/***************************************************************************************
* @brief  HAL_UART_MspInit  会被HAL_UART_Init()调用
* @param  串口句柄
* @retval NONE
***************************************************************************************/    
void HAL_UART_MspInit(UART_HandleTypeDef *huart)    
{
    GPIO_InitTypeDef GPIO_Initure;
    if(USART1 == huart->Instance)
    {
        __HAL_RCC_GPIOA_CLK_ENABLE();
        __HAL_RCC_USART1_CLK_ENABLE();

        __HAL_RCC_DMA2_CLK_ENABLE();

        GPIO_Initure.Pin=GPIO_PIN_9;         
        GPIO_Initure.Mode=GPIO_MODE_AF_PP;   
        GPIO_Initure.Pull=GPIO_PULLUP;           
        GPIO_Initure.Speed=GPIO_SPEED_FAST;      
        GPIO_Initure.Alternate=GPIO_AF7_USART1;  
        HAL_GPIO_Init(GPIOA,&GPIO_Initure); 

        GPIO_Initure.Pin=GPIO_PIN_10;        
        HAL_GPIO_Init(GPIOA,&GPIO_Initure);

    /* Peripheral DMA init*/
    m_DmaUart1Handler.Instance = DMA2_Stream7;
        m_DmaUart1Handler.Init.Channel = DMA_CHANNEL_4;
    m_DmaUart1Handler.Init.Direction = DMA_MEMORY_TO_PERIPH;
    m_DmaUart1Handler.Init.PeriphInc = DMA_PINC_DISABLE;
    m_DmaUart1Handler.Init.MemInc = DMA_MINC_ENABLE;
    m_DmaUart1Handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    m_DmaUart1Handler.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    m_DmaUart1Handler.Init.Mode = DMA_NORMAL;
    m_DmaUart1Handler.Init.Priority = DMA_PRIORITY_LOW;     

        HAL_DMA_DeInit(&m_DmaUart1Handler);
    HAL_DMA_Init(&m_DmaUart1Handler);

    __HAL_LINKDMA(huart,hdmatx,m_DmaUart1Handler); 

        HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 3, 0);
        HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);  

        HAL_NVIC_EnableIRQ(USART1_IRQn);
        HAL_NVIC_SetPriority(USART1_IRQn,3,0);           
    }
}

/********************************************************************************
* @brief  HAL_UART_RxCpltCallback  进入中断后HAL库会调用这个函数
* @param  串口句柄
* @retval NONE
*********************************************************************************/  
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(USART1 == huart->Instance)
    {
        if(NULL != pFunUart1Callback)
        {
            pFunUart1Callback(Uart1RxBuf[0]); /* 将接收到的数据通过回调传出 */
        }
        do
        {

        }while(HAL_OK != HAL_UART_Receive_IT(&m_Uart1Handler, (INT8U *)Uart1RxBuf, DEF_UART1_RX_BUF_SIZE));  /* 开中断,设置接收buf和大小 */

    }

}

/*******************************************************************************
 * @brief  USART1_IRQHandler 串口1中断函数
 * @param  串口句柄
 * @retval NONE
*********************************************************************************/  
void USART1_IRQHandler(void)     
{
    HAL_UART_IRQHandler(&m_Uart1Handler);

}

/*******************************************************************************
 * @brief  DMA2_Stream7_IRQHandler 串口1DMA发送中断
 * @param  NONE
 * @retval NONE
*********************************************************************************/  
void DMA2_Stream7_IRQHandler(void)
{
  HAL_DMA_IRQHandler(&m_DmaUart1Handler); 

}

/***********************************************************************
* @brief  初始化串口 
* @param  port:串口号  baudrate:波特率  prx_fun:接收回调函数
* @retval TRUE:成功  FALSE:失败 
***********************************************************************/
BOOLEAN DRIVER_UARTInit(INT8U port, INT32U baudrate, UART_RECEIVE_CALLBACK prx_fun)
{
    switch(port)
    {
        case DRIVER_UART_PORT1:
            DRIVER_Uart1Init(baudrate);
            DRIVER_Uart1SetReviceCallback(prx_fun);
            break;

        default:
            return FALSE;
    }
    return TRUE;
}

/***********************************************************************
* @brief  串口发送
* @param  port:串口号  pdata:数据起始地址 len:长度
* @retval TRUE:成功  FALSE:失败 
***********************************************************************/
BOOLEAN DRIVER_UARTWrite(INT8U port, INT8U* pdata, INT16U len)
{
    switch(port)
    {
        case DRIVER_UART_PORT1:
            return DRIVER_UART1SendData(pdata, len);
        default:
            return FALSE;
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ubuntu中可以使用C语言编写程序来读取串口超声波数据。下面是一个示例程序: ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <termios.h> int main() { int fd; struct termios options; // 打开串口设备文件 fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY); if (fd == -1) { perror("无法打开串口设备文件"); exit(EXIT_FAILURE); } // 配置串口参数 tcgetattr(fd, &options); cfsetispeed(&options, B9600); // 设置波特率为9600 cfsetospeed(&options, B9600); options.c_cflag |= (CLOCAL | CREAD); // 使能接收和本地模式 options.c_cflag &= ~PARENB; // 不使用奇偶校验 options.c_cflag &= ~CSTOPB; // 1位停止位 options.c_cflag &= ~CSIZE; options.c_cflag |= CS8; // 8位数据位 tcsetattr(fd, TCSANOW, &options); // 读取串口数据 char buffer[256]; int bytes_read; while (1) { bytes_read = read(fd, buffer, sizeof(buffer)-1); if (bytes_read > 0) { buffer[bytes_read] = '\0'; printf("接收到数据:%s\n", buffer); } } // 关闭串口设备文件 close(fd); return 0; } ``` 这个程序会打开名为`/dev/ttyUSB0`的串口设备文件,并配置参数为波特率9600、无奇偶校验、1位停止位和8位数据位。然后,它会不断地读取串口数据,并在控制台上显示出来。 你需要根据实际的串口设备文件路径和超声波模块的通信协议进行相应的修改。另外,记得编译这个程序时加上`-ltermcap`参数,例如`gcc example.c -o example -ltermcap`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值