OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3270|回复: 15

串口+DMA对齐

[复制链接]

2

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
110
金钱
110
注册时间
2018-3-15
在线时间
22 小时
发表于 2018-3-15 17:17:55 | 显示全部楼层 |阅读模式
1金钱
还是那个问题,配置串口+DMA接收数据,buffer接收数据错位,如图,本来应该帧头0x55,0x51在最开始的
dma.png

最佳答案

查看完整内容[请看2#楼]

[mw_shl_code=applescript,true]void MYDMA_Enable(DMA_Channel_TypeDef* DMAy_Channelx)//重新传输设置 { DMA_Cmd(DEBUG_RX_DMA_CHANNEL,DISABLE); //失能通道 DMAy_Channelx->CNDTR = USART_ARRAY_LEN; //重新写入数量 DMAy_Channelx->CMAR = (u32)USART_RX_BUF;//重新设置存储器地址指针 DMA_Cmd(DEBUG_RX_DMA_CHANNEL,ENABLE); //使能通道 } void DEBUG_USART_IRQHandler(v ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

10

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
817
金钱
817
注册时间
2016-2-5
在线时间
163 小时
发表于 2018-3-15 17:17:56 | 显示全部楼层
Luxs 发表于 2018-4-25 17:03
我就是用的空闲中断方式,请问你空闲中断的方式有碰到过我这种情况吗?

[mw_shl_code=applescript,true]void MYDMA_Enable(DMA_Channel_TypeDef* DMAy_Channelx)//重新传输设置
{
     DMA_Cmd(DEBUG_RX_DMA_CHANNEL,DISABLE);   //失能通道
     DMAy_Channelx->CNDTR = USART_ARRAY_LEN;  //重新写入数量     
     DMAy_Channelx->CMAR = (u32)USART_RX_BUF;//重新设置存储器地址指针
     DMA_Cmd(DEBUG_RX_DMA_CHANNEL,ENABLE);   //使能通道         
}

void DEBUG_USART_IRQHandler(void)
{
    if(USART_GetITStatus(DEBUG_USARTx,USART_IT_IDLE) == SET)    //这个步骤已经进行了SR的读操作
    {
        USART_ReceiveData(DEBUG_USARTx);//清除总线空闲中断需要先读USART_SR,然后读USART_DR
        USART_RX_NUM = USART_ARRAY_LEN - DMA_GetCurrDataCounter(DEBUG_RX_DMA_CHANNEL);
        //数量在DMA使能时只可以进行读的操作。
        USART_RX_STA = 1; //传输完成标志置位                                 
        USART_ClearITPendingBit(DEBUG_USARTx, USART_IT_IDLE);         //清除中断标志
        MYDMA_Enable(DEBUG_RX_DMA_CHANNEL);                   //恢复DMA指针,等待下一次的接收        
    }
}[/mw_shl_code],我是这样写的
不甘黄土掩枯骨,宁化寒光映碧霄。
回复

使用道具 举报

2

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
110
金钱
110
注册时间
2018-3-15
在线时间
22 小时
 楼主| 发表于 2018-3-15 17:18:24 | 显示全部楼层
能否有人提供点解决的方向
回复

使用道具 举报

21

主题

2205

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5141
金钱
5141
注册时间
2014-8-26
在线时间
1317 小时
发表于 2018-3-15 18:16:25 | 显示全部楼层
帮顶。
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
发表于 2018-3-15 19:56:08 | 显示全部楼层
描述再具体一点。看着这个问题想提点建议真的无从下手
没有脑袋
回复

使用道具 举报

2

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
110
金钱
110
注册时间
2018-3-15
在线时间
22 小时
 楼主| 发表于 2018-3-15 20:11:20 | 显示全部楼层
美丽的时光机器 发表于 2018-3-15 19:56
描述再具体一点。看着这个问题想提点建议真的无从下手

就是我的STM32串口端接收数据期望的是Usart2Type.usartDMA_rxBuf[0]=0x55,Usart2Type.usartDMA_rxBuf[0]=0x51...这个是别的模块发送过来的数据帧头,但是有时候发现里面接收数据的顺序如上面图片的了,串口加DMA配置就是按照CubeMX配置的
回复

使用道具 举报

3

主题

40

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
241
金钱
241
注册时间
2015-7-8
在线时间
46 小时
发表于 2018-3-15 21:14:37 | 显示全部楼层
本帖最后由 寂青山 于 2018-3-15 21:15 编辑

帮助不能,不过提供 USART+DMA 驱动代码倒是可以,走MODBUS协议,连接BMCS服务器,跑得正常。
本代码只提供参考!!!!!


#include <STM32F10X.H>
#include <USART.H>
#include <USART2_SERVICEACCESS.H>
#include <LED.H>

/* USART2 &#187;o′&#230; */
void  ( *USART2_DataProcessing )( uint8_t *CL_Pointer ) ;
uint8_t USART2_Buff[ 255 ] = { 0x00 } ;

/*===============================================================================*/
//
// USART2&#197;&#228;&#214;&#195;:
// 2¨ì&#216;&#194;ê&#206;a9600£&#172;êy&#190;Y&#206;&#187;&#206;a8£&#172;&#197;&#188;D£&#209;é£&#172;ò&#187;&#184;&#246;í£&#214;1&#206;&#187;;
// STM32 &#214;D×&#214;3¤&#197;&#228;&#214;&#195;&#206;a 9 &#206;&#187;£&#172;&#198;&#230;&#197;&#188;D£&#209;é1|&#196;ü&#191;a&#198;&#244;£&#172;&#188;′&#198;&#230;&#197;&#188;D£&#209;é&#206;&#187;&#213;y3£&#189;óê&#213;£&#172;μ&#171;2&#187;′|àí;
// USART2 &#212;ú&#196;&#172;è&#207;&#199;é&#191;&#246;&#207;&#194;£&#172;′|óú&#189;óê&#213;&#196;£ê&#189;;
//
/*===============================================================================*/
void USART2_Init( void )
{
/* ′ò&#191;a&#203;ùê1ó&#195;μ&#196; GPIO &#191;úê±&#214;óê1&#196;ü */
        if( !( RCC -> APB2ENR |= RCC_APB2ENR_IOPAEN ) )                                // GPIOA ê±&#214;ó
        {
                RCC -> APB2ENR |= RCC_APB2ENR_IOPAEN ;
        }
        
/* USART2 DMA′&#171;ê&#228;3&#245;ê&#188;&#187;ˉ */
        DMA1_Channel6 -> CCR  |= DMA_CCR6_MINC | DMA_CCR6_PL ;                        // DMA &#189;óê&#213;
        DMA1_Channel6 -> CMAR  = (uint32_t)&( USART2_Buff[ 1 ] ) ;
        DMA1_Channel6 -> CPAR  = (uint32_t)&( USART2 -> DR ) ;
        DMA1_Channel6 -> CNDTR = 255 ;
        DMA1_Channel6 -> CCR  |= DMA_CCR6_EN ;
        
        DMA1_Channel7 -> CCR |= DMA_CCR7_MINC | DMA_CCR7_DIR |DMA_CCR7_TCIE | DMA_CCR7_PL ;                // DMA ·¢&#203;í
        DMA1_Channel7 -> CMAR = (uint32_t)&( USART2_Buff[ 1 ] ) ;
        DMA1_Channel7 -> CPAR = (uint32_t)&( USART2 -> DR ) ;
        
        NVIC -> IP[ 17 ]   = 0x00 ;                                // DMA ·¢&#203;ííê3é&#214;D&#182;&#207;ê1&#196;ü
        NVIC -> ISER[ 0 ] |= NVIC_ISER_SETENA_17 ;

/* USART2 &#197;&#228;&#214;&#195; */        
        RCC -> APB1ENR |= RCC_APB1ENR_USART2EN ;                                                // USART2 ê±&#214;ó
        RCC -> APB1RSTR |= RCC_APB1RSTR_USART2RST ;                                        // USART2 &#184;′&#206;&#187;
        RCC -> APB1RSTR &= ~RCC_APB1RSTR_USART2RST ;
        
        GPIOA -> CRL  &= 0xFFFF000F ;                                // USART2 &#191;&#216;&#214;&#198;òy&#189;&#197;&#197;&#228;&#214;&#195;£&#172;TX &#197;&#228;&#214;&#195;&#206;a&#184;′ó&#195;10MHZê&#228;3&#246;£&#172;RX&#197;&#228;&#214;&#195;&#206;a&#207;&#194;à-ê&#228;è&#235;
        GPIOA -> CRL  |= 0x00008930 ;
        GPIOA -> BSRR |= GPIO_BSRR_BR3 ;                // RX &#207;&#194;à-
        USART2_RX_ENABLE( ) ;                                                                //&#196;&#172;è&#207;&#196;£ê&#189;&#207;&#194;&#206;a&#189;óê&#213;&#196;£ê&#189;

        USART2 -> BRR  = USART_BoundRateCal( USART2_BOUNDRATE * 2 ) ;                        // 9600 £&#172;8&#206;&#187;êy&#190;Y&#206;&#187;£&#172;&#197;&#188;D£&#209;é£&#172;ò&#187;&#184;&#246;í£&#214;1&#206;&#187;
        USART2 -> CR1 |= USART_CR1_M | USART_CR1_PCE | USART_CR1_RE | USART_CR1_IDLEIE ;
        USART2 -> CR1 |= USART_CR1_UE ;
        USART2 -> CR3 |= USART_CR3_DMAR ;

        NVIC -> IP[ 38 ]   = 0x40 ;
        NVIC -> ISER[ 1 ] |= NVIC_ISER_SETENA_6        ;
        
}

/*===============================================================================*/
//
// USART2 ·¢&#203;í&#198;&#244;&#182;ˉ
//
/*===============================================================================*/
void USART2_StartTX( uint8_t *CL_Pointer )
{
/* DMAí¨μà61&#216;±&#213;£&#172;′ò&#191;aDMAí¨μà7£&#172;2¢3&#245;ê&#188;&#187;ˉ·¢&#203;í×&#214;&#189;ú&#184;&#246;êy */
        DMA1_Channel6 -> CCR  &= ~DMA_CCR6_EN ;
        DMA1_Channel7 -> CNDTR = *CL_Pointer ;
        DMA1_Channel7 -> CMAR  = (uint32_t)( CL_Pointer + 1 ) ;
        DMA1_Channel7 -> CCR  |= DMA_CCR7_EN ;

/* USART2 &#199;D&#187;&#187;μ&#189;·¢&#203;í&#196;£ê&#189;£&#172;1&#216;±&#213; DMA &#189;óê&#213;£&#172;′ò&#191;a DMA ·¢&#203;í */        
        USART2 -> CR3 &= ~USART_CR3_DMAR ;
        USART2 -> CR1 &= ~USART_CR1_RE ;
        USART2 -> CR1 |= USART_CR1_TE ;
        USART2 -> SR  &= ~USART_SR_TC ;
        USART2_TX_ENABLE( ) ;
        USART2 -> CR3 |= USART_CR3_DMAT ;
}

/*===============================================================================*/
//
// USART2 &#191;&#213;&#207;D&#214;&#161;&#214;D&#182;&#207;
//
/*===============================================================================*/
void USART2_IRQHandler( void )
{
/* &#199;&#229;3y IDLE ±ê&#214;&#190;&#206;&#187; */
        USART2 -> SR ;
        USART2 -> DR ;
        
        LED_Ctrl( LED_ID_1 , LED_TURNON ) ;
        
        DMA1_Channel6 -> CCR &= ~DMA_CCR6_EN ;
        
        USART2_Buff[ 0 ] = 255 - DMA1_Channel6 -> CNDTR ;
        ( *USART2_DataProcessing )( USART2_Buff ) ;

        DMA1_Channel6 -> CNDTR = 255 ;
        DMA1_Channel6 -> CMAR  = (uint32_t)&( USART2_Buff[ 1 ] ) ;
        DMA1_Channel6 -> CCR |= DMA_CCR6_EN ;
        
        LED_Ctrl( LED_ID_1 , LED_TURNOFF ) ;
}

/*===============================================================================*/
//
// USART2 DMA·¢&#203;ííê3é&#214;D&#182;&#207;
//
/*===============================================================================*/
void DMA1_Channel7_IRQHandler( void )
{
/* &#199;&#229;3y&#214;D&#182;&#207;±ê&#214;&#190;£&#172;1&#216;±&#213; USART2 DMA·¢&#203;í£&#172;′ò&#191;a DMA &#189;óê&#213;ê1&#196;ü */
        DMA1 -> IFCR |= DMA_IFCR_CGIF7 ;

/* μè′y×&#238;oóò&#187;&#184;&#246;×&#214;&#189;ú·¢&#203;ííê3é */        
        while( !( USART2 -> SR & USART_SR_TXE ) ) ;                                //μè′y×&#238;oóò&#187;&#184;&#246;×&#214;&#189;ú·¢&#203;ííê3é
        
        DMA1_Channel7 -> CCR &= ~DMA_CCR7_EN ;
        DMA1_Channel6 -> CNDTR = 255 ;
        DMA1_Channel6 -> CMAR  = (uint32_t)&( USART2_Buff[ 1 ] ) ;
        DMA1_Channel6 -> CCR |= DMA_CCR6_EN ;
        
        while( !( USART2 -> SR & USART_SR_TC ) ) ;

/* USART2 ·¢&#203;íê1&#196;ü1&#216;±&#213;£&#172;&#189;óê&#213;ê1&#196;ü′ò&#191;a£&#172;1&#216;±&#213; DMA ·¢&#203;íê1&#196;ü£&#172;′ò&#191;a DMA &#189;óê&#213;ê1&#196;ü */        
        USART2 -> SR  &= USART_SR_TC ;
        USART2 -> CR1 &= ~USART_CR1_TE ;
        USART2 -> CR1 |= USART_CR1_RE ;
        USART2 -> CR3 &= ~USART_CR3_DMAT ;
        USART2_RX_ENABLE( ) ;
        USART2 -> CR3 |= USART_CR3_DMAR ;
}
回复

使用道具 举报

2

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
110
金钱
110
注册时间
2018-3-15
在线时间
22 小时
 楼主| 发表于 2018-3-19 13:44:23 | 显示全部楼层
寂青山 发表于 2018-3-15 21:14
帮助不能,不过提供 USART+DMA 驱动代码倒是可以,走MODBUS协议,连接BMCS服务器,跑得正常。
本代码只提 ...

0.0确实不能帮助
回复

使用道具 举报

2

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
110
金钱
110
注册时间
2018-3-15
在线时间
22 小时
 楼主| 发表于 2018-3-19 13:44:35 | 显示全部楼层
寂青山 发表于 2018-3-15 21:14
帮助不能,不过提供 USART+DMA 驱动代码倒是可以,走MODBUS协议,连接BMCS服务器,跑得正常。
本代码只提 ...

但是还是多谢
回复

使用道具 举报

10

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
817
金钱
817
注册时间
2016-2-5
在线时间
163 小时
发表于 2018-4-25 15:42:39 | 显示全部楼层
我是用的串口1做DMA接收的。使用的串口空闲中断加DMA,这样接收比较好点
不甘黄土掩枯骨,宁化寒光映碧霄。
回复

使用道具 举报

2

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
110
金钱
110
注册时间
2018-3-15
在线时间
22 小时
 楼主| 发表于 2018-4-25 17:03:44 | 显示全部楼层
夜乄歌 发表于 2018-4-25 15:42
我是用的串口1做DMA接收的。使用的串口空闲中断加DMA,这样接收比较好点

我就是用的空闲中断方式,请问你空闲中断的方式有碰到过我这种情况吗?
回复

使用道具 举报

10

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
817
金钱
817
注册时间
2016-2-5
在线时间
163 小时
发表于 2018-4-25 19:31:12 | 显示全部楼层
Luxs 发表于 2018-4-25 17:03
我就是用的空闲中断方式,请问你空闲中断的方式有碰到过我这种情况吗?

没有啊,...这个我觉得挺简单的。只是看到一个帖子上说的空闲中断看了下手册就出来
不甘黄土掩枯骨,宁化寒光映碧霄。
回复

使用道具 举报

10

主题

71

帖子

0

精华

高级会员

Rank: 4

积分
817
金钱
817
注册时间
2016-2-5
在线时间
163 小时
发表于 2018-4-25 19:34:00 | 显示全部楼层
Luxs 发表于 2018-4-25 17:03
我就是用的空闲中断方式,请问你空闲中断的方式有碰到过我这种情况吗?

然后,我是搞了一个结构体的指令表。等接受完成后,去把指令大小写转换,和指令表对比得到相应的执行号,然后就清除接受数组,去执行执行号对应的代码
不甘黄土掩枯骨,宁化寒光映碧霄。
回复

使用道具 举报

0

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
77
金钱
77
注册时间
2018-4-15
在线时间
18 小时
发表于 2018-4-25 21:28:30 | 显示全部楼层
用DMA接收ADC时用的,解决了数据错位问题,不知道对你是否有用。也就是用时打开,用完关闭
        MYDMA_Enable(DMA1_Channel1);
        while(DMA_GetFlagStatus(DMA1_FLAG_TC1)!=RESET);
        DMA_ClearFlag(DMA1_FLAG_TC1);
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);                       
        ADC_SoftwareStartConvCmd(ADC1, DISABLE);       //用时打开,用完关闭
回复

使用道具 举报

2

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
110
金钱
110
注册时间
2018-3-15
在线时间
22 小时
 楼主| 发表于 2018-4-26 09:30:11 | 显示全部楼层
夜乄歌 发表于 2018-4-25 19:34
然后,我是搞了一个结构体的指令表。等接受完成后,去把指令大小写转换,和指令表对比得到相应的执行号, ...

谢谢,我再去看看
回复

使用道具 举报

2

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
110
金钱
110
注册时间
2018-3-15
在线时间
22 小时
 楼主| 发表于 2018-4-26 09:30:45 | 显示全部楼层
唠叨的汉堡包 发表于 2018-4-25 21:28
用DMA接收ADC时用的,解决了数据错位问题,不知道对你是否有用。也就是用时打开,用完关闭
        MYDMA_Enable( ...

多谢,这个也要试试
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-9 05:38

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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