原创 TM32实现USART+DMA接收未知长度的数据和发送(三)

2016-1-18 13:50 965 4 4 分类: MCU/ 嵌入式 文集: 单片机编程应用

 

数组定义,含义如题名:
u8 USART1_SEND_DATA;   
u8 USART2_SEND_DATA; 
u8 USART1_RECEIVE_DATA; 
u8 USART2_RECEIVE_DATA; 
u8 USART1_TX_Finish=1;// USART1发送完成标志量
u8 USART2_TX_Finish=1; // USART2发送完成标志量
USART1中断服务函数
void USART1_IRQHandler(void)
{
        u16 DATA_LEN;
        u16 i;
        if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)//如果为空闲总线中断
    {
                DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
                //USART_RX_STA = USART1->SR;//先读SR,然后读DR才能清除
      //USART_RX_STA = USART1->DR;
                DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel5); 
                if(DATA_LEN > 0)
      {                        
                        while(USART1_TX_Finish==0)//等待数据传输完成才下一次
            {
                ;
            }
                        //将数据送DMA存储地址
            for(i=0;i
            {
                USART1_SEND_DATA=USART1_RECEIVE_DATA;
            }
            //USART用DMA传输替代查询方式发送,克服被高优先级中断而产生丢帧现象。
            DMA_Cmd(DMA1_Channel4, DISABLE); //改变datasize前先要禁止通道工作
            DMA1_Channel4->CNDTR=DATA_LEN; //DMA1,传输数据量
            USART1_TX_Finish=0;//DMA传输开始标志量
            DMA_Cmd(DMA1_Channel4, ENABLE);                        
                }
                //DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
                DMA_ClearFlag(DMA1_FLAG_GL5 | DMA1_FLAG_TC5 | DMA1_FLAG_TE5 | DMA1_FLAG_HT5);//清标志
                DMA1_Channel5->CNDTR = 512;//重装填
                DMA_Cmd(DMA1_Channel5, ENABLE);//处理完,重开DMA
                //读SR后读DR清除Idle
                i = USART1->SR;
                i = USART1->DR;
        }
        if(USART_GetITStatus(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//出错
        {
                USART_ClearITPendingBit(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE);
        }
        USART_ClearITPendingBit(USART1, USART_IT_TC);
        USART_ClearITPendingBit(USART1, USART_IT_IDLE);
}
USART2中断服务函数
void USART2_IRQHandler(void)
{
        u16 DATA_LEN;
        u16 i;
        if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET) //如果为空闲总线中断
    {
                DMA_Cmd(DMA1_Channel6, DISABLE);//关闭DMA,防止处理其间有数据
                //USART_RX_STA = USART1->SR;//先读SR,然后读DR才能清除
      //USART_RX_STA = USART1->DR;
                DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel6); 
                if(DATA_LEN > 0)
      {                        
                        while(USART2_TX_Finish==0)//等待数据完成才下一次
            {
                ;
            }
                        //将数据送DMA存储地址
            for(i=0;i
            {
                USART2_SEND_DATA=USART2_RECEIVE_DATA;
            }
            //USART用DMA传输替代查询方式发送,克服被高优先级中断而产生丢帧现象。
            DMA_Cmd(DMA1_Channel7, DISABLE); //改变datasize前先要禁止通道工作
            DMA1_Channel7->CNDTR=DATA_LEN; //DMA1,传输数据量
            USART2_TX_Finish=0;//DMA传输开始标志量
            DMA_Cmd(DMA1_Channel7, ENABLE);                        
                }
                //DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
                DMA_ClearFlag(DMA1_FLAG_GL6 | DMA1_FLAG_TC6 | DMA1_FLAG_TE6 | DMA1_FLAG_HT6);//清标志
                DMA1_Channel6->CNDTR = 512;//重装填
                DMA_Cmd(DMA1_Channel6, ENABLE);//处理完,重开DMA
                //读SR后读DR清除Idle
                i = USART2->SR;
                i = USART2->DR;
        }
        if(USART_GetITStatus(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET)//出错
        {
                USART_ClearITPendingBit(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE);
        }
        USART_ClearITPendingBit(USART2, USART_IT_TC);
        USART_ClearITPendingBit(USART2, USART_IT_IDLE);
}
DMA1_Channel5中断服务函数
void DMA1_Channel5_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_IT_TC5);
DMA_ClearITPendingBit(DMA1_IT_TE5);
DMA_Cmd(DMA1_Channel5, DISABLE);//关闭DMA,防止处理其间有数据
DMA1_Channel5->CNDTR = 580;//重装填
DMA_Cmd(DMA1_Channel5, ENABLE);//处理完,重开DMA
}
DMA1_Channel6中断服务函数
void DMA1_Channel6_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_IT_TC6);
DMA_ClearITPendingBit(DMA1_IT_TE6);
DMA_Cmd(DMA1_Channel6, DISABLE);//关闭DMA,防止处理其间有数据
DMA1_Channel6->CNDTR = 580;//重装填
DMA_Cmd(DMA1_Channel6, ENABLE);//处理完,重开DMA
}
DMA1_Channel4中断服务函数
//USART1使用DMA发数据中断服务程序
void DMA1_Channel4_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_IT_TC4);
DMA_ClearITPendingBit(DMA1_IT_TE4);
DMA_Cmd(DMA1_Channel4, DISABLE);//关闭DMA
USART1_TX_Finish=1;//置DMA传输完成
}
DMA1_Channel7中断服务函数
//USART2使用DMA发数据中断服务程序
void DMA1_Channel7_IRQHandler(void)
{
DMA_ClearITPendingBit(DMA1_IT_TC7);
DMA_ClearITPendingBit(DMA1_IT_TE7);
DMA_Cmd(DMA1_Channel7, DISABLE);//关闭DMA
USART2_TX_Finish=1;//置DMA传输完成
}呵呵,全部完,但是程序在开始启动时会出现自己发几个不知道什么字符,之后一切正常。如有什么问题,请大神指教。个人认为问题不大,因为在工作的时候通过STM32访问后台或者后台访问STM32大量的间隔密的数据时没有出现问题。而如果没有使用DMA,单帧数据发收可以,多帧数据经过USART1转USART2,就收不到从USART2反馈的第二帧数据了。不一定是速度上的问题,可能是我处理顺序的问题,但是不管是巧合,还是瞎撞的,总归解决办法的就是好办法。;i++)<>
;i++)<>

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
4
关闭 站长推荐上一条 /3 下一条