打印
[STM32F1]

STM32F101 一直进入串口中断,无法进入主循环,头疼了几天了,还没解决。

[复制链接]
4006|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cooblai|  楼主 | 2015-6-18 14:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
板子硬件正常,因为使用USART_IT_IDLE中断时,串口正常工作。但是用到USART_IT_RXNE时,就一直进入中断,导致无法进入main的主循环。 由于没有JLINK或STLINK,无法判断到底是哪个引起的的中断。
下面是关于串口的配置代码:

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

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);      
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE);
       
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_2;                    //USART1_TX  usart2
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_3;      //USART1_RX     usart2
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);



        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
        USART_Cmd(USART1, ENABLE);


it中:
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//如果寄存器中有数据
        {

                USART_ClearITPendingBit(USART1, USART_IT_RXNE);
                i = USART_ReceiveData(USART1);
                USART_SendData(USART1,i);

        }       

沙发
diweo| | 2015-6-18 14:42 | 只看该作者
貌似GPIOA的时钟没开

使用特权

评论回复
板凳
diweo| | 2015-6-18 14:43 | 只看该作者
还有USART的配置代码呢?

使用特权

评论回复
地板
ywlzh| | 2015-6-18 17:59 | 只看该作者
确定这程序能开始?

使用特权

评论回复
5
泰山特曲123| | 2015-6-18 18:14 | 只看该作者
是因为产生溢出中断了,仔细看看手册。在中断函数的最后,读取状态寄存器,然后读取数据寄存器,就可以清除中断了

使用特权

评论回复
6
airwill| | 2015-6-18 18:34 | 只看该作者
支持一下新人
应该借助调试器, 在中断服务里看中断标志相关的寄存器, 就是看 SR 和 CR1, CR3 来对比

使用特权

评论回复
7
mmuuss586| | 2015-6-18 19:17 | 只看该作者
在中断程序加上:将中断寄存器清0的指令;

使用特权

评论回复
8
通宵敲代码| | 2015-6-19 01:07 | 只看该作者
竟然没有J-link,
话说还不到50块钱啊!

使用特权

评论回复
9
张允| | 2015-6-19 10:57 | 只看该作者
实例代码,仅供参考
/*************************************************************
函数名:void USART1_Config(void)
参        数: 无
作        用: 无
说        明:  配置USART1模块
***************************************************************/
void USART1_Config(void)
        {
         USART1_RCC_Config();
         USART1_GPIO_Config();
         USART1_Mode_Config();
         USART1_NVIC_Config();
         USART1_DMA_Configuration();
         USART1_RX_Box=OSMboxCreate((void*)0);                         //初始化串口1接收邮箱为空
}
/*************************************************************
函数名:void USART1_RCC_Config(void)
参        数: 无
作        用: 无
说        明: 配置TXD,RXDIO时钟,以及USART1模块的时钟
***************************************************************/
void USART1_RCC_Config(void)
{
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO,ENABLE);   //IO口时钟在APB2总线上
          RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
}
/*************************************************************
函数名:void USART1_GPIO_Config(void)
参        数: 无
作        用: 无
说        明: 配置USART1关联的TXD(PA9),RXD(PA10)
***************************************************************/
void USART1_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;                                                                                        //IO配置                               
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
               
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
}
/*************************************************************
函数名:void USART1_Mode_Config(void)
参        数: 无
作        用: 无
说        明:配置USART1  工作模式
***************************************************************/
void USART1_Mode_Config(void)
{
        USART_InitTypeDef USART_InitStructure;
        USART_InitStructure.USART_BaudRate=115200;                                                                                 //配置串口属性
        USART_InitStructure.USART_WordLength=USART_WordLength_8b;
        USART_InitStructure.USART_StopBits=USART_StopBits_1;
        USART_InitStructure.USART_Parity=USART_Parity_No;
        USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
        USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
        USART_Init(USART1,&USART_InitStructure);
        USART_Cmd(USART1,ENABLE);
}
/*************************************************************
函数名:void USART1_NVIC_Config(void)
参        数: 无
作        用: 无
说        明: 配置USART的中断入口,中断优先级,并使能USART1接收中断
***************************************************************/
void USART1_NVIC_Config(void)
{
        NVIC_InitTypeDef  NVIC_InitStructure;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);       
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                                                              //配置串口中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority         = UART1_IDLE_PRIO        ;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority                                 = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);  
        USART_ITConfig(USART1,USART_IT_TC,DISABLE);                                                                         //
        USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);                                                                        
        USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);                                                                        //开启空闲接收中断
        USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);                                                                        //使能DMA接收
        USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);                                                                        //使能DMA发送
}
/*************************************************************
函数名: void USART1_DMA_Configuration(void)
参        数: 无
作        用: 无
说        明: 把USART1 配置DMA接收发送方式
***************************************************************/
void USART1_DMA_Configuration(void)
{
        DMA_InitTypeDef DMA_InitStructure;
        /*****************************************************
                                配置发送方式
        ****************************************************/
        DMA_DeInit(DMA1_Channel4);                                                                               
        DMA_InitStructure.DMA_PeripheralBaseAddr         = (u32)(&USART1->DR);
        DMA_InitStructure.DMA_MemoryBaseAddr                 = (uint32_t)USART1_TX_BUF;
        DMA_InitStructure.DMA_DIR                                         = DMA_DIR_PeripheralDST;
        DMA_InitStructure.DMA_BufferSize                         = USART1_MAX_SEND_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(DMA1_Channel4, &DMA_InitStructure);

        /*****************************************************
                                配置接收方式
        ****************************************************/
        DMA_DeInit(DMA1_Channel5);                                                                                                 //DMA1通道5配置     
        DMA_InitStructure.DMA_PeripheralBaseAddr         = (u32)(&USART1->DR);                         //外设地址     
        DMA_InitStructure.DMA_MemoryBaseAddr                 = (uint32_t)USART1_RX_BUF;                                  //内存地址     
        DMA_InitStructure.DMA_DIR                                         = DMA_DIR_PeripheralSRC;                                                  //dma传输方向单向   
        DMA_InitStructure.DMA_BufferSize                         = USART1_MAX_RECV_LEN;                                                  //设置DMA在传输时缓冲区的长度     
        DMA_InitStructure.DMA_PeripheralInc                 = DMA_PeripheralInc_Disable;                  //设置DMA的外设递增模式,一个外设     
        DMA_InitStructure.DMA_MemoryInc                         = DMA_MemoryInc_Enable;                                   //设置DMA的内存递增模式   
        DMA_InitStructure.DMA_PeripheralDataSize         = DMA_PeripheralDataSize_Byte; //外设数据字长      
        DMA_InitStructure.DMA_MemoryDataSize                 = DMA_MemoryDataSize_Byte;                 //内存数据字长   
        DMA_InitStructure.DMA_Mode                                         = DMA_Mode_Normal;                                                         //设置DMA的传输模式   
        DMA_InitStructure.DMA_Priority                                 = DMA_Priority_VeryHigh;                                 //设置DMA的优先级别     
        DMA_InitStructure.DMA_M2M                                         = DMA_M2M_Disable;                                                         //设置DMA的2个memory中的变量互相访问
        DMA_Init(DMA1_Channel5,&DMA_InitStructure);   
        DMA_Cmd(DMA1_Channel5,ENABLE);                                                                                        //使能通道5
}

void USART1_IRQHandler(void)
{         
    if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
    {
        DMA_Cmd(DMA1_Channel5,DISABLE);
                                OSMboxPost(USART1_RX_Box,(void*)1);
        USART1_RX_STA         =         USART1->SR;
        USART1_RX_STA         =         USART1->DR; //清USART_IT_IDLE标志
        USART1_RX_STA         =         USART1_MAX_RECV_LEN - DMA_GetCurrDataCounter(DMA1_Channel5);  //设置传输数据长度                 
        DMA1_Channel5->CNDTR = USART1_MAX_RECV_LEN;//重装填,并让接收地址偏址从0开始
        DMA_Cmd(DMA1_Channel5, ENABLE);//处理完,重开DMA  
    }  
    __nop();
}

使用特权

评论回复
10
FireRiver9| | 2015-6-19 15:43 | 只看该作者
楼上的参考程序不错啊

使用特权

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

本版积分规则

1

主题

8

帖子

1

粉丝