你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【求助】F103平台USART1 DMA模式发送数据失败,可DMA中断有效

[复制链接]
革命小将 提问时间:2016-11-4 22:02 /
Dear 大侠,小弟刚学习STM32遇到一个问题: STM32F103平台 串口1 DMA模式发送数据失败,但是DMA发送完成中断有效。中断部分的打印函数有得到执行。。。。我搞了几天了,都没搞明白问题出在哪里。请大侠帮忙看看我的代码错在哪里。
求大侠抽空帮忙扫一下代码。。。。多谢多谢


如下是我的代码
main函数部分
#include "stm32f10x.h"
#include "rcc.h"
#include "led.h"
#include "usart1.h"

extern u8 SendBuff[SENDBUFF_SIZE];
u16 i;

int main(void)
{
//
收藏 3 评论15 发布时间:2016-11-4 22:02

举报

15个回答
革命小将 回答时间:2016-11-4 22:04:30
int main(void)
{
//        u16 data = 1234;
SendBuff[0] = 0x11;
SendBuff[1] = 0x22;


        SYS_RCC_CFG();
        LED_GPIO_CFG();                                  //时钟初始化必须在GPIO初始化之前
        USART1_CFG();
        DMA_USART1_CFG();


/*填充将要发送的数据*/
for(i=2;i<SENDBUFF_SIZE;i++)
        {
                SendBuff[i] = 0xff;
        }
/*串口向DMA发出请求*/
//        USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);
        DMA_Cmd (DMA1_Channel4,ENABLE);                                        //使能DMA
//        USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);       
//        DMA_Cmd (DMA1_Channel4,ENABLE);                                        //使能DMA
/*在DMA尚未传送完成时,CPU继续执行main函数中的代码*/

        LED_ON;
/*点亮LED灯,同时DMA在向串口传送数据,当DMA发送完成时,在中断函数中关闭LED灯*/


        while(1);

}
革命小将 回答时间:2016-11-4 22:05:07
DMA配置部分
void DMA_USART1_CFG(void)
{
        DMA_InitTypeDef DMA_InitStructure;

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

        NVIC_CFG();                                   //配置DMA中断

        DMA_DeInit(DMA1_Channel4);   
         
        /*设置DMA源:内存地址&串口数据寄存器地址*/
    DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;          

        /*内存地址(要传输的变量的指针)*/
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32) SendBuff;
       
        /*方向:从内存到外设*/               
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;       
       
        /*传输大小DMA_BufferSize=SENDBUFF_SIZE*/       
    DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;
       
        /*外设地址不增*/            
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
       
        /*内存地址自增*/
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;       
       
        /*外设数据单位*/       
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
       
        /*内存数据单位 8bit*/
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;         
       
        /*DMA模式:一次传输,循环*/
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;         
       
        /*优先级:中*/       
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;  
       
        /*禁止内存到内存的传输        */
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
       
        /*配置DMA1的4通道*/                  
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);

//        DMA_Cmd (DMA1_Channel4,ENABLE);                                        //使能DMA                  
//        USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);       
        DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);  //配置DMA发送完成后产生中断

}
革命小将 回答时间:2016-11-4 22:05:30
中断部分

void DMA1_Channel4_IRQHandler(void)
{       
//判断是否为DMA发送完成中断
   if(DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET)
   {  
   //LED关闭  

//                LED_OFF;
        printf("\r\n this is a demo \r\n");       
        printf("The value is %d\t",SendBuff[1]);       
        printf("The value is %d\t",SendBuff[80]);
         
        DMA_ClearFlag(DMA1_FLAG_TC4);
        }       
}
笑鸟007 回答时间:2016-11-5 09:28:02
我没有看到串口引脚配置,是不是在USART1_CFG();里面时钟没有打开,或者引脚配置不对?

评分

参与人数 1ST金币 +2 收起 理由
zero99 + 2

查看全部评分

peter001 回答时间:2016-11-6 00:27:14
应该不难,仔细debug一下吧
asssdz-382474 回答时间:2016-11-6 04:45:28
革命小将 回答时间:2016-11-7 14:56:41
笑鸟007 发表于 2016-11-5 09:28
我没有看到串口引脚配置,是不是在USART1_CFG();里面时钟没有打开,或者引脚配置不对? ...

非常感谢你的回复。。。原本打算上传工程文件,但是无法添加附件,只能拷贝代码了。1,串口管脚应该没有配置错误;若错误,中断内的打印函数不可能得到执行。串口工具有接收到中断内的打印输出。

2,时钟使能,我都是在时钟配置函数内完成得。
如下是时钟配置函数
#include "rcc.h"

void SYS_RCC_CFG(void)
{
        RCC_DeInit();
        RCC_HSEConfig(RCC_HSE_ON);
        while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);

        RCC_HCLKConfig(RCC_SYSCLK_Div1);
        RCC_PCLK2Config(RCC_HCLK_Div1);
        RCC_PCLK1Config(RCC_HCLK_Div2);
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
        RCC_PLLCmd(ENABLE);

        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
        while(RCC_GetSYSCLKSource() != 0x08);

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

}

革命小将 回答时间:2016-11-7 14:58:28
笑鸟007 发表于 2016-11-5 09:28
我没有看到串口引脚配置,是不是在USART1_CFG();里面时钟没有打开,或者引脚配置不对? ...

如下是串口配置函数
u8 SendBuff[SENDBUFF_SIZE];

void USART1_CFG(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;
        USART_InitTypeDef        USART_InitStructure;
        USART_ClockInitTypeDef USART_ClockInitStructure;

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

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

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

        USART_InitStructure.USART_BaudRate = 115200;
        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_Init(USART1, &USART_InitStructure);
        USART_Cmd(USART1, ENABLE);

}
革命小将 回答时间:2016-11-7 15:00:02
peter001 发表于 2016-11-6 00:27
应该不难,仔细debug一下吧

我刚入行在自学,没人指导。。。对比过网上的参考例程,整了几天还是搞不定。所有只有到论坛来求助了~~~烦请抽空帮忙看看,多谢~~~
12下一页

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版