OpenEdv-开源电子网

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

stm32的DMA无法发送,请各位帮忙看看!谢谢!

[复制链接]

11

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2015-3-6
在线时间
1 小时
发表于 2015-3-6 20:55:34 | 显示全部楼层 |阅读模式
5金钱
#include "stm32f10x.h"
/*
开发板:原子mini开发板,f103的

实验内容:
         1、usart通过DMA方式把数据 SendBuff 发送到外设(即usart数据寄存器),发送成功LED状态会取反
2、通过usart把通过DMA接收的数据data=SendBuff发送给串口调试助手
         (程序没有出错,可以下载到板子上使用)

我的问题:不知道我对DMA方式有没有理解错误,
          串口助手收到的数据一直是00,和DMA传输得到的不一样,
 希望各位指点指点,多谢!!!


*/
void Delay_Int(void);
void delay_ms(u16 nms);
void GPIO_int(void);
void usart_init(void);
void DMA_init(void);
u8 SendBuff=6; //DMA要发送的数据
u8 data; //读取DMA发来的数据
DMA_InitTypeDef DMA_InitStructure;
int main(void)
{  
    Delay_Int();
GPIO_int();
usart_init();  
    DMA_init();
while(1)
{
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);//使能DMA功能

/*开启DMA一次传送*/
DMA_Cmd(DMA1_Channel4, DISABLE );  //关闭USART1 TX DMA1 所指示的通道      
    DMA_InitStructure.DMA_BufferSize = sizeof(SendBuff);
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
  DMA_Cmd(DMA1_Channel4, ENABLE);  //使能USART1 TX DMA1 所指示的通道 

while(1)
{  
if(DMA_GetFlagStatus(DMA1_FLAG_TC4) == SET)//等待通道4传输完成
{

DMA_ClearFlag(DMA1_FLAG_TC4);  //清除发送完成标志
GPIOA->ODR^=(1<<8);//LED1状态取反
break; 
}
data=USART1->DR;//读取DMA发来的数据
USART_SendData(USART1, data);//Data: 把数据发送到串口助手
delay_ms(300);
GPIOD->ODR^=(1<<2);//LED2状态取反
}   
}
}
void usart_init(void)  
{   
   USART_InitTypeDef USART_InitStructure;
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 

USART_InitStructure.USART_BaudRate = 9600;
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_Tx | USART_Mode_Rx;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);//使能或者失能USART外设
}
void GPIO_int()

  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA9,USART1_TX
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);   
  //PA10 ,USART1_TX
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure); 

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //LED0-->A.8 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOA, &GPIO_InitStructure);
 GPIO_SetBits(GPIOA,GPIO_Pin_8);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //LED0-->d.2 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOD, &GPIO_InitStructure);
 GPIO_SetBits(GPIOD,GPIO_Pin_2);

void DMA_init()
{
RCC_APB2PeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
delay_ms(2);
DMA_DeInit(DMA1_Channel4); 
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(USART1->DR);//外设地址 
DMA_InitStructure.DMA_MemoryBaseAddr = SendBuff;  //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //外设作为数据目的地
DMA_InitStructure.DMA_BufferSize = sizeof(SendBuff);//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_Medium; //设置DMA通道优先级为高中
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;   //禁止DMA通道设置为内存至内存传输 
DMA_Init(DMA1_Channel4, &DMA_InitStructure);
}
 void Delay_Int()
{
 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//外部时钟,8分频,72/8M 
}
/*ms延时 */
void delay_ms(u16 nms)//nms<=1864
{
  u32 flag;
  u32 num=(u32)nms*9*1000;//72M晶振8分频成为9M
  SysTick->LOAD=num;//重装载值
  SysTick->VAL=0;  //清空计数器
  SysTick->CTRL=1;//开启计数
  do
  {
    flag=SysTick->CTRL;
  }
  while(!(flag&(1<<16))&&(flag&0x01));
  SysTick->CTRL=0;//关闭计数
  SysTick->LOAD=0; // 清空




最佳答案

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

回复【2楼】正点原子: --------------------------------- 谢谢原子哥,我找到问题了,是开始的时钟设置错误了(唉,3天都没发现这个错误),应该把RCC_APB2PeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); 改为RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);这样它的标志位可以是SET了,但是另一个问题,我用DMA发送的数据是 u8 SendBuff=8 到串口数据寄存器,我用 data=(u32)&(USART1->DR);然后 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

11

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2015-3-6
在线时间
1 小时
 楼主| 发表于 2015-3-6 20:55:35 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
谢谢原子哥,我找到问题了,是开始的时钟设置错误了(唉,3天都没发现这个错误),应该把RCC_APB2PeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
改为RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);这样它的标志位可以是SET了,但是另一个问题,我用DMA发送的数据是 u8 SendBuff=8 到串口数据寄存器,我用 data=(u32)&(USART1->DR);然后USART_SendData(USART1,data); 串口助手收到的数是04,换成其他的值也是04,不知道这个是什么问题。
回复

使用道具 举报

11

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2015-3-6
在线时间
1 小时
 楼主| 发表于 2015-3-6 20:55:35 | 显示全部楼层
好吧,忙了一天,终于把所有遇到的问题解决了,就当分享一下吧。数据发送不对的原因是需要定义一个常量入u8 dat【】={0x55}(数组类型的,不知道为什么,必须定义,否则数据发送会出错),然后把dat赋值给SendBuf,就没问题了。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-3-6 22:33:46 | 显示全部楼层
你直接下载我们例程测试,结果如何?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

11

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2015-3-6
在线时间
1 小时
 楼主| 发表于 2015-3-7 10:43:20 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
你们的结果没有问题,和预期结果一样。我的这个程序DMA无法发送,它的标志位无法达到SET状态。不过串口发送数据到串口助手没问题,不过发送的是00,就是说Usart->DR的值没有变。DMA没有发送这样。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-3-7 22:46:31 | 显示全部楼层
回复【5楼】广寒宫:
---------------------------------
谢谢分享
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-25 06:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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