STM32
直播中

南风一号

9年用户 1048经验值
擅长:EMC/EMI设计
私信 关注
[问答]

STM32F030C8T6串口初始化,卡在中断里面是怎么回事?

void USART2_IRQHandler(void)
{
uint8_t i=0;
if(RESET != USART_GetiTStatus(USART2, USART_IT_IDLE))//接收非空
{

        /* clear IDLE flag */
        rc_tmp=USART2->ISR;
        rc_tmp=USART2->RDR;//软件序列清除IDLE标志位
        USART2->ICR = 1<<3;
        USART2->ICR = 1<<4;
        USART_ClearITPendingBit(USART2,USART_IT_IDLE);

        for(i=0;i<7;i++)
        {
                recive_485buf[i] = rxbuf[i];
        }
        UART_RX_Proc();
        DMA_Cmd(DMA1_Channel5,DISABLE);
        DMA_SetCurrDataCounter(DMA1_Channel5, 10);
        DMA_Cmd(DMA1_Channel5,ENABLE);        

}

if(RESET != USART_GetITStatus(USART2, USART_IT_TXE))//发送完成
{
        USART_ClearITPendingBit(USART2, USART_IT_TXE);
        GPIO_ResetBits(GPIOA,GPIO_Pin_4);

}
}

static void usart_dma_init(void)
{
DMA_InitTypeDef  DMA_InitStructure;
NVIC_InitTypeDef NVIC_Initstrcuture;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//DMA1时钟使能

/* tx */
DMA_DeInit(DMA1_Channel4);
DMA_InitStructure.DMA_PeripheralBaseAddr                 = (uint32_t) (USART2->TDR);                //DMA外设地址
DMA_InitStructure.DMA_MemoryBaseAddr                         = (uint32_t)txbuf;                                                        
DMA_InitStructure.DMA_DIR                                             = DMA_DIR_PeripheralDST;               
DMA_InitStructure.DMA_BufferSize                                 = 0;                                                                //数据传输量
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_High;                                //中等优先级
DMA_Init(DMA1_Channel4,  DMA_InitStructure);
DMA_Cmd(DMA1_Channel4,DISABLE);


/* rx */
DMA_DeInit(DMA1_Channel5);
DMA_InitStructure.DMA_PeripheralBaseAddr                 = (uint32_t) (USART2->RDR);                //DMA外设地址
DMA_InitStructure.DMA_MemoryBaseAddr                         = (uint32_t)rxbuf;                                                
DMA_InitStructure.DMA_DIR                                             = DMA_DIR_PeripheralSRC;               
DMA_InitStructure.DMA_BufferSize                                 = 10;                                                                //数据传输量
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_High;                                //中等优先级
DMA_Init(DMA1_Channel5,  DMA_InitStructure);
DMA_Cmd(DMA1_Channel5,ENABLE);
}





void USART2_Config(void)
{
GPIO_InitTypeDef GPIO_Initstructure;
USART_InitTypeDef USART_Initstructure;
NVIC_InitTypeDef NVIC_Initstrcuture;

//        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE );
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA ,ENABLE );

GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_1);
//TX
GPIO_Initstructure.GPIO_Pin = GPIO_Pin_2;
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Initstructure.GPIO_OType = GPIO_OType_PP;
GPIO_Initstructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, GPIO_Initstructure);
//RX
GPIO_Initstructure.GPIO_Pin = GPIO_Pin_3;
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Initstructure.GPIO_OType = GPIO_OType_PP;
GPIO_Initstructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, GPIO_Initstructure);
//485 set
GPIO_Initstructure.GPIO_Pin = GPIO_Pin_4;
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_Initstructure.GPIO_OType = GPIO_OType_PP;
GPIO_Initstructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, GPIO_Initstructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_4);

USART_Initstructure.USART_BaudRate = 115200;
USART_Initstructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Initstructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Initstructure.USART_Parity = USART_Parity_No;
USART_Initstructure.USART_StopBits = USART_StopBits_1;
USART_Initstructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART2, USART_Initstructure);

NVIC_Initstrcuture.NVIC_IRQChannel = USART2_IRQn;
NVIC_Initstrcuture.NVIC_IRQChannelPriority=3;        
NVIC_Initstrcuture.NVIC_IRQChannelCmd = ENABLE;        
NVIC_Init( NVIC_Initstrcuture);


usart_dma_init();
USART_DMACmd(USART2, USART_DMAReq_Rx | USART_DMAReq_Tx, ENABLE);

USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);//开启空闲中断
USART_ClearITPendingBit(USART2,USART_IT_IDLE);
USART_ClearFlag(USART2, USART_FLAG_IDLE);



USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
USART_ClearITPendingBit(USART2, USART_IT_TXE);
USART_ClearFlag(USART2, USART_IT_TXE);


USART_Cmd(USART2, ENABLE);
}

void USART0_DMAsend(uint8_t Len)
{
GPIO_SetBits(GPIOA,GPIO_Pin_4);
DMA_Cmd(DMA1_Channel4,DISABLE);
DMA_SetCurrDataCounter(DMA1_Channel4, Len);
DMA_Cmd(DMA1_Channel4,ENABLE);
while (RESET == DMA_GetFlagStatus(DMA1_FLAG_TC2)) {}
}

回帖(1)

湛蓝

2024-7-3 16:55:51
首先,我们需要了解STM32F030C8T6的串口初始化和中断处理。从您提供的代码片段来看,您正在尝试在USART2中断处理函数中处理IDLE中断。以下是一些可能的原因和解决方案:

1. 确保您的串口初始化正确:
确保您已经正确初始化了串口,包括波特率、字长、停止位、校验位等参数。您可以使用HAL库或标准外设库进行初始化。

2. 检查中断使能:
确保您已经使能了USART2的IDLE中断。在HAL库中,您可以使用`HAL_UART_Receive_IT()`函数;在标准外设库中,您可以使用`USART_ITConfig()`函数。

3. 检查中断优先级:
确保您的中断优先级设置正确。在STM32中,中断优先级可以通过NVIC配置。确保USART2的中断优先级高于其他可能影响它的中断。

4. 检查中断服务函数的实现:
从您提供的代码片段来看,您在处理IDLE中断时,首先检查了IDLE标志位,然后清除了它。但是,您的代码中存在一些问题:

- `rc_tmp=USART2->ISR;` 这行代码没有实际作用,因为它只是将ISR寄存器的值赋给了一个局部变量,但并没有使用这个变量。
- `rc_tmp=USART2->RDR;` 这行代码尝试读取接收到的数据,但是并没有将其存储在某个地方,也没有进一步处理。

您可以修改您的中断服务函数,如下所示:

```c
void USART2_IRQHandler(void)
{
    if (RESET != USART_GetITStatus(USART2, USART_IT_IDLE))
    {
        /* 清除IDLE标志位 */
        USART2->ICR = USART_ICR_IDLECF;

        /* 读取接收到的数据 */
        uint8_t received_data = USART2->RDR;

        /* 处理接收到的数据 */
        // ...
    }
}
```

5. 检查其他可能的问题:
如果以上步骤都无法解决问题,您可能需要检查其他方面,例如硬件连接、串口线缆等。

总之,确保您的串口初始化正确,中断使能和优先级设置正确,以及中断服务函数实现正确。希望这些建议能帮助您解决问题。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分