历史上的今天

今天是:2024年10月09日(星期三)

正在发生

2020年10月09日 | STM32的串口采用DMA方式接收数据测试

发布者:limm20032003 来源: eefocus关键字:STM32  串口  DMA方式  接收数据 手机看文章 扫描二维码
随时随地手机看文章

环境:


主机:WINXP


开发环境:MDK4.23


MCU:STM32F103CBT6




说明:


串口可以配置成用DMA的方式接收数据,不过DMA需要定长才能产生接收中断,如何接收可变长度的数据呢?


方法有以下3种:


1.将RX脚与一路时钟外部引脚相连,当串口一帧发完,即可利用此定时器产生超时中断.这个实时性较高,可以做到1个字节实时监测.


2.不改变硬件,开启一个定时器监控DMA接收,如果超时则产生中断.这个实时性不高,因为超时时间必须要大于需要接收帧的时间,精度不好控制.


3.STM32单片机有的串口可以监测总线是否处于空闲,如果空闲则产生中断.可以用它来监测DMA接收是否完毕.这种方式实时性很高.


本文采用第3种方式.在波特率576000下大数据包冲击证明可行.




源代码:



//串口接收DMA缓存

#define UART_RX_LEN 128

extern uint8_t Uart_Rx[UART_RX_LEN];


//串口接收DMA缓存

uint8_t Uart_Rx[UART_RX_LEN] = {0};


//---------------------串口功能配置---------------------

//打开串口对应的外设时钟  

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE); 

//串口发DMA配置  

//启动DMA时钟

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

//DMA发送中断设置

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

//DMA1通道4配置

DMA_DeInit(DMA1_Channel4);

//外设地址

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);

//内存地址

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Uart_Send_Buffer;

//dma传输方向单向

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

//设置DMA在传输时缓冲区的长度

DMA_InitStructure.DMA_BufferSize = 100;

//设置DMA的外设递增模式,一个外设

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

//设置DMA的内存递增模式

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

//外设数据字长

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

//内存数据字长

DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;

//设置DMA的传输模式

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

//设置DMA的优先级别

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

//设置DMA的2个memory中的变量互相访问

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel4,&DMA_InitStructure);

DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);

//使能通道4

//DMA_Cmd(DMA1_Channel4, ENABLE);

 

//串口收DMA配置  

//启动DMA时钟

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

//DMA1通道5配置

DMA_DeInit(DMA1_Channel5);

//外设地址

DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);

//内存地址

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Uart_Rx;

//dma传输方向单向

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

//设置DMA在传输时缓冲区的长度

DMA_InitStructure.DMA_BufferSize = UART_RX_LEN;

//设置DMA的外设递增模式,一个外设

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

//设置DMA的内存递增模式

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

//外设数据字长

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

//内存数据字长

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

//设置DMA的传输模式

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

//设置DMA的优先级别

DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;

//设置DMA的2个memory中的变量互相访问

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel5,&DMA_InitStructure);

 

//使能通道5

DMA_Cmd(DMA1_Channel5,ENABLE);

  

    //初始化参数  

    //USART_InitStructure.USART_BaudRate = DEFAULT_BAUD;  

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;  

    USART_InitStructure.USART_StopBits = USART_StopBits_1;  

    USART_InitStructure.USART_Parity = USART_Parity_No;  

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  

    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    

    USART_InitStructure.USART_BaudRate = DEFAULT_BAUD; 

//初始化串口 

    USART_Init(USART1,&USART_InitStructure);  

    //TXE发送中断,TC传输完成中断,RXNE接收中断,PE奇偶错误中断,可以是多个   

    //USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

//中断配置

USART_ITConfig(USART1,USART_IT_TC,DISABLE);

USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);

USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);  

 

//配置UART1中断  

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;               //通道设置为串口1中断  

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;       //中断占先等级0  

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;              //中断响应优先级0  

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //打开中断  

    NVIC_Init(&NVIC_InitStructure);   

        

//采用DMA方式发送

USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);

//采用DMA方式接收

USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);

    //启动串口  

    USART_Cmd(USART1, ENABLE); 


//串口1接收中断   

void USART1_IRQHandler(void)                               

{   

uint32_t temp = 0;

uint16_t i = 0;

if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)

    {

    //USART_ClearFlag(USART1,USART_IT_IDLE);

    temp = USART1->SR;

    temp = USART1->DR; //清USART_IT_IDLE标志

    DMA_Cmd(DMA1_Channel5,DISABLE);

 

temp = UART_RX_LEN - DMA_GetCurrDataCounter(DMA1_Channel5);

for (i = 0;i < temp;i++)

{

Data_Receive_Usart = Uart_Rx[i];

  //启动串口状态机

usart_state_run(); 

}

 

//设置传输数据长度

DMA_SetCurrDataCounter(DMA1_Channel5,UART_RX_LEN);

    //打开DMA

DMA_Cmd(DMA1_Channel5,ENABLE);

    } 

__nop(); 


测试结果:


条件:单片机运行于72M,与PC通信速率为460800.PC每隔100ms发送一个9个字节的包:c5 5c 6 0 6F 10 5 4e f7.


测试:单片机每次收到此包,一个IO作电平跳转,然后处理返回一包.


示波器显示:

放大显示:

关键字:STM32  串口  DMA方式  接收数据 引用地址:STM32的串口采用DMA方式接收数据测试

上一篇:STM32单片机PWM输出测试
下一篇:STM32的串口采用DMA方式发送数据测试

推荐阅读

您了解当下的现状。您部门中的一些人员刚刚参加了一场关于全新人机协作技术的研讨会。如今,他们请求您帮助其朝着技术实施迈出第一步。毫无疑问,机器人密度以及人机协作应用在所有制造业领域处于一个快速上升通道。作为机器人技术的早期采用者,汽车行业也是最早在车间广泛采用人机协作技术的行业之一。但是要部署这项技术,您需要在一开始知道哪些事情?...
据外媒报道,当地时间9月26日,瑞萨电子公司(Renesas Electronics Corporation)宣布与StradVision公司合作,联合研发一个基于深度学习的目标识别解决方案,用于下一代高级驾驶辅助系统(ADAS)的智能摄像头,适用于L2及以上的ADAS。瑞萨电子是先进半导体解决方案的主要供应商,而StradVision是为自动驾驶汽车提供视觉处理技术解决方案的供应商,而且该...
有的人第一次使用示波器可能会被示波器的一堆理论知识绕晕,从而丧失学习的兴趣。如果我们一开始能先学习如何测量一个简单的信号,快速的入门和获得成就感,也许就更有动力去学习和了解示波器。基于这种想法,在学习一些理论知识之前,我们可以先来看看如何用示波器测量一个简单的信号。准备工具:示波器,探头第一步:示波器开机,然后将探头与示波器相连...
在具挑战的照明条件下带来同类最佳的动态范围AR0821CS具有先进的功能和卓越的图像质量,已被集成到Basler dart系列区域扫描相机模块中2021年10月9日—领先于智能电源和智能感知技术的安森美(onsemi,美国纳斯达克股票代号:ON),宣布推出新的1/1.7英寸830万像素CMOS数字图像传感器,该传感器采用卷帘快门和嵌入式高动态范围(eHDR)技术。AR0821CS在具挑战...

史海拾趣

问答坊 | AI 解惑

WinCE下声音的问题(急请达人指教)

程序要分离系统声音和按键声音,使两者互不干扰。 现在系统声音的设置通过waveOutSetVolume(0, 音量值) 这种情况下,可不可以实现另外做一个音频的通道,使其不受主音量的干扰,成为按键的声音? 要怎么做才能实现呢? 请指教啊~~~~~谢谢…

查看全部问答∨

修改了WINCE下自带的源代码,如何快速编译把修改的情况及时反应到新的NK里面去?要求对系统不进行全部编译。

修改了WINCE下自带的源代码,如何快速编译把修改的情况及时反应到新的NK里面去?要求对系统不进行全部编译。…

查看全部问答∨

hid设备控制问题? audio与usb复合设备

现在有个心片,是一个usb的audio设备 ,我现在可以把她作为一个普通的usb设备读写,但是现在有个问题就是希望该设备作为audio 设备来播放音乐,除了控制命令用endpoint1和4来传外,另外的audio channel怎么指定啊? 谢谢指定一下!…

查看全部问答∨

请问在MTK开发平台上后缀名为.pth文件是做什么用的?

请问在MTK开发平台上后缀名为.pth文件是做什么用的?…

查看全部问答∨

QQ的内嵌技术

您好,我使用MVC架构(java语言)来作QQ内嵌,实现用户可通过QQ和在线的管理员进行交流。我在网上搜索后,没有找到可用的资源。请您指教!…

查看全部问答∨

LM3开发笔记_2.时钟和GPIO

        今天熟悉了一下LM提供的StellarisWare固件库,感觉跟STM32的固件库有很大的差异,使用上有点像Windows平台API函数的意思,使用外设的时候到对应的固件库看看有啥函数可以用就行了。   &nbs ...…

查看全部问答∨

请问版主STR710的IIC功能现在有没有解决?

                                 没有波形出来呀,还会死机。…

查看全部问答∨

请高手看看我的程序那错了

MOV #00H, R4 ; MOV #05H ,R8 ; MOV #200H ,R6 ; LOOP_M1 MOV.B M_S(R4),R6 ;标准读写模式设置将模式数据放到RJ6指向的地址中 ...…

查看全部问答∨

看门狗不会复位怎么办

看门狗不会复位怎么办,我用的是MSP430147,究竟是什么导致这种情况发生的呢?…

查看全部问答∨

μC/OS-II下通用驱动框架的设计与实现 转

      摘要:在μC/OS-II下,设计了一个通用的设备管理模型,称为通用驱动框架,通过该驱动框架,可以实现对硬件设备的   统一、一致的管理,同时,也为上层应用程序提供了统一、一致的设备访问接口,并在以ARM7TDMI ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved