搜索
bottom↓
回复: 14

分享一个自己写的STM32的DMA串口收发的例子,来抛砖引玉……

[复制链接]

出0入0汤圆

发表于 2015-7-15 17:58:58 | 显示全部楼层 |阅读模式
本帖最后由 654705188 于 2015-7-16 09:24 编辑

#ifndef _RDCOM_H_
#define _RDCOM_H_
#include "driver_about.h"
//////////////////////////////////////////////////////////////////////
#define RDCOMDEBUG            0

#define RDCOM_MODE            RDCOM_DMA//USART收发数据的方式-查询、中断、DMA

#define RDCOMUSART            USART1  //串口号
#define RDCOM_RCC_APBnPeriphClockCmd()  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE)//打开串口时钟
//配置IO口前别忘了开启IO时钟
#define RDCOMRX_PORT                             GPIOA
#define RDCOMRX_PIN                             GPIO_Pin_10//RX
#define RDCOMTX_PORT                             GPIOA
#define RDCOMTX_PIN                             GPIO_Pin_9//TX

////////////////////中断方式下需要配置////////////////////////////////
#define RDCOMUSART_IRQ                  USART1_IRQn       //串口接收中断
#define RDCOMUSART_IRQHandler           USART1_IRQHandler //串口接收中断服务
////////////////////DMA方式下需要配置////////////////////////////////
#define RDCOMPerph_Addr                 (u32)(&(USART1->DR)) //串口发送寄存器作为目的地址
#define RDCOM_RCC_AHBPeriphClockCmd()   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE)//DMA时钟

#define RDCOMDMAn_Channeln_Send         DMA1_Channel4//DMA通道TX选择
#define RDCOMDMAn_IT_TC_Send            DMA1_IT_TC4//传输完成中断
#define RDCOMDMAn_IT_TE_Send            DMA1_IT_TE4//传输错误中断
#define RDCOMDMAn_IT_GL_Send            DMA1_IT_GL4//全部中断
#define RDCOMDMAn_Chn_IRQn_Send         DMA1_Channel4_IRQn
#define RDCOMUSART_DMAHandler_Send      DMA1_Channel4_IRQHandler//DMA中断服务

#define RDCOMDMAn_Channeln_Recv         DMA1_Channel5//DMA通道RX选择
#define RDCOMDMAn_FLAG_GL_Recv          DMA1_FLAG_GL5//DMA传输的所有标志
#define RDCOMDMAn_IT_TC_Recv            DMA1_IT_TC5//传输完成中断
#define RDCOMDMAn_IT_TE_Recv            DMA1_IT_TE5//传输错误中断
#define RDCOMDMAn_IT_GL_Recv            DMA1_IT_GL5//全部中断
#define RDCOMDMAn_Chn_IRQn_Recv         DMA1_Channel5_IRQn
#define RDCOMUSART_DMAHandler_Recv      DMA1_Channel5_IRQHandler//DMA中断服务
/////////////////// 以下不需要修改////////////////////////////////////
#define RDCOM_NORMAL          0         //USART收发数据的方式的选项
#define RDCOM_INT             1
#define RDCOM_DMA             2

s8 RDCOMUsartInit(u32 baudrate);//串口初始化,输入波特率,只需要调用此函数即可完成初始化
//////////////////查询方式下:mode=RDCOM_NORMAL/////////////////
#if(RDCOM_MODE==RDCOM_NORMAL)
u8 RDCOMnormal_Send(u8 *data,u8 len);
u8 RDCOMnormal_Receive(u8 *data,u16 timeout_ms);
u8 RDCOMnormal_Receive_Char(u8 *data,char ch,u16 timeout_ms);
u8 RDCOMnormal_Receive_Len(u8 *data,u8 len,u16 timeout_ms);
#endif
//////////////////中断方式下:mode=RDCOM_INT/////////////////
#if(RDCOM_MODE==RDCOM_INT)
void RDCOMUSART_IRQHandler(void);//中断接收服务
#endif
//////////////////DMA方式下 :mode=RDCOM_DMA/////////////////
#if(RDCOM_MODE==RDCOM_DMA)
u8   RDCOMDMA_Send(u8 *Send_Data,u8 len);//通过DMA发送数据
void RDCOMUSART_DMAHandler(void);//USART的DMA发送完成或错误中断服务
#endif


////////////////////////////////////////////////////////////////////////
extern s8 RDCOM_Send(u8 *sdata,u8 len,OS_TICK timeout);
extern s8 RDCOM_Recv(u8 *rdata,u8 *len,OS_TICK timeout);
extern s8 RDCOM_SendRecv(u8 *send_data,u8 send_len,u8 *recv_data,u8 *recv_len,OS_TICK timeout);//有延时的发送和接收数据
#endif


#include "rdcom.h"

#if(RDCOM_MODE==RDCOM_DMA)
static CPU_TS ts=0;  //存放发送消息时的时间戳OS_TS_GET()
static OS_ERR err;   //返回的错误信息
OS_SEM RDCOMSend_Sem;
OS_SEM RDCOMRecv_Sem;
        
#endif

void RDCOMGPIO_Config(void)//串口IO口配置
{
        GPIO_InitTypeDef GPIO_InitStructure;
        
        GPIO_InitStructure.GPIO_Pin = RDCOMRX_PIN;//
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//2M
        GPIO_Init(RDCOMRX_PORT,&GPIO_InitStructure);//

        GPIO_InitStructure.GPIO_Pin = RDCOMTX_PIN;//
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//2M
        GPIO_Init(RDCOMTX_PORT, &GPIO_InitStructure);//
}

void RDCOMUSART_Config(u32 baudrate)//串口初始化
{
        USART_InitTypeDef USART_InitStructure;
        RDCOM_RCC_APBnPeriphClockCmd();
        
        USART_StructInit(&USART_InitStructure);//将结构体设置为缺省状态,9600bps,8数据位,1停止位,不校验,硬件流控制失能
        USART_InitStructure.USART_BaudRate =baudrate;//波特率设置
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//一帧数据的宽度设置为8bits
        USART_InitStructure.USART_StopBits = USART_StopBits_1;//在帧结尾传输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(RDCOMUSART, &USART_InitStructure);//设置串口
#if(RDCOM_MODE==RDCOM_INT)
        USART_ITConfig(RDCOMUSART, USART_IT_RXNE, ENABLE);//打开接收中断
#endif
        USART_Cmd(RDCOMUSART, ENABLE);//打开串口
        USART_GetFlagStatus(RDCOMUSART, USART_FLAG_TC);
        //发送数据前先清除标志位,否则第1字节数据会丢失
}
///////////////////查询方式下///////////////////////////////////
#if(RDCOM_MODE==RDCOM_NORMAL)
u8 RDCOMnormal_Send(u8 *data,u8 len)
{
        u8 i=0;
        for(i=0;i<len;i++)
                {
                USART_SendData(RDCOMUSART, data);//发送数据
                while(USART_GetFlagStatus(RDCOMUSART, USART_FLAG_TC) == RESET);//等待数据发送完毕
                }
        return i;
}
u8 RDCOMnormal_Receive(u8 *data,u16 timeout_ms)
{
        u32 timeout=timeout_ms*740,timeout_count=0;
        u8 i=0;
        while(timeout_count<timeout)//等待时间设置
        {
                if (USART_GetFlagStatus(RDCOMUSART, USART_FLAG_RXNE) != RESET)  //判断接收标志;查询方式的USART接收
                {
                data[i++]=USART_ReceiveData(RDCOMUSART);
                timeout_count=0;
                }
                else
                {
                timeout_count++;
                }               
        }
        return i;
}

u8 RDCOMnormal_Receive_Char(u8 *data,char ch,u16 timeout_ms)//ms
{
        u32 timeout=timeout_ms*740,timeout_count=0;        
        u8 i=0;
        while(timeout_count<timeout)//等待时间设置600000=800ms
        {
                if (USART_GetFlagStatus(RDCOMUSART, USART_FLAG_RXNE) != RESET)  //判断接收标志;查询方式的USART接收
                {
                data[i++]=USART_ReceiveData(RDCOMUSART);
                timeout_count=0;
                if(data[i-1]==ch)
                        break;
                }
                else
                {
                timeout_count++;
                }               
        }
        return i;
}
u8 RDCOMnormal_Receive_Len(u8 *data,u8 len,u16 timeout_ms)
{
        u32 timeout=timeout_ms*740,timeout_count=0;        
        u8 i=0;
        while(timeout_count<timeout)//等待时间设置
        {
                if (USART_GetFlagStatus(RDCOMUSART, USART_FLAG_RXNE) != RESET)  //判断接收标志;查询方式的USART接收
                {
                data[i++]=USART_ReceiveData(RDCOMUSART);
                timeout_count=0;
                if(i>=len)
                        break;
                }
                else
                {
                timeout_count++;
                }               
        }
        return i;
}
#endif
///////////////////中断方式下////////////////////////////////////////////////////////////////////////
#if(RDCOM_MODE==RDCOM_INT)
void RDCOMUSART_IRQHandler(void)//中断方式的USART接收
{
        if(USART_GetITStatus(RDCOMUSART, USART_IT_RXNE) != RESET) //判断发生接收中断
        {//USART_ClearITPendingBit(RDCOMUSART,  USART_IT_RXNE);    //清除中断标志,读接收到的数据时自动清除
               
         //USART_SendData(RDCOMUSART, USART_ReceiveData(RDCOMUSART));//发送数据
         //while(USART_GetFlagStatus(RDCOMUSART, USART_FLAG_TC) == RESET);//等待数据发送完毕
        }
}
void RDCOMNVIC_Config(void)//配置中断
{
        NVIC_InitTypeDef NVIC_InitStructure;
        //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//选择中断分组1
        NVIC_InitStructure.NVIC_IRQChannel = RDCOMUSART_IRQ;//选择串口中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占式中断优先级设置为0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//响应式中断优先级设置为3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断
        NVIC_Init(&NVIC_InitStructure);
}
#endif
///////////////////DMA方式下////////////////////////////////////////////////////////////////////////
#if(RDCOM_MODE==RDCOM_DMA)
u8 RDCOMDMA_Send(u8 *send_data,u8 len)
{  
     DMA_InitTypeDef DMA_InitStructure;
      //if(RDCOM_DMASend_Finish!=1)//发送未完成
      //return 0;
      //RDCOM_DMASend_Finish=0;//DMA发送完成的标志,1为发送完成
     USART_GetFlagStatus(RDCOMUSART,USART_FLAG_ORE);//清溢出标志USART_FLAG_NE,USART_FLAG_FE,USART_FLAG_PE
     USART_ReceiveData(RDCOMUSART);//清缓存
        
     RDCOM_RCC_AHBPeriphClockCmd();
     DMA_DeInit(RDCOMDMAn_Channeln_Send);//复位DMA-TX通道
     DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)RDCOMPerph_Addr;//外设地址
     DMA_InitStructure.DMA_MemoryBaseAddr     = (u32)send_data;//内存地址,自己开辟的数组
     DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;//外设作为数据传输的目的地
     DMA_InitStructure.DMA_BufferSize         = len;//传输的数据长度,单位在下边设置

     DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;//设置DMA外设递增模式禁止
     DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable; //设置DMA内存递增模式使能
     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_Medium;//设置DMA优先级
     DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;//内存到内存禁止
     DMA_Init(RDCOMDMAn_Channeln_Send, &DMA_InitStructure);//配置完成后,启动DMA通道
     USART_DMACmd(RDCOMUSART,USART_DMAReq_Tx,ENABLE);//使能USART的发送DMA请求
     DMA_Cmd(RDCOMDMAn_Channeln_Send, ENABLE);
     DMA_ITConfig(RDCOMDMAn_Channeln_Send, DMA_IT_TC, ENABLE); //DMA传输完成
   return len;
}
void RDCOMDMANVIC_Config_Send(void)//配置中断
{
        NVIC_InitTypeDef NVIC_InitStructure;
        //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//选择中断分组1
        NVIC_InitStructure.NVIC_IRQChannel = RDCOMDMAn_Chn_IRQn_Send;//选择DMA中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占式中断优先级设置为0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;//响应式中断优先级设置为3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断
        NVIC_Init(&NVIC_InitStructure);
}
void RDCOMUSART_DMAHandler_Send(void)//USART的DMA发送完成或错误中断
{
        OSIntEnter();
        
         if(DMA_GetITStatus(RDCOMDMAn_IT_TC_Send) != RESET) //判断发生DMA发送完成中断
        {  
                //RDCOM_DMASend_Finish=1;//DMA发送完成的标志,1为发送完成
                OSSemPost(&RDCOMSend_Sem,OS_OPT_POST_1,&err);//发送完成信号
                DMA_ClearITPendingBit(RDCOMDMAn_IT_GL_Send);    //清除全部中断标志
        }         

        OSIntExit();
}



u8 RDCOMDMA_Recv(u8 *recv_data,u8 len)
{
     DMA_InitTypeDef DMA_InitStructure;
      //if(RDCOM_DMARecv_Finish!=1)//接收未完成
      //return 0;
      //RDCOM_DMARecv_Finish=0;//DMA接收完成的标志,1为接收完成
     USART_GetFlagStatus(RDCOMUSART,USART_FLAG_ORE);//清溢出标志USART_FLAG_NE,USART_FLAG_FE,USART_FLAG_PE
     USART_ReceiveData(RDCOMUSART);//清缓存
        
     RDCOM_RCC_AHBPeriphClockCmd();
     DMA_DeInit(RDCOMDMAn_Channeln_Recv);//复位DMA-RX通道
     DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)RDCOMPerph_Addr;//外设地址
     DMA_InitStructure.DMA_MemoryBaseAddr     = (u32)recv_data;//内存地址,自己开辟的数组
     DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralSRC;//外设作为数据传输的数据源
     DMA_InitStructure.DMA_BufferSize         = len;//传输的数据长度,单位在下边设置

     DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;//设置DMA外设递增模式禁止
     DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable; //设置DMA内存递增模式使能
     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_Medium;//设置DMA优先级
     DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;//内存到内存禁止
     DMA_Init(RDCOMDMAn_Channeln_Recv, &DMA_InitStructure);//配置完成后,启动DMA通道
     USART_DMACmd(RDCOMUSART,USART_DMAReq_Rx,ENABLE);//使能USART的接收DMA请求
     DMA_Cmd(RDCOMDMAn_Channeln_Recv, ENABLE);
     DMA_ITConfig(RDCOMDMAn_Channeln_Recv, DMA_IT_TC, ENABLE); //DMA传输完成
   return len;
}
void RDCOMDMANVIC_Config_Recv(void)//配置中断
{
        NVIC_InitTypeDef NVIC_InitStructure;
        //NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//选择中断分组1
        NVIC_InitStructure.NVIC_IRQChannel = RDCOMDMAn_Chn_IRQn_Recv;//选择DMA中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占式中断优先级设置为0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//响应式中断优先级设置为2
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能中断
        NVIC_Init(&NVIC_InitStructure);
}
void RDCOMUSART_DMAHandler_Recv(void)//USART的DMA接收完成或错误中断
{
        OSIntEnter();
        USART_DMACmd(RDCOMUSART,USART_DMAReq_Rx,DISABLE);//禁能USART的接收DMA请求
        if(DMA_GetITStatus(RDCOMDMAn_IT_TC_Recv) != RESET) //判断发生DMA接收完成中断
        {
                //RDCOM_DMARecv_Finish=1;//DMA接收完成的标志,1为接收完成        
                OSSemPost(&RDCOMRecv_Sem,OS_OPT_POST_1,&err);//发送完成信号
                DMA_ClearITPendingBit(RDCOMDMAn_IT_GL_Recv);        //清除全部中断标志
        }
               
        OSIntExit();
}

#endif
////////////////////////////////////////////////////////////////////////////////////////////////////        
s8 RDCOMUsartInit(u32 baudrate)
{
        RDCOMUSART_Config(baudrate);//串口初始化,与第二句顺序互换是避免复位后发送一个FF
        RDCOMGPIO_Config();//串口IO口配置        
#if(RDCOM_MODE==RDCOM_INT)
        RDCOMNVIC_Config();//配置中断
#endif
#if(RDCOM_MODE==RDCOM_DMA)
        RDCOMDMANVIC_Config_Send();
        RDCOMDMANVIC_Config_Recv();
        OSSemCreate(&RDCOMSend_Sem,(char *)"RDCOMSend Sem", 0, &err);
        OSSemCreate(&RDCOMRecv_Sem,(char *)"RDCOMRecv Sem", 0, &err);
#endif
        return ERR_NO;
        }
/**************************************************************************************
        **********************以下为RDCOM设置处理函数******************************************
***************************************************************************************/
s8 RDCOM_Send(u8 *sdata,u8 len,OS_TICK timeout)//OS_CFG_TICK_RATE_HZ
{
        if(len>0)//有发送数据
        {
                OSSemSet(&RDCOMSend_Sem,0,&err);//清发送信号量
                RDCOMDMA_Send((u8 *)sdata,len);//开始发送
                OSSemPend(&RDCOMSend_Sem,timeout,OS_OPT_PEND_BLOCKING,&ts,&err);//信号量等待
                USART_DMACmd(RDCOMUSART,USART_DMAReq_Tx,DISABLE);//禁能USART的发送DMA请求
                if(err!=OS_ERR_NONE) return ERR_ERROR;//发送数据时出错
        }
        return ERR_NO;
}

s8 RDCOM_Recv(u8 *rdata,u8 *len,OS_TICK timeout)
{
        s8 re=0;
        memset(rdata,0,DATAPKG_MAXLEN);
        OSSemSet (&RDCOMRecv_Sem,0,&err);//清接收信号量
        RDCOMDMA_Recv(rdata,DATAPKG_XORMINLEN);//开始接收
        OSSemPend(&RDCOMRecv_Sem,timeout,OS_OPT_PEND_BLOCKING,&ts,&err);//信号量等待
        if(err!=OS_ERR_NONE)
        {
                return ERR_ERROR;
        }
        re=Check_Data_Pkghead(rdata);
        if(re==ERR_NO)//数据头正确
        {
          RDCOMDMA_Recv(DATARECV(rdata)->DATA,DATARECV_DLEN(rdata)+DATAPKG_MINLEN-DATAPKG_XORMINLEN);//开始接收
          OSSemPend(&RDCOMRecv_Sem,timeout,OS_OPT_PEND_BLOCKING,&ts,&err);//信号量等待
                if(err==OS_ERR_NONE)
                {
                    *len=DATARECV_DLEN(rdata)+DATAPKG_MINLEN;
                    return ERR_NO;
                }
                if(err==OS_ERR_TIMEOUT)//第二次接收超时
                {
                  *len=DATAPKG_XORMINLEN;
                  return ERR_NO;
                }
        
        }
        //头错误
        {        
          USART_DMACmd(RDCOMUSART,USART_DMAReq_Rx,DISABLE);//禁能USART的接收DMA请求
          return re;
        }
}

s8 RDCOM_SendRecv(u8 *send_data,u8 send_len,u8 *recv_data,u8 *recv_len,OS_TICK timeout)//有延时的发送和接收数据
{
        s8 re=0;
        memset(recv_data,0,DATAPKG_MAXLEN);
        OSSemSet (&RDCOMRecv_Sem,0,&err);//清接收信号量
        
        if(send_len>0)//有发送数据
        {
                OSSemSet(&RDCOMSend_Sem,0,&err);//清发送信号量
                RDCOMDMA_Send((u8 *)send_data,send_len);//开始发送
                OSSemPend(&RDCOMSend_Sem,timeout,OS_OPT_PEND_BLOCKING,0,&err);//信号量等待
                if(err!=OS_ERR_NONE) return ERR_ERROR;
        }
        
        RDCOMDMA_Recv(recv_data,DATAPKG_MAXLEN);//开始接收
        OSSemPend(&RDCOMRecv_Sem,timeout,OS_OPT_PEND_BLOCKING,&ts,&err);//信号量等待100ms
        if(err==OS_ERR_NONE)
        {
                *recv_len=DATARECV_DLEN(recv_data)+DATAPKG_MINLEN;
                return ERR_NO;
        }
        if(err==OS_ERR_TIMEOUT)//第二次接收超时
        {
                *recv_len=DATAPKG_XORMINLEN;
                return ERR_NO;
        }
        
        //错误
        {               
               USART_DMACmd(RDCOMUSART,USART_DMAReq_Rx,DISABLE);//禁能USART的接收DMA请求
               return re;
        }        
}

出0入0汤圆

发表于 2015-7-15 18:03:40 | 显示全部楼层
多谢分享,上个工程文件就更好了。

出0入0汤圆

 楼主| 发表于 2015-7-15 18:10:17 | 显示全部楼层
feezai 发表于 2015-7-15 18:03
多谢分享,上个工程文件就更好了。

这是商业项目中的一个模块,恕我不便发出。
其实如果去掉有关 OS的几句,然后直接复制到.h 和.c文件就可以编译的。

出0入0汤圆

发表于 2015-7-15 18:14:55 | 显示全部楼层
654705188 发表于 2015-7-15 18:10
这是商业项目中的一个模块,恕我不便发出。
其实如果去掉有关 OS的几句,然后直接复制到.h 和.c文件就可 ...

ok, 无论如何都表示感谢。

出0入8汤圆

发表于 2015-7-15 22:40:03 | 显示全部楼层
这种代码风格实在是乱

只有楼主自己能懂吧。。。

还不如说下实现的机制

出0入0汤圆

发表于 2015-7-15 23:32:18 | 显示全部楼层
  楼主,你需要解释下,不然谁看到这么乱的一坨代码都发愁。

出0入0汤圆

 楼主| 发表于 2015-7-16 09:08:28 | 显示全部楼层
brieve 发表于 2015-7-15 23:32
楼主,你需要解释下,不然谁看到这么乱的一坨代码都发愁。

其实并不乱啊,都是由三个宏控制的
#define RDCOMDEBUG            0//是否使能串口debug调试

#define RDCOM_MODE            RDCOM_DMA//USART收发数据的方式-查询、中断、DMA

#define RDCOMUSART            USART1  //串口号
静下心来,就会明白的。

出0入0汤圆

发表于 2015-7-16 09:11:30 | 显示全部楼层
串口的代码,接口映射选项有限,简化到只指明UART?即可。
另,个人不喜欢满屏注释的代码。

出0入0汤圆

 楼主| 发表于 2015-7-16 09:17:47 | 显示全部楼层
styleno1 发表于 2015-7-16 09:11
串口的代码,接口映射选项有限,简化到只指明UART?即可。
另,个人不喜欢满屏注释的代码。 ...

此程序可以用于所有串口的不同通讯方式查询、中断、DMA只需要设置.h文件中的 几个参数即可。还是很方便的。重点是DMA方式下配合OS收发数据,效率很高。
代码风格 ,这东西,每个人都有不同的喜好,见仁见智啊。

出100入85汤圆

发表于 2015-7-16 09:49:12 | 显示全部楼层
能提供有操作 系统和无操作系统的例程吗  ?

出0入0汤圆

发表于 2016-3-22 16:11:43 | 显示全部楼层
MARK STM32的DMA串口

出0入45汤圆

发表于 2016-3-22 21:31:24 | 显示全部楼层
MARK下 STM32的DMA

出0入0汤圆

发表于 2016-3-22 22:08:56 | 显示全部楼层
谢谢分享~~~~~~~

出0入0汤圆

发表于 2016-3-23 18:00:22 | 显示全部楼层
谢谢分享!

出0入0汤圆

发表于 2018-3-20 23:49:14 | 显示全部楼层
MARK一下DMA串口
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-7 15:47

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表