OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2265|回复: 5

UART4的DMA2通道中断进不了,不知道怎么回事?但DMA1通道的中断能进,原子哥求助啊

[复制链接]

1

主题

12

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
391
金钱
391
注册时间
2018-4-13
在线时间
64 小时
发表于 2018-5-11 10:22:46 | 显示全部楼层 |阅读模式
6金钱
u8 SendBuff[2000];
u8 ReceiveBuff[2000];
u16 ReceiveCnt = 0;
u8 dmaover =0;

const u8 TEXT_TO_SEND[]={"ALIENTEK Warship STM32 DMA 串口实验"};       
int main(void)
{         
        u16 i;
        u8 t=0;
        u8 j,mask=0;
        float pro=0;//进度

        delay_init();                     //延时函数初始化          
        NVIC_Configuration();          //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        uart_init(9600);                 //串口初始化为9600
        LED_Init();                             //LED端口初始化
        LCD_Init();                                  //初始化LCD
        KEY_Init();                                //按键初始化       
                        
        MYDMA_Config(DMA2_Channel5,(u32)&UART4->DR,(u32)SendBuff,1900);//DMA2通道5,外设为串口4,存储器为SendBuff,长度1900.   

//        DMA_RX_Config(DMA1_Channel5,(u32)&USART1->DR,(u32)ReceiveBuff,2000);//DMA1通道4,外设为串口1,存储器为SendBuff,长度5168.   
               
        POINT_COLOR=RED;//设置字体为红色
        LCD_ShowString(60,50,200,16,16,"WarShip STM32");       
        LCD_ShowString(60,70,200,16,16,"DMA TEST");       
        LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
        LCD_ShowString(60,110,200,16,16,"2012/9/8");       
        LCD_ShowString(60,130,200,16,16,"KEY0:Start");
        //显示提示信息       
        j=sizeof(TEXT_TO_SEND);          
        for(i=0;i<1900;i++)//填充ASCII字符集数据
    {
                if(t>=j)//加入换行符
                {
                        if(mask)
                        {
                                SendBuff[i]=0x0a;
                                t=0;
                        }else
                        {
                                SendBuff[i]=0x0d;
                                mask++;
                        }       
                }else//复制TEXT_TO_SEND语句
                {
                        mask=0;
                        SendBuff[i]=TEXT_TO_SEND[t];
                        t++;
                }             
    }                 
        POINT_COLOR=BLUE;//设置字体为蓝色          
        i=0;
        while(1)
        {
                t=KEY_Scan(0);
                if(t==KEY_RIGHT)//KEY0按下
                {
//                        ReceiveCnt =0;
                        LCD_ShowString(60,150,200,16,16,"Start Transimit....");
                        LCD_ShowString(60,170,200,16,16,"   %");//显示百分号
                        printf("\r\nDMA DATA:\r\n");
                        USART_DMACmd(UART4,USART_DMAReq_Tx,ENABLE); //使能串口4的DMA发送  
                        MYDMA_Enable(DMA2_Channel5);//开始一次DMA传输!          
                    //等待DMA传输完成,此时我们来做另外一些事,点灯
                    //实际应用中,传输数据期间,可以执行另外的任务

                        while(1)
                    {
//                                if(DMA_GetFlagStatus(DMA1_FLAG_TC4)!=RESET)        //判断通道4传输完成
//                                {
//                                        DMA_ClearFlag(DMA1_FLAG_TC4);//清除通道4传输完成标志
//                                        break;
//                        }
                                if(dmaover)
                                {
                                        dmaover=0;
                                        break;
                        }
                                pro=DMA_GetCurrDataCounter(DMA2_Channel5);//得到当前还剩余多少个数据
                                pro=1-pro/1900;//得到百分比          
                                pro*=100;      //扩大100倍
                                LCD_ShowNum(60,170,pro,3,16);          
                    }                            
                        LCD_ShowNum(60,170,100,3,16);//显示100%          
                        LCD_ShowString(60,150,200,16,16,"Transimit Finished!");//提示传送完成
                }
                i++;
                delay_ms(10);
                if(i==20)
                {
                        LED0=!LED0;//提示系统正在运行       
                        i=0;
                }                  
        }
}


DMA_InitTypeDef DMA_InitStructure;
extern u8 dmaover;

u16 DMA2_MEM_LEN;//保存DMA每次数据传送的长度             
//DMA2的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_CHxMA通道CHx
//cpar:外设地址
//cmar:存储器地址
//cndtr:数据传输量
void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
{
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);        //使能DMA传输
        delay_ms(5);                                //等待DMA时钟稳定
    DMA_DeInit(DMA_CHx);   //将DMA2的通道5寄存器重设为缺省值
        DMA2_MEM_LEN=cndtr;
        DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;  //DMA外设ADC基地址
        DMA_InitStructure.DMA_MemoryBaseAddr = cmar;  //DMA内存基地址
        DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  //数据传输方向,从内存读取发送到外设
        DMA_InitStructure.DMA_BufferSize = cndtr;  //DMA通道的DMA缓存的大小
        DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  //外设地址寄存器不变
        DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  //内存地址寄存器递增
        DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  //外设数据宽度为8位
        DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //存储器数据宽度为8位
        DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  //工作在正常缓存模式
        DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级
        DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  //DMA通道x没有设置为内存到内存传输

        DMA_Init(DMA_CHx, &DMA_InitStructure);  //根据DMA_InitStruct中指定的参数初始化DMA的通道UART4_Tx_DMA_Channel所标识的寄存器

        NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn;       
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;       
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
        NVIC_Init(&NVIC_InitStructure);

        DMA_ITConfig(DMA2_Channel5,DMA_IT_TC,ENABLE);                //使能传输完成中断                

}
//开启一次DMA传输
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
        DMA_Cmd(DMA_CHx, DISABLE );  //关闭USART4 TX DMA2 所指示的通道      
        DMA_SetCurrDataCounter(DMA2_Channel5,DMA2_MEM_LEN);//DMA通道的DMA缓存的大小
        DMA_Cmd(DMA_CHx, ENABLE);  //使能USART1 TX DMA1 所指示的通道
}          

void DMA2_Channel4_5_IRQHandler(void)
{
        if(DMA_GetFlagStatus(DMA2_FLAG_TC5)!=RESET)        //判断通道5传输完成
        {
                DMA_ClearFlag(DMA2_FLAG_TC5);//清除通道5传输完成标志
                dmaover=1;
        }
        LED1=!LED1;
}


//初始化IO 串口4
//bound:波特率
void uart_init(u32 bound){

         RCC_APB2PeriphClockCmd(RCC_APB1Periph_UART4|RCC_APB2Periph_GPIOC, ENABLE);  //使能UART4,GPIOA时钟
         USART_DeInit(UART4);  //复位串口4
          //UART4_TX        PC.10
         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
         GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化PC10
       
         //UART4_RX   PC.11
         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
         GPIO_Init(GPIOC, &GPIO_InitStructure);  //初始化PC11
       
        //Usart1 NVIC 配置
       
         NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级3
         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;          //子优先级3
         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //IRQ通道使能
         NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
       
        //USART 初始化设置
       
         USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
         USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
         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(UART4, &USART_InitStructure); //初始化串口
         USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//开启中断
         USART_Cmd(UART4, ENABLE);                                          //使能串口
         USART_ClearFlag(UART4, USART_FLAG_TC);         /* 清发送完成标志,Transmission Complete flag */

}



                ; External Interrupts
                DCD     WWDG_IRQHandler            ; Window Watchdog
                DCD     PVD_IRQHandler             ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler          ; Tamper
                DCD     RTC_IRQHandler             ; RTC
                DCD     FLASH_IRQHandler           ; Flash
                DCD     RCC_IRQHandler             ; RCC
                DCD     EXTI0_IRQHandler           ; EXTI Line 0
                DCD     EXTI1_IRQHandler           ; EXTI Line 1
                DCD     EXTI2_IRQHandler           ; EXTI Line 2
                DCD     EXTI3_IRQHandler           ; EXTI Line 3
                DCD     EXTI4_IRQHandler           ; EXTI Line 4
                DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1
                DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2
                DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3
                DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4
                DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5
                DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6
                DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7
                DCD     ADC1_2_IRQHandler          ; ADC1 & ADC2
                DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TX
                DCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0
                DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1
                DCD     CAN1_SCE_IRQHandler        ; CAN1 SCE
                DCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5
                DCD     TIM1_BRK_IRQHandler        ; TIM1 Break
                DCD     TIM1_UP_IRQHandler         ; TIM1 Update
                DCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and Commutation
                DCD     TIM1_CC_IRQHandler         ; TIM1 Capture Compare
                DCD     TIM2_IRQHandler            ; TIM2
                DCD     TIM3_IRQHandler            ; TIM3
                DCD     TIM4_IRQHandler            ; TIM4
                DCD     I2C1_EV_IRQHandler         ; I2C1 Event
                DCD     I2C1_ER_IRQHandler         ; I2C1 Error
                DCD     I2C2_EV_IRQHandler         ; I2C2 Event
                DCD     I2C2_ER_IRQHandler         ; I2C2 Error
                DCD     SPI1_IRQHandler            ; SPI1
                DCD     SPI2_IRQHandler            ; SPI2
                DCD     USART1_IRQHandler          ; USART1
                DCD     USART2_IRQHandler          ; USART2
                DCD     USART3_IRQHandler          ; USART3
                DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10
                DCD     RTCAlarm_IRQHandler        ; RTC Alarm through EXTI Line
                DCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
                DCD     TIM8_BRK_IRQHandler        ; TIM8 Break
                DCD     TIM8_UP_IRQHandler         ; TIM8 Update
                DCD     TIM8_TRG_COM_IRQHandler    ; TIM8 Trigger and Commutation
                DCD     TIM8_CC_IRQHandler         ; TIM8 Capture Compare
                DCD     ADC3_IRQHandler            ; ADC3
                DCD     FSMC_IRQHandler            ; FSMC
                DCD     SDIO_IRQHandler            ; SDIO
                DCD     TIM5_IRQHandler            ; TIM5
                DCD     SPI3_IRQHandler            ; SPI3
                DCD     UART4_IRQHandler           ; UART4
                DCD     UART5_IRQHandler           ; UART5
                DCD     TIM6_IRQHandler            ; TIM6
                DCD     TIM7_IRQHandler            ; TIM7
                DCD     DMA2_Channel1_IRQHandler   ; DMA2 Channel1
                DCD     DMA2_Channel2_IRQHandler   ; DMA2 Channel2
                DCD     DMA2_Channel3_IRQHandler   ; DMA2 Channel3
                DCD     DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5

最佳答案

查看完整内容[请看2#楼]

谢谢原子哥,问题都解决了,DMA2串口4通道都OK了,配置的顺序不对导致的问题!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

12

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
391
金钱
391
注册时间
2018-4-13
在线时间
64 小时
 楼主| 发表于 2018-5-11 10:22:47 | 显示全部楼层
谢谢原子哥,问题都解决了,DMA2串口4通道都OK了,配置的顺序不对导致的问题!
回复

使用道具 举报

1

主题

12

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
391
金钱
391
注册时间
2018-4-13
在线时间
64 小时
 楼主| 发表于 2018-5-11 10:23:20 | 显示全部楼层
其他的串口的DMA1能进!
回复

使用道具 举报

1

主题

12

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
391
金钱
391
注册时间
2018-4-13
在线时间
64 小时
 楼主| 发表于 2018-5-11 11:44:34 | 显示全部楼层
串口的配置搞错了应该是                    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);        RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);





回复

使用道具 举报

1

主题

12

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
391
金钱
391
注册时间
2018-4-13
在线时间
64 小时
 楼主| 发表于 2018-5-11 11:47:37 | 显示全部楼层
发现有这个问题 串口4的中断配置与 DMA2的通道的中断配置不能共存!要用DMA2通道中断配置,必须把串口4的中断配置关闭,这样才能进入DMA2中断配置!
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2018-5-13 00:37:27 | 显示全部楼层
黎明哥 发表于 2018-5-11 11:47
发现有这个问题 串口4的中断配置与 DMA2的通道的中断配置不能共存!要用DMA2通道中断配置,必须把串口4的中 ...

串口4的接收中断么?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-7 20:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表