打印

STM32103RC UART4 DMA 发送问题 DMA发送中断只进一次

[复制链接]
5943|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ddk2006|  楼主 | 2012-6-24 14:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用的是STM32103RC ,UART4 DMA发送功能,初始化如下
void DigitalUartInit(void)
{

GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);

   
GPIO_InitStructure.GPIO_Pin = DIGITAL_UART_TX_GPIO;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(DIGITAL_UART_GPIO_PTR, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = DIGITAL_UART_RX_GPIO;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(DIGITAL_UART_GPIO_PTR, &GPIO_InitStructure);


NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

#if 1
DMA_DeInit(DMA2_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&DIGITAL_UART_PTR->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DigitalUartTxBuf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
//DMA_InitStructure.DMA_BufferSize = 12;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel5, &DMA_InitStructure);
//DMA_ITConfig(DMA2_Channel5, DMA_IT_TC, ENABLE);
//DMA_Cmd(DMA2_Channel5, ENABLE);
#endif
DMA_DeInit(DMA2_Channel3);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DIGITAL_UART_PTR+0x00000004;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)DigitalUartRxBuf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = UART_RXBUF_SIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel3, &DMA_InitStructure);
DMA_ITConfig(DMA2_Channel3, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA2_Channel3, 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(DIGITAL_UART_PTR, &USART_InitStructure);
//USART_DMACmd(ZJ_UART_PTR, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
USART_DMACmd(DIGITAL_UART_PTR,  USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE);
USART_Cmd(DIGITAL_UART_PTR, ENABLE);   
DititalMbox = OSMboxCreate((void*)NULL);
DititalUartSendSem = OSSemCreate(1);
  
}

我设想是每次发送的时候,更改buffer的地址和长度,发送请code如下
INT8U err;
DMA_InitTypeDef DMA_InitStructure;
OSSemPend(DititalUartSendSem,0,&err);
DMA_DeInit(DMA2_Channel5);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pBuf;
DMA_InitStructure.DMA_BufferSize = len;
  DMA_Cmd(DMA2_Channel5, ENABLE);
这样的话我发现,只能进一次中断,中断code如下
void DMA2_Channel4_5_IRQHandler(void)
{
OS_CPU_SR  cpu_sr;
OS_ENTER_CRITICAL();  //保存全局中断标志,关总中断/* Tell uC/OS-II that we are starting an ISR*/
    OSIntNesting++;
    OS_EXIT_CRITICAL();   //恢复全局中断标志   
if(DMA_GetITStatus(DMA2_IT_TC5)) //通道5传输完成中断TC 还有传输 过半中断HT 错误中断TE 全局中断GL
    {
  DMA_ClearITPendingBit(DMA2_IT_GL5);    //清除全部中断标志   
  OSSemPost(DititalUartSendSem);
    }
OSIntExit();  //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换     
}

如果把发送code改成
INT8U err;
DMA_InitTypeDef DMA_InitStructure;
OSSemPend(DititalUartSendSem,0,&err);
DMA_DeInit(DMA2_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&DIGITAL_UART_PTR->DR);
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pBuf;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = len;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA2_Channel5, &DMA_InitStructure);
DMA_ITConfig(DMA2_Channel5, DMA_IT_TC, ENABLE);
DMA_Cmd(DMA2_Channel5, ENABLE);
也就是重新初始化DMA2_Channel5,中断就正常,哪位高手是否可以指点一下,谢谢
沙发
lai832| | 2012-6-24 16:10 | 只看该作者

..

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  
----循环
Buffer满后,地址重新开始,要不是BUffer地址会一直一直加下去-----地址溢出

使用特权

评论回复
板凳
ddk2006|  楼主 | 2012-6-27 11:00 | 只看该作者
结贴啦

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

14

帖子

0

粉丝