野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11218|回复: 4

【求助】F103 DMA1 USART1发送数组失败

[复制链接]
发表于 2016-11-24 11:12:17 | 显示全部楼层 |阅读模式
本帖最后由 geming21 于 2016-11-24 14:29 编辑

请各位大虾,帮忙看看代码,小弟感激不尽。。。查过资料,搞了两周了,都没有头绪。我是自学,,,,

实验目的:内存定义一个数组SendBuff,通过DMA1 和USART1把数组发送出去。数据发送完成后,在中断函数内点亮LED灯。
硬件平台: stm32f103evt;软件平台:keil4;库版本:3.5
实现现象: 若数组内的5个数都定义为0x12,则无任何输出;若都定义为0x55,则输出UUUUU。另外无论串口是否有输出,LED灯都会被点亮。
附件是我的主函数 和中断函数代码。

最后  感谢各位帮助
这是主函数
  1. #include "stm32f10x.h"
  2. #include <stdio.h>        //下面strlen函数需要此头文件

  3. u8        SendBuff[5]= {0x55,0x55,0x55,0x55,0x55};

  4. //void Delay( u32 nCount);
  5. void SYS_RCC_CFG(void);
  6. void LED_GPIO_CFG(void);
  7. void DMA_USART1_CFG(void);
  8. void USART1_CFG(void);
  9. void NVIC_CFG(void);


  10. int main(void)
  11. {

  12.         SYS_RCC_CFG();
  13. //        Delay(0x2fffe);
  14.         LED_GPIO_CFG();                                  //时钟初始化必须在GPIO初始化之前
  15.         DMA_USART1_CFG();
  16.         NVIC_CFG();
  17.         USART1_CFG();

  18.         printf("\r\n this is a demo \r\n");          //验证串口是否正常

  19. /*串口向DMA发出请求*/
  20.         DMA_Cmd(DMA1_Channel4,ENABLE);                                        //使能DMA
  21.         USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);       

  22. /*在DMA尚未传送完成时,CPU继续执行main函数中的代码*/

  23.         while(1);

  24. }

  25. //void Delay( u32 nCount )
  26. //{
  27. //        for(; nCount!=0; nCount--);
  28. //}

  29. void SYS_RCC_CFG(void)
  30. {
  31.         RCC_DeInit();                                                                                        /*设置时钟系统寄存器为默认值*/
  32.         RCC_HSEConfig(RCC_HSE_ON);                                                                 /*设置HSE为系统时钟源*/
  33.         while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);                  /*等待HSE时钟源准备就绪*/
  34. //        while(RCC_WaitForHSEStartUp() == ERROR);

  35.         RCC_HCLKConfig(RCC_SYSCLK_Div1);
  36.         RCC_PCLK2Config(RCC_HCLK_Div1);
  37.         RCC_PCLK1Config(RCC_HCLK_Div2);
  38.         RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
  39.         RCC_PLLCmd(ENABLE);

  40.         while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
  41.         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  42.         while(RCC_GetSYSCLKSource() != 0x08);

  43.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
  44.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
  45.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);        //使用串口必须使能AFIO时钟

  46. }


  47. void LED_GPIO_CFG(void)
  48. {
  49. //        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

  50.         GPIO_InitTypeDef GPIO_InitStructure;
  51.        
  52.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
  53.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  54.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  55.         GPIO_Init(GPIOB,&GPIO_InitStructure);
  56.        
  57. }

  58. void USART1_CFG(void)
  59. {
  60.         GPIO_InitTypeDef        GPIO_InitStructure;
  61.         USART_InitTypeDef        USART_InitStructure;
  62. //        USART_ClockInitTypeDef USART_ClockInitStructure;

  63.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  64.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  65.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  66.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  67.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  68.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  69. //        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  70.         GPIO_Init(GPIOA, &GPIO_InitStructure);

  71. //        USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
  72. //        USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;//空闲时钟为低电平
  73. //        USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;//时钟第二个边沿进行数据捕获
  74. //        USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;//最后一位数据的时钟脉冲不从SCLK输出
  75. //        USART_ClockInit(USART1, &USART_ClockInitStructure);

  76.         USART_InitStructure.USART_BaudRate = 115200;
  77.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  78.         USART_InitStructure.USART_StopBits = USART_StopBits_1;
  79.         USART_InitStructure.USART_Parity = USART_Parity_No;
  80.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  81.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  82.         USART_Init(USART1, &USART_InitStructure);
  83.         USART_Cmd(USART1, ENABLE);

  84. }

  85. void NVIC_CFG(void)
  86. {
  87.   NVIC_InitTypeDef NVIC_InitStructure;
  88.   
  89.   /* Configure one bit for preemption priority */
  90.   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  91.   
  92.   /* 配置DMA通道4为中断源 */
  93.   NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
  94.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  95.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  96.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  97.   NVIC_Init(&NVIC_InitStructure);
  98. }

  99. void DMA_USART1_CFG(void)
  100. {
  101.         DMA_InitTypeDef DMA_InitStructure;

  102. //        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);        //开启DMA时钟

  103.         DMA_ClearITPendingBit(DMA1_IT_TC4);
  104. //        DMA_Cmd(DMA1_Channel4,DISABLE);                                        //临时添加 禁止DMA


  105.         DMA_DeInit(DMA1_Channel4);   
  106.          
  107.         /*设置DMA源:内存地址&串口数据寄存器地址*/
  108.     DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) (&USART1->DR); //0x40013804;          

  109.         /*内存地址(要传输的变量的指针)*/
  110.     DMA_InitStructure.DMA_MemoryBaseAddr = (u32) SendBuff;
  111.        
  112.         /*方向:从内存到外设*/               
  113.     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;       
  114.        
  115.         /*传输大小DMA_BufferSize=SENDBUFF_SIZE*/       
  116.     DMA_InitStructure.DMA_BufferSize = 5; //SENDBUFF_SIZE;
  117.        
  118.         /*外设地址不增*/            
  119.     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  120.        
  121.         /*内存地址自增*/
  122.     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;       
  123.        
  124.         /*外设数据单位*/       
  125.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  126.        
  127.         /*内存数据单位 8bit*/
  128.     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;         
  129.        
  130.         /*DMA模式:一次传输,循环*/
  131.     DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;         
  132.        
  133.         /*优先级:中*/       
  134.     DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;  
  135.        
  136.         /*禁止内存到内存的传输        */
  137.     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  138.        
  139.         /*配置DMA1的4通道*/                  
  140.     DMA_Init(DMA1_Channel4, &DMA_InitStructure);


  141.         DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);  //配置DMA发送完成后产生中断

  142. }

  143. //加入以下代码,支持printf函数,而不需要选择use MicroLIB          
  144. /***************************START*********************/
  145. #if 1
  146. #pragma import(__use_no_semihosting)            
  147. //标准库需要的支持函数                 
  148. struct __FILE
  149. {
  150.         int handle;
  151.         /* Whatever you require here. If the only file you are using is */
  152.         /* standard output using printf() for debugging, no file handling */
  153.         /* is required. */
  154. };
  155. /* FILE is typedef’ d in stdio.h. */
  156. FILE __stdout;      
  157. //定义_sys_exit()以避免使用半主机模式   
  158. _sys_exit(int x)
  159. {
  160.         x = x;
  161. }
  162. //重定义fputc函数
  163. int fputc(int ch, FILE *f)
  164. {  
  165.         USART_SendData(USART1, (u8) ch);
  166.         USART_ClearFlag(USART1,USART_FLAG_TC);  //[特别注意] 此条代码是防止丢失传输数据的第一个字符
  167.         while( USART_GetFlagStatus(USART1,USART_FLAG_TC)== RESET);       
  168.         return (ch);   
  169. //        USART1->DR = (u8) ch;      
  170. //        while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
  171. //        return ch;
  172. }
  173. #endif

  174. //
复制代码

以下是中断函数部分
  1. void DMA1_Channel4_IRQHandler(void)
  2. {       
  3. //判断是否为DMA发送完成中断
  4. //   if(DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET)
  5.    if(DMA_GetITStatus(DMA1_IT_TC4)==SET)
  6.    {  
  7.    //LED关闭  

  8.                 LED_ON;
  9.         DMA_Cmd(DMA1_Channel4,DISABLE);                                        //临时添加 禁止DMA
  10.        
  11.         DMA_ClearITPendingBit(DMA1_IT_TC4);
  12. //        DMA_ClearFlag(DMA1_FLAG_TC4);
  13.         }       
  14. }
复制代码



回复

使用道具 举报

发表于 2016-11-24 11:27:19 | 显示全部楼层
可以看看我们dma教程配套的例子,就是用串口的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-11-24 11:29:03 | 显示全部楼层
本帖最后由 geming21 于 2016-11-24 14:31 编辑

楼主删除这部分,请跳过不阅读。。。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-11-24 11:33:41 | 显示全部楼层
flyleaf 发表于 2016-11-24 11:27
可以看看我们dma教程配套的例子,就是用串口的

非常感谢你的回复。。。我就是参照《开发实战指南》写的代码。对比过两者,没有观察出差异。而且书籍自带的代码,我下载到开发板内,也是没有输出。
还请,帮忙看看代码。。。多谢多谢
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-11-25 09:53:53 | 显示全部楼层
我这帖子看来是要沉下去了
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-6-26 00:43 , Processed in 0.039945 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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