OpenEdv-开源电子网

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

stm32f103 串口dma发送出错

[复制链接]

6

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2013-11-3
在线时间
0 小时
发表于 2014-6-12 23:23:09 | 显示全部楼层 |阅读模式
5金钱
参考战舰开发板例程
在这个基础上做了修改
把串口1 dma改为串口2 dma
然后在定时器里面发送
定时器设置为5ms发一次
发现串口1正常工作,
串口2不能正常工作
串口2发送12个数据,调试助手只能收到4个或5个,每包都丢数,断点调试的时候就好了
考虑可能原因是断点时间较长,dma能够将数据搬移完成,
但串口1不用加断点也能正常工作
求大神赐教
怎么解决
谢谢啦

最佳答案

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

[mw_shl_code=c,true]//初始化IO 串口2 //pclk1CLK1时钟频率(Mhz) //bound:波特率 void USART2_Init(u32 pclk1,u32 bound) { RCC->APB2ENR|=1<<2; //使能PORTA口时钟 GPIOA->CRL&=0XFFFF00FF; //IO状态设置 GPIOA->CRL|=0X00008B00; //IO状态设置 RCC->APB1ENR|=1<<17; //使能串口时钟 RCC->APB1RSTR|=1<<17; //复位串口2 RCC->APB1RSTR&=~(1<<17);/ ...
stm32初学中
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-12 23:23:10 | 显示全部楼层
[mw_shl_code=c,true]//初始化IO 串口2 //pclk1CLK1时钟频率(Mhz) //bound:波特率 void USART2_Init(u32 pclk1,u32 bound) { RCC->APB2ENR|=1<<2; //使能PORTA口时钟 GPIOA->CRL&=0XFFFF00FF; //IO状态设置 GPIOA->CRL|=0X00008B00; //IO状态设置 RCC->APB1ENR|=1<<17; //使能串口时钟 RCC->APB1RSTR|=1<<17; //复位串口2 RCC->APB1RSTR&=~(1<<17);//停止复位 //波特率设置 USART2->BRR=(pclk1*1000000)/(bound);// 波特率设置 USART2->CR1|=0X200C; //1位停止,无校验位. USART2->CR3=1<<7; //使能串口2的DMA发送 UART_DMA_Config(DMA1_Channel7,(u32)&USART2->DR,(u32)USART2_TX_BUF);//DMA1通道7,外设为串口2,存储器为USART2_TX_BUF #ifdef USART2_RX_EN //如果使能了接收 //使能接收中断 USART2->CR1|=1<<8; //PE中断使能 USART2->CR1|=1<<5; //接收缓冲区非空中断使能 MY_NVIC_Init(2,3,USART2_IRQn,2);//组2,最低优先级 TIM4_Init(99,7199); //10ms中断 USART2_RX_STA=0; //清零 TIM4_Set(0); //关闭定时器4 #endif } //串口2,printf 函数 //确保一次发送数据不超过USART2_MAX_SEND_LEN字节 void u2_printf(char* fmt,...) { va_list ap; va_start(ap,fmt); vsprintf((char*)USART2_TX_BUF,fmt,ap); va_end(ap); while(DMA1_Channel7->CNDTR!=0); //等待通道7传输完成 UART_DMA_Enable(DMA1_Channel7,strlen((const char*)USART2_TX_BUF)); //通过dma发送出去 }[/mw_shl_code]

我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-12 23:29:52 | 显示全部楼层
你没有同时开串口1和串口2的DMA吧?

可以参考下我们的GSM模块例程,串口2的发送就是用的DMA.没什么问题.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

6

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2013-11-3
在线时间
0 小时
 楼主| 发表于 2014-6-12 23:50:15 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
好的,原子哥,我回去看看
stm32初学中
回复

使用道具 举报

6

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2013-11-3
在线时间
0 小时
 楼主| 发表于 2014-6-13 11:30:17 | 显示全部楼层
 回复【3楼】 crazymachael :
---------------------------------
原子哥,我早上做了实验,参照gsm例程,在使能dma之前查询dma传输完成标志
while(DMA1_Channel7->CNDTR!=0); //等待通道7传输完成  
运行发现程序死在这个while循环里了。
的代码是这样的
[mw_shl_code=c,true] [/mw_shl_code] [mw_shl_code=c,true]void MYDMA_Config_USART2(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr) { RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输 DMA_DeInit(DMA_CHx); //将DMA的通道1寄存器重设为缺省值 DMA1_MEM_LEN_USART2=cndtr; DMA_InitStructure.DMA_PeripheralBaseAddr = cpar; //DMA外设ADC基地址 DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设 DMA_InitStructure.DMA_BufferSize = cndtr; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init(DMA_CHx, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器 } void MYDMA_Enable_USART2(DMA_Channel_TypeDef*DMA_CHx) { DMA_Cmd(DMA_CHx, DISABLE ); //关闭USART2 TX DMA1 所指示的通道 DMA_SetCurrDataCounter(DMA_CHx,DMA1_MEM_LEN_USART2);//DMA通道的DMA缓存的大小 DMA_Cmd(DMA_CHx, ENABLE); //使能USART2 TX DMA1 所指示的通道 } MYDMA_Config_USART2(DMA1_Channel7,(u32)&USART2->DR,(u32)USART2_TX_BUF,12);//DMA1通道7,外设为串口2,存储器为USART2_TX_BUF,长度12 //定时器里面的发送程序是这样的 USART_DMACmd(USART2,USART_DMAReq_Tx,ENABLE); //使能串口1的DMA发送 while(DMA1_Channel7->CNDTR!=0); //等待通道7传输完成 MYDMA_Enable_USART1(DMA1_Channel7);//开始一次DMA传输! [/mw_shl_code]
用同样的代码测试dma1 ,发现dma1如果加了while循环,也会死在while循环里,但是去掉while循环,dma1能够发送数据,且数据正确。
想不明白啊

stm32初学中
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-6-13 23:03:37 | 显示全部楼层
以上代码,摘自蓝牙模块例程,测试无误.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

6

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2013-11-3
在线时间
0 小时
 楼主| 发表于 2014-6-14 10:42:23 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
好的,谢谢原子哥
stm32初学中
回复

使用道具 举报

12

主题

53

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
246
金钱
246
注册时间
2015-1-28
在线时间
50 小时
发表于 2017-12-1 22:57:32 | 显示全部楼层
我也出现了同样的问题,你是怎么解决的?
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-25 20:02

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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