打印
[STM32F1]

串口中断收发异常

[复制链接]
855|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wenqiangjames|  楼主 | 2015-3-4 15:38 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 wenqiangjames 于 2015-3-4 15:46 编辑

试验内容:串口中断收发,STM32        接收字符,以十进制输出输入的值
问题现象:1、原测试程序波特率115200,串口调试助手发送“1”,回收“49”,此为正确现象
                2、波特率修改为9600,串口调试助手发送“1”,回收却变成“149”,异常了,多了个1
                3、在中断中取出输出的printf,上位机还是能收到“1”
总结问题:STM32接收到数据后,自己返回接收的数据(并不是我所期望的),请大神们帮忙,谢谢!!!


</p><p>//头文件调用
#include "usually.h"
#include "usart.h"

//加入以下代码,支持printf函数,而不需要选择use MicroLIB         
#if 1
#pragma import(__use_no_semihosting)            
//标准库需要的支持函数                 
struct __FILE
{
        int handle;
        /* Whatever you require here. If the only file you are using is */
        /* standard output using printf() for debugging, no file handling */
        /* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;      
//定义_sys_exit()以避免使用半主机模式   
_sys_exit(int x)
{
        x = x;
}
//重定义fputc函数
int fputc(int Data, FILE *f)
{   
        while(!USART_GetFlagStatus(USART1,USART_FLAG_TXE));          //USART_GetFlagStatus:得到发送状态位
                                                                                                      //USART_FLAG_TXE:发送寄存器为空 1:为空;0:忙状态
        USART_SendData(USART1,Data);                                                  //发送一个字符
           
        return Data;                                                                                  //返回一个值
}
#endif

/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: USART1_Send_Byte
** 功能描述: 串口发送一个字符串
** 参数描述:Data 要发送的数据
** 作   者: Dream
** 日   期: 2011年6月20日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void USART1_Send_Byte(uint16_t Data)
{
        while(!USART_GetFlagStatus(USART1,USART_FLAG_TXE));          //USART_GetFlagStatus:得到发送状态位
                                                                                                                  //USART_FLAG_TXE:发送寄存器为空 1:为空;0:忙状态
        USART_SendData(USART1,Data);                                                  //发送一个字符
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: USART1_Send_Byte
** 功能描述: 串口发送一个字符串
** 参数描述:Data 要发送的数据
** 作   者: Dream
** 日   期: 2011年6月20日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
uint8_t USART1_Receive_Byte(void)
{
           while(!(USART_GetFlagStatus(USART1,USART_FLAG_RXNE))); //USART_GetFlagStatus:得到接收状态位
                                                                                               //USART_FLAG_RXNE:接收数据寄存器非空标志位
                                                                                                 //1:忙状态  0:空闲(没收到数据,等待。。。)
        return USART_ReceiveData(USART1);                                           //接收一个字符
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: Usart_Init
** 功能描述: 串口引脚初始化
** 参数描述: 无
** 作   者: Dream
** 日   期: 2011年6月20日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void Init_Usart(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;                                        //定义一个GPIO结构体变量

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);        
                                                                                                                        //使能各个端口时钟,重要!!!

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                                 //配置串口接收端口挂接到9端口
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                           //复用功能输出开漏
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   //配置端口速度为50M
          GPIO_Init(GPIOA, &GPIO_InitStructure);                                           //根据参数初始化GPIOA寄存器        

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //浮空输入(复位状态);                                          
          GPIO_Init(GPIOA, &GPIO_InitStructure);                                           //根据参数初始化GPIOA寄存器        
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: Usart_Configuration
** 功能描述: 串口配置函数
** 参数描述: BaudRate设置波特率
** 作   者: Dream
** 日   期: 2011年6月20日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void Usart_Configuration(uint32_t BaudRate)
{
        USART_InitTypeDef USART_InitStructure;                                                                    //定义一个串口结构体

        USART_InitStructure.USART_BaudRate            =BaudRate ;                                  //波特率115200
        USART_InitStructure.USART_WordLength          = USART_WordLength_8b;         //传输过程中使用8位数据
        USART_InitStructure.USART_StopBits            = USART_StopBits_1;                 //在帧结尾传输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(USART1, &USART_InitStructure);                                                                //根据参数初始化串口寄存器
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);                                                        //使能串口中断接收
        USART_Cmd(USART1, ENABLE);                                                                                             //使能串口外设
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
** 函数名称: USART1_IRQHandler
** 功能描述: 串口中断函数
** 参数描述: 无
** 作   者: Dream
** 日   期: 2011年6月20日
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
void USART1_IRQHandler()
{
        uint8_t ReceiveDate;                                                                //定义一个变量存放接收的数据
        if(!(USART_GetITStatus(USART1,USART_IT_RXNE)));         //读取接收中断标志位USART_IT_RXNE
                                                                                                                //USART_FLAG_RXNE:接收数据寄存器非空标志位
                                                                                                                //1:忙状态  0:空闲(没收到数据,等待。。。)
        {
                USART_ClearITPendingBit(USART1,USART_IT_RXNE);        //清楚中断标志位
                ReceiveDate=USART_ReceiveData(USART1);                        //接收字符存入数组
                printf("%d",(char*)ReceiveDate);                                //以十进制输出输入的值,从这里我们可以看到键盘上所有的键值对应的十进制数
                                                                                                                //比如输入"1"对应的输出49 、 输入"A" 对应的值为65
                printf("\n\rT");                                                                        //换行置顶
        }  
}
/*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
End:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D:-D
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
</p>

沙发
mmuuss586| | 2015-3-4 21:36 | 只看该作者
换个串口调试软件测试下看看;

并用串口监控软件看下;

使用特权

评论回复
板凳
mmuuss586| | 2015-3-4 21:38 | 只看该作者

再用示波器看下;

使用特权

评论回复
地板
wenqiangjames|  楼主 | 2015-3-5 08:48 | 只看该作者
mmuuss586 发表于 2015-3-4 21:36
换个串口调试软件测试下看看;

并用串口监控软件看下;

改Secure CRT也一样来着

使用特权

评论回复
5
复仇之矛| | 2015-3-5 09:13 | 只看该作者
楼主,请教你个问题,如何去设置串口,进而能接收一个字符串,我搞的程序只能接收一个字符,如果是字符串的话,也是第一个字符。

使用特权

评论回复
6
icecut| | 2015-3-5 10:23 | 只看该作者
估计奇偶配置错了.

使用特权

评论回复
7
wenqiangjames|  楼主 | 2015-3-5 12:13 | 只看该作者
icecut 发表于 2015-3-5 10:23
估计奇偶配置错了.

奇偶校验么?我没开这个功能啊
USART_InitStructure.USART_Parity              = USART_Parity_No ;                 //奇偶失能

使用特权

评论回复
8
icecut| | 2015-3-5 22:48 | 只看该作者
跟踪一下代码吧

使用特权

评论回复
9
搞IT的| | 2015-3-7 11:11 | 只看该作者
O(∩_∩)O~ 不错,顶一个!!

使用特权

评论回复
10
wenqiangjames|  楼主 | 2015-3-9 15:56 | 只看该作者
搞IT的 发表于 2015-3-7 11:11
O(∩_∩)O~ 不错,顶一个!!

哥,我这问题还没解决呢:dizzy:,有建议没

使用特权

评论回复
11
mumu3013| | 2015-3-10 15:47 | 只看该作者
在 Usart_Init函数中,RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE); 改为  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO| RCC_APB2Periph_USART1, ENABLE);试试

使用特权

评论回复
12
wenqiangjames|  楼主 | 2015-3-10 16:30 | 只看该作者
mumu3013 发表于 2015-3-10 15:47
在 Usart_Init函数中,RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);  ...

两个效果一样的,好像RCC_APB2Periph_AFIO时钟开不开对USART1的效果没啥影响

使用特权

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

本版积分规则

1

主题

9

帖子

1

粉丝