STM32 DMA多通道传输怎么将数据直接打印到串口

2019-07-14 16:17发布

废话不说了,直接上代码:
我的思路是这样的:AD采集的值通过DMA方式传输到内存,然后再请求使用DMA方式将数据直接打印到串口!
下面是DMA的配置!!!


u16 ADC_RegularConvertedValueTab[RECEVE_SIZE];
u16 SendBuff[SENDBUFF_SIZE];

void DMA_Configuration(void)            //DMA方式发送
{
    DMA_InitTypeDef DMA_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
        
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    //DMA设置:
    //设置DMA源:内存地址&ADC1数据寄存器地址
    //方向:外设-->内存
    //每次传输位:16bit
    //传输大小DMA_BufferSize=RECEVE_SIZE
    //地址自增模式:外设地址不增,内存地址自增1
    //DMA模式:循环
    //优先级:很高
    DMA_DeInit(DMA1_Channel1);//ADC1的DMA传输通道是通道1
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Base;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_RegularConvertedValueTab;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设作为DMA数据传输的来源
    DMA_InitStructure.DMA_BufferSize = RECEVE_SIZE;//传输大小
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不增加
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址自增1
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    //DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//(DMA传送优先级很高)
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
        
        DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);     //中断方式吧
        //开始一次DMA传输!
        DMA_Cmd(DMA1_Channel1, ENABLE);
        
        
        //DMA设置:
    //设置DMA源:内存地址&串口数据寄存器地址
    //方向:内存-->外设
    //每次传输位:8bit
    //传输大小DMA_BufferSize=SENDBUFF_SIZE
    //地址自增模式:外设地址不增,内存地址自增1
    //DMA模式:一次传输,非循环
    //优先级:中
    DMA_DeInit(DMA1_Channel4);//串口1的DMA传输通道是通道4
    DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_RegularConvertedValueTab;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//外设作为DMA的目的端
    DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;//传输大小
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不增加
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址自增1
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    //DMA_Mode_Normal(只传送一次), DMA_Mode_Circular (不停地传送)
    DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//(DMA传送优先级为中等)
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);
}


主函数简单!!!如下

int main(void)
{
        delay_init(72);
        USART_Configuration();
        Beep_Init();
        ADC1_Configuration();
        DMA_Configuration();
        while (1)  
        {   
                while(Flag_Uart_Send);
                USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
                DMA_SetCurrDataCounter(DMA1_Channel4,RECEVE_SIZE);
                //开始一次DMA传输!
                DMA_Cmd(DMA1_Channel4, ENABLE);
                while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET)
                {
                        beep_on();
                        delay_ms(50);
                        beep_off();
                        delay_ms(50);
}
                Flag_Uart_Send=1;
        }
}

其中DMA通道1采用了中断的方式!!!

extern u8 Flag_Uart_Send;
//串口1DMA方式发送中断  
void DMA1_Channel1_IRQHandler(void)  
{  
        //清除标志位  
    DMA_ClearFlag(DMA1_FLAG_TC1);  
    //关闭DMA  
    DMA_Cmd(DMA1_Channel4,DISABLE);  
    //允许再次发送  
    Flag_Uart_Send = 0;  
}



经过调试发现,逻辑上应该是没有问题的,可是串口打印出来的数据是乱码,求大神指导啊!!!!


还有一个问题就是:DMA传输时外设地址自增这个一直不明白是什么意思!是不是就是多个外设采用DMA方式的时候的通道切换???求大神指导啊111



友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。