打印
[STM32F1]

【串口USART3中断】串口可中断发送无**常接收

[复制链接]
1674|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
仙人球W|  楼主 | 2016-4-19 08:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
配置如下:
1、USART3寄存器配置
USART_DeInit(USART3);
USART_StructInit(&USART_InitStructure);
USART_Init(USART3,&USART_InitStructure);
USART3->CR1|=0x206c;        //;USART模块使能,允许接收发送,使能USART中断
USART3->BRR=0x1A0A;        //BaudRate 4800

2、引脚配置
//USART3 配置//
// Configure USART3 Tx (PB.10) as alternate function push-pull //
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
//对于发送PIN必须配置成复用输出上拉否则不能正常发送//
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// Configure USART3 Rx (PB.11) as input floating //
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
//对于接收PIN必须配置成浮点输入否则不能正常接收//
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOB, &GPIO_InitStructure);

3、时钟配置
这里我用到很多其它的外设,也注意了管脚默认功能问题IIC这里是没用开启时钟的
#define  GPIO_Remap_JTAG_Disable    0x04000000   
//Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG and AFIO clocks
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1|
                                                           RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|
                                                            RCC_APB2Periph_GPIOD| RCC_APB2Periph_AFIO,ENABLE);         
//启动IO口的复用功能(AFIO),        用于外部中断
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//使能I2C2, SPI2 时钟//
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3|RCC_APB1Periph_TIM2|
RCC_APB1Periph_TIM3|RCC_APB1Periph_TIM4|RCC_APB1Periph_DAC, ENABLE );

4、中断函数如下
可忽略各标志位,现在是发送数据正常(向USART3->DR写数据触发发送中断)。使用上位机串口猎人发送数据,USART3->DR没用接收到数据,无法触发接收终断
void USART3_IRQHandler(void)     
{
        BYTE  RecTemp;
       
        if(USART3->SR&0x40) //发送
           {
                     USART3->SR&=~0x40;
                     if(SCIStartSent)
               {
                       if(SendCounter<SendBuffer[0])
                                  USART3->DR= SendBuffer[SendCounter++];
                       else
                           {
                                   if(!SCIRece)sentIntervalDelay = 3; // 3ms 完成一循通信稍做延时以便SCI有空闲做下次通信,此种情况专属sentkey
                                    SCISentDis;
                                    SendCounter=0;
                                    SCIStartSent=0;
                                }
                     }
           }

         if(USART3->SR&0x20) //接收                //ReceBuffer[]不包含0x01
             {
                      RecTemp=USART3->DR;
                       
                      if(AddrEqual==0)
                      {
                       if(RecTemp==Saddress)
                          {
                               AddrEqual=1;  //被正确询址                               
                               ReceBuffer[1]=Saddress;
                               }
                      }
                     else
               {
                              if(RendCounter<LENGTH)
                                 ReceBuffer[2+RendCounter++]=RecTemp;               
                               
                         if(RendCounter==LENGTH)
                        {
                                 RendCounter=0;  
                                    if(SCIRece)
                              {
                                        SCIRece=0;
                                        sentIntervalDelay=3; // 3ms 完成一循通信稍做延时以便SCI有空闲做下次通信
                               }
                                FinishedRece=1;  //完成一帧数据接收
                                AddrEqual=0;
                                SCIstate.bit.SCISendtoComputer = 1; // CP返回数据接收完成,可在1ms中断中进行数据处理
                       }
                     }
             }
}

5、有没有遇到过类似问题的网友了,谢谢大家讨论帮助!
沙发
仙人球W|  楼主 | 2016-4-19 08:27 | 只看该作者
6、补充我的中断使能设置如下:

void NVIC_Configuration(void)
{
       NVIC_InitTypeDef NVIC_InitStructure;
   
        /* Configure the NVIC Preemption Priority Bits */  
       NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
       
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
        NVIC_Init(&NVIC_InitStructure);       

        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
        NVIC_Init(&NVIC_InitStructure);       
       
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_Init(&NVIC_InitStructure);       

        NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
        NVIC_Init(&NVIC_InitStructure);       

        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;                     
          NVIC_Init(&NVIC_InitStructure);
}

使用特权

评论回复
板凳
sky8023| | 2016-4-21 16:33 | 只看该作者
这是我的USART1配置:收发都可以用的,你修改一下应该可以。
//初始化 USART1 的时钟
static void  USART1_RCC_Configuration(void)
{
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
}

//配置 USART1 的工作模式
static void  USART1_GPIO_Configuration(void)
{
        /*定义 GPIO 初始化结构体*/
        GPIO_InitTypeDef GPIO_InitStructure;
        /*初始化结构体*/
        GPIO_StructInit(&GPIO_InitStructure);
        
        /*配置 USART1 的发送端口*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                 //PD.8
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;        //复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);                         //初始化PD8
        
        /*配置 USART1 的接收端口*/
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);                  //初始化PD9
}

//配置 USART1 的工作参数
static void  USART1_Configuration(u32 bound)
{
        USART_InitTypeDef USART_InitStructure;

        USART_InitStructure.USART_BaudRate = bound;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        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;
        /*配置 USART1 的异步双工串行工作模式*/
        USART_Init(USART1, &USART_InitStructure);
        /*使能 USART1 的接收中断  */
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
        /*使能 USART1 的发送中断*/
        USART_ITConfig(USART1, USART_IT_TC, ENABLE);
        /*使能 USART1*/
        USART_Cmd(USART1, ENABLE);
}

//配置中断优先级函数
static void  USART1_NVIC_Configuration(void)
{
        NVIC_InitTypeDef NVIC_InitStructure;
        /* Enable the USARTx Interrupt */
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}

void USART1_Init(u32 bound)
{
        USART1_RCC_Configuration();
        USART1_GPIO_Configuration();
        USART1_NVIC_Configuration();
        USART1_Configuration(bound);
}

/*-----------------------------------------------------------------------------
  Function:                USART1_IRQHandler                                                                        
                                                                                                         
  Parameter:                                                                                                                                                                                          
                        None                                    
  Returns:                                                                                                
                       None                                                                                      
  Description:                                                                                            
                       USART1 ISR routine.                                    
*-----------------------------------------------------------------------------*/
void USART1_IRQHandler(void){
        u8 Res;
        if (USART_GetITStatus(USART1, USART_IT_TC) != RESET)                 //发送中断
        {
                USART_SendData(USART1, Res);
                USART_ClearFlag(USART1, USART_FLAG_TC);
        }
        }else if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
        {
                USART_ClearFlag(USART1,USART_FLAG_RXNE);             //清空中断标记
                Res = USART1->DR;
        }
}

使用特权

评论回复
地板
仙人球W|  楼主 | 2018-7-6 11:53 | 只看该作者
sky8023 发表于 2016-4-21 16:33
这是我的USART1配置:收发都可以用的,你修改一下应该可以。
//初始化 USART1 的时钟
static void  USART1_ ...

感谢

使用特权

评论回复
5
wakayi| | 2018-7-14 21:22 | 只看该作者
楼主找到问题了没有

使用特权

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

本版积分规则

38

主题

720

帖子

5

粉丝