大家好!
这两天正在使用DMA的功能,主要是和串口1结合在一起使用的,虽然串口和DMA配置完后串口能够通过DMA收发数据,但配置的DMA中断虽然开启了,但始终无法进入中断函数,后来开启串口接收中断
函数倒是可进入中断函数的,所以后来我怀疑是不是启动文件里 中断向量名字有问题,查看了下也没问题。所以觉得纳闷。以下是一些关键的配置程序
首先配置USART1
void usart_init()
{
GPIO_InitTypeDef gpio_typ; //初始化GPIO结构体
USART_InitTypeDef usart_typ;
RCC_APB2PeriphClockCmd(USART1_GPIO_CLK, ENABLE); //RCC_APB2Periph_GPIOA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//RCC_APB2Periph_USART1
//USART1 TX脚配置
gpio_typ.GPIO_Pin = USART1_TxPin;
gpio_typ.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
gpio_typ.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(USART_GPIOA,&gpio_typ);
//USART1 RX脚配置
gpio_typ.GPIO_Pin = USART1_RxPin;
gpio_typ.GPIO_Mode = GPIO_Mode_IN_FLOATING; //复用选浮动输入
GPIO_Init(USART_GPIOA,&gpio_typ);
// USART_DeInit(USART1);
usart_typ.USART_BaudRate = USART_BaudRate0;
usart_typ.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //不设置硬件数据流
usart_typ.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
usart_typ.USART_Parity = USART_Parity_No; // 无校验
usart_typ.USART_StopBits = USART_StopBits_1;
usart_typ.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&usart_typ);
//USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 这样也只能进入串口接收中断函数中
USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
// 使能串口
USART_Cmd(USART1, ENABLE);
NVIC_INIT();
}
然后配置DMA
void dma_urx_init(void)
{
DMA_InitTypeDef dma_typ;
NVIC_InitTypeDef nvic_typ;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //DMA1的AHB外设时钟开启
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
nvic_typ.NVIC_IRQChannel = DMA1_Channel5_IRQn; //中断请求打开
nvic_typ.NVIC_IRQChannelPreemptionPriority = 0;
nvic_typ.NVIC_IRQChannelSubPriority = 0;
nvic_typ.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_typ);
dma_typ.DMA_PeripheralBaseAddr = USART_DR_ADDRESS;//dma 外设地址
dma_typ.DMA_MemoryBaseAddr = (uint32_t)dma_rx_srcbuffer; //dma SRAM地址
dma_typ.DMA_DIR = DMA_DIR_PeripheralSRC; //存储器SRAM作为目标,外设串口作为发射源
dma_typ.DMA_BufferSize = dma_urx_size; //数据数量
dma_typ.DMA_PeripheralInc = DMA_PeripheralInc_Disable ; //使能外设地址增量
dma_typ.DMA_MemoryInc = DMA_MemoryInc_Enable; //使能SRAM地址增量
dma_typ.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据宽度 8位
dma_typ.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //SRAM内存数据宽度 8位
dma_typ.DMA_Mode = DMA_Mode_Normal; //正常模式只发送一次
dma_typ.DMA_Priority = DMA_Priority_High;
dma_typ.DMA_M2M = DMA_M2M_Disable; //不使能内存到外设传输
DMA_Init(DMA1_Channel5,&dma_typ);
DMA_ITConfig(DMA1_Channel5, DMA1_FLAG_TC5, ENABLE); // 使能DMA1通道5的发送完成中断
DMA_Cmd(DMA1_Channel5, ENABLE);
}
然后在stm32f10x_it.c文件中写了启动文件里命名的DMA1通道5的中断函数
void USART1_IRQHandler() // 地址 0x0800 0BE4
{
LED_G(OFF);
LED_B(OFF);
LED_R(ON);
USART_ClearFlag(USART1, USART_FLAG_RXNE);
}
void DMA1_Channel4_IRQHandler() //
{
uint8_t i;
i++;
DMA_ClearITPendingBit(DMA1_FLAG_TC4);
}
void DMA1_Channel5_IRQHandler() //地址 0800 0292
{
uint8_t i;
i++;
DMA_ClearITPendingBit(DMA1_FLAG_TC5);
}
又写了2个连续可随时控制触发DMA的函数
void Dma_Uart1_TX()
{
DMA_Cmd(DMA1_Channel4,DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel4,dma_utx_size); //UART1的DMA对应CH4通道
DMA_Cmd(DMA1_Channel4,ENABLE);
}
//==开启DMA串口接收===//
void Dma_Uart1_RX()
{
DMA_Cmd(DMA1_Channel5,DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel5,10); //到时候我串口调试软件发10个数据测试
DMA_ClearITPendingBit(DMA1_FLAG_TC5); // 这样的设置居然无法在DMA发送完成后触发中断函数,但通过仿真发现相关的DMA_ISR里面的中断标志位其实已经挂起说明中断相应了,但却没有进入中断函数中
//DMA_ClearITPendingBit(DMA1_FLAG_HT5); //注释和不注释都试过
//DMA_ClearFlag(DMA1_FLAG_TC5); //注释和不注释都试过
DMA_Cmd(DMA1_Channel5,ENABLE);
}
就这样下载仿真,从串口调试助手里连续发10个数据,然后我看到数组 dma_rx_srcbuffer里面的确是收到了DMA方式传过来的10个数据
但是DMA中断就是没有触发,断点打在void DMA1_Channel5_IRQHandler()里面的函数始终没进去。 然后我使能了串口的接收中断,再测试
但非常遗憾也只能进入void USART1_IRQHandler()的中断函数,void DMA1_Channel5_IRQHandler()中断函数依旧进不去
哪位大神知道原因吗?
|