
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) { // |
{
// 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);
}
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发送完成后产生中断
}
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);
}
}
评分
查看全部评分
非常感谢你的回复。。。原本打算上传工程文件,但是无法添加附件,只能拷贝代码了。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);
}
如下是串口配置函数
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);
}
我刚入行在自学,没人指导。。。对比过网上的参考例程,整了几天还是搞不定。所有只有到论坛来求助了~~~烦请抽空帮忙看看,多谢~~~