打印

STM32 USART2接收问题

[复制链接]
10513|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
luenqing|  楼主 | 2013-8-27 19:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
各位大侠指点,问题:STM32F103RB6 ,同时使能USART1,USART2中断接收PC数据,再将接收的数据发送回PC。当用USART1端口接PC UART进行测试,接收发送都是OK的。但是用USART2端口接PC UART进行测试时,只能接收到最后一个字符。USART1和USART2的初始化和中断程序都差不多。
沙发
乌月明星稀| | 2013-8-27 21:19 | 只看该作者
将关键源码贴出来。我用过没有遇到相关问题。

使用特权

评论回复
板凳
乌月明星稀| | 2013-8-27 21:19 | 只看该作者
你查一下你的IO口有没有相应地初始化

使用特权

评论回复
地板
luenqing|  楼主 | 2013-8-28 22:09 | 只看该作者
先谢谢了. IO都有初始化.下面是初始化和中断接收的代码请指正:
//////////////////////////////////////////////////////////////////
#ifdef EN_USART1_RX   //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误          
u8 USART_RX_BUF[64];     //接收缓冲,最大64个字节.
//接收状态
//bit7,接收完成标志
//bit6,接收到0x0d
//bit5~0,接收到的有效字节数目
u8 USART_RX_STA=0;       //接收状态标记          
u8 flag=0;
void USART1_IRQHandler(void)
{
        u8 res;            
        if(USART1->SR&(1<<5))//接收到数据
        {         
                res=USART1->DR;
                if((USART_RX_STA&0x80)==0)//接收未完成
                {
                        if(USART_RX_STA&0x40)//接收到了0x0d
                        {
                                if(res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
                                else USART_RX_STA|=0x80;        //接收完成了
                        }
                        else //还没收到0X0D
                        {       
                                if(res==0x0d)USART_RX_STA|=0x40;
                                else
                                {
                                        USART_RX_BUF[USART_RX_STA&0X3F]=res;
                                        USART_RX_STA++;
                                        if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收          
                                }                 
                        }
                }                                                                                                
        }                                                                                           
}
#endif

#ifdef EN_USART2_RX   //如果使能了接收
u8 USART2_RX_BUF[64];     //接收缓冲,最大64个字节.
u8 USART2_RX_STA=0;       //接收状态标记
u8 flag2=0;
void USART2_IRQHandler(void)
{  
  u8 res2;     
  if(USART2->SR&(1<<5))//接收到数据
  {  
          res2=USART2->DR;
        if((USART2_RX_STA&0x80)==0)//接收未完成
        {
                if(USART2_RX_STA&0x40)//接收到了0x0d
                {
                        if(res2!=0x0a)USART2_RX_STA=0;//接收错误,重新开始
                        else USART2_RX_STA|=0x80;        //接收完成了
                }
                else //还没收到0X0D
                {       
                        if(res2==0x0d)        USART2_RX_STA|=0x40;
                        else
                        {
                                USART2_RX_BUF[USART2_RX_STA&0x3F]=res2;
                                USART2_RX_STA++;
                                if(USART2_RX_STA>63)        USART2_RX_STA=0;//接收数据错误,重新开始接收          
                        }                 
                }
        }
}  
}

#endif
                                                                                 
//初始化IO 串口1
//pclk2:PCLK2时钟频率(72Mhz)
void uart_init(u32 pclk2,u32 bound)
{           
        float temp;
        u16 mantissa;
        u16 fraction;          
        temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
        mantissa=temp;                                 //得到整数部分
        fraction=(temp-mantissa)*16; //得到小数部分         
    mantissa<<=4;
        mantissa+=fraction;
        RCC->APB2ENR|=1<<2;   //使能PORTA口时钟  
        RCC->APB2ENR|=1<<14;  //使能串口时钟
        GPIOA->CRH&=0XFFFFF00F;
        GPIOA->CRH|=0X000008B0;//IO状态设置 IOA9,IOA10
                  
        RCC->APB2RSTR|=1<<14;   //复位串口1
        RCC->APB2RSTR&=~(1<<14);//停止复位                     
        //波特率设置
        USART1->BRR=mantissa; // 波特率设置         
        USART1->CR1|=0X200C;  //1位停止,无校验位.
#ifdef EN_USART1_RX                  //如果使能了接收
        //使能接收中断
        USART1->CR1|=1<<8;    //PE中断使能
        USART1->CR1|=1<<5;    //接收缓冲区非空中断使能                   
        MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级
#endif
}

//初始化IO 串口2
//pclk1:PCLK1时钟频率(36Mhz)
void uart2_init(u32 pclk1,u32 bound)
{   
   float temp;
   u16 mantissa;
   u16 fraction;   
   temp=(float)(pclk1*1000000)/(bound*16);//得到USARTDIV
   mantissa=temp;     //得到整数部分
   fraction=(temp-mantissa)*16; //得到小数部分  
   mantissa<<=4;
   mantissa+=fraction;
   RCC->APB2ENR|=1<<2;   //使能PORTA口时钟  
   RCC->APB1ENR|=1<<17;  //使能串口时钟
   GPIOA->CRL&=0XFFFF00FF;
   GPIOA->CRL|=0X00008B00;//IO状态设置 IOA2,IOA3
   
   RCC->APB1RSTR|=1<<17;   //复位串口1
   RCC->APB1RSTR&=~(1<<17);//停止复位        
   //波特率设置
   USART2->BRR=mantissa; // 波特率设置  
   USART2->CR1|=0X200C;  //1位停止,无校验位.
#ifdef EN_USART2_RX    //如果使能了接收
   //使能接收中断
   USART2->CR1|=1<<8;    //PE中断使能
   USART2->CR1|=1<<5;    //接收缓冲区非空中断使能      
   MY_NVIC_Init(3,3,USART2_IRQChannel,2);//组2,最低优先级
#endif
}

使用特权

评论回复
5
rtgchym| | 2013-8-29 09:12 | 只看该作者
luenqing 发表于 2013-8-28 22:09
先谢谢了. IO都有初始化.下面是初始化和中断接收的代码请指正:
///////////////////////////////////////// ...

串口2的引脚需要重映射吧

使用特权

评论回复
6
luenqing|  楼主 | 2013-8-29 14:24 | 只看该作者
串口2的引脚默认不是IOA2,IOA3吗,还需要重映射吗?
另外我测试过,用串口2向PC发送一串数据都是OK的,现在接收中断那里不知出现什么问题,只收到最后一个数据。

使用特权

评论回复
7
bbstr| | 2013-8-29 14:27 | 只看该作者
FIFO被清掉了,轮询方式有问题没?

使用特权

评论回复
8
乌月明星稀| | 2013-8-29 15:11 | 只看该作者
luenqing 发表于 2013-8-28 22:09
先谢谢了. IO都有初始化.下面是初始化和中断接收的代码请指正:
///////////////////////////////////////// ...

你的通信协议好怪。

使用特权

评论回复
9
luenqing|  楼主 | 2013-8-29 17:34 | 只看该作者
不知道你指的是哪里,能说明白些吗?

使用特权

评论回复
10
luenqing|  楼主 | 2013-8-29 17:36 | 只看该作者
bbstr 发表于 2013-8-29 14:27
FIFO被清掉了,轮询方式有问题没?

接收是放在中断里处理的

使用特权

评论回复
11
rtgchym| | 2013-8-30 09:02 | 只看该作者
luenqing 发表于 2013-8-29 14:24
串口2的引脚默认不是IOA2,IOA3吗,还需要重映射吗?
另外我测试过,用串口2向PC发送一串数据都是OK的,现 ...

嗯,不用重映射,我记错了,重映射就到PD脚了,我用库函数写了没问题呢

使用特权

评论回复
12
hxb20122012| | 2013-8-30 09:18 | 只看该作者
你可以仔细对照你的程序,肯定是你哪个地方有问题。

使用特权

评论回复
13
luenqing|  楼主 | 2013-8-30 09:40 | 只看该作者
hxb20122012 发表于 2013-8-30 09:18
你可以仔细对照你的程序,肯定是你哪个地方有问题。

uart2的初始化和中断接收程序上面有贴出来,我对比了一个,除了与uart1的寄存器不同外,处理过程是一样的。

使用特权

评论回复
14
hxb20122012| | 2013-9-2 09:18 | 只看该作者
现在还是不行吗??

使用特权

评论回复
15
jeffkuang| | 2013-9-2 14:35 | 只看该作者
两个UART都有接232

使用特权

评论回复
16
604603487| | 2013-9-2 15:02 | 只看该作者
USART2_RX_BUF[USART2_RX_STA&0x3F]=res2;
USART2_RX_STA++;
数组里更新的USART2_RX_STA和你的接收状态标记USART2_RX_STA=0为什么一样的,你是接受0X0D和0X0A中的数据,对吧?但是你的标志就会从数组0X40中开始填写,你根本就装不下64个数据的

使用特权

评论回复
17
604603487| | 2013-9-2 15:03 | 只看该作者
个人见解,你再好好分析一下程序吧

使用特权

评论回复
18
604603487| | 2013-9-2 15:09 | 只看该作者
我理解错了
,你是对的

使用特权

评论回复
19
hkcj| | 2013-9-2 19:40 | 只看该作者
会不会是线序的问题   或者是传输波特率太高了

使用特权

评论回复
20
luenqing|  楼主 | 2013-9-3 10:18 | 只看该作者
波特率9600

使用特权

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

本版积分规则

6

主题

39

帖子

0

粉丝