打印
[STM8]

请教和讨论关于STM8L串口接收字符串的问题:数据接收不完整

[复制链接]
11986|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
摩捏|  楼主 | 2015-4-14 17:19 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
先把问题列出来,然后贴代码。
1、从PC机向STM8L152C6发送字符串:123456789abcdefgh(仅仅是举例)
2、STM8L接收到字符后,逐一返回PC机。
3、现象:收到的字符串:123456789ac...h 少了b,或者少了10位以后的某一位。如此循环。
4、PC机定时发送字符串给STM8L。STM8L接收一定时间后,大约是一两百个字符后,串口无反应,并且不再可以通信。
5、暂停ST-link。再打开,单片机发送初始化的一串数据。(是不是说明单片机复位?)

已经排除:
1、PC机和串口线硬件。
2、内部时钟切换了外部晶振,扔存在。
3、不管接收,连续循环发送字符,字符串无问题。
4、收到的字符,不发送出来,直接存到数组,仍是接收不完全。
5、禁止中断,查询方式接收,一样效果。
main()
{
        CLK_HSEConfig(CLK_HSE_ON);
        CLK_SYSCLKSourceSwitchCmd(ENABLE);
        CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_HSE);
          CLK_SYSCLKDivConfig(CLK_SYSCLKDiv_1);
        while (CLK_GetSYSCLKSource() != CLK_SYSCLKSource_HSE);

         usart_init();  

}



void usart_init(void)
{
        //set tx as output
        GPIO_Init(GPIOC,GPIO_Pin_3,GPIO_Mode_Out_PP_High_Fast);
        //set rx as input.
        GPIO_Init(GPIOC,GPIO_Pin_2,GPIO_Mode_In_PU_No_IT);        
          USART_DeInit(USART1);
        USART_Init(USART1, 9600, USART_WordLength_8b, USART_StopBits_1,\
        USART_Parity_No,USART_Mode_Rx|USART_Mode_Tx);
       
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
        USART_ITConfig(USART1, USART_IT_ERR, ENABLE);
       
        USART_Cmd(USART1, ENABLE);
        enableInterrupts();
        printf("Hello world!");
}


INTERRUPT_HANDLER(USART1_RX_IRQHandler,28)
{
unsigned char t=0;
if(USART_GetFlagStatus(USART1, USART_IT_RXNE)!=RESET)
{
t=USART_ReceiveData8(USART1);
putchar(t);
}
return;
沙发
摩捏|  楼主 | 2015-4-14 17:29 | 只看该作者
上面的代码,在main函数里面,最后是有个死循环while(1);

由于拷贝的时候,删除了一些注释,所以也删除了这个死循环。我很少犯一些低级的错误,因为这个串口已经反复看了2天,调试,找办法解决。各位如果有什么意见,欢迎提,在这里谢谢了!

使用特权

评论回复
板凳
摩捏|  楼主 | 2015-4-14 17:32 | 只看该作者
说一下免得误会,main()函数的最后是死循环while(1);这里裁剪贴上来的程序,把这个和注释都删掉了。同时穿上图片。

接收到的数据反传到PC.jpg (161.64 KB )

接收到的数据反传到PC.jpg

使用特权

评论回复
地板
摩捏|  楼主 | 2015-4-14 17:35 | 只看该作者
USART_ITConfig(USART1, USART_IT_ERR, ENABLE);
使能这个的原因,是由于参考了网上的一篇**。同事中断里面也检测了OR标志位,仍然无果。哎。

使用特权

评论回复
5
小班儿| | 2015-4-14 17:44 | 只看该作者
串口中断函数中接收到一个字符就发送出来,这种方式不太好。如果每次只是发送一个字节,这个就没有问题。如果发送的字符串多了就会丢字符。建议在接收完一个完整的字符串后再将字符串发送到PC。

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
摩捏 + 2
6
jiaduo| | 2015-4-14 17:50 | 只看该作者
我也遇到过,,是发送接收函数的问题,必须清空or标志和,还有就是等待fifo空再发送。。问题解决。

使用特权

评论回复
7
jiaduo| | 2015-4-14 17:52 | 只看该作者
#include "BSPSerial.h"
#ifdef BSP_SERIAL_RX_INT
uint8_t SerRxLen = 0;/* SerRxLen should be -1 when read the buf below */
uint8_t SerBuf[SER_BUF_SIZE];
#endif

/* BSP serial interface init 16M sysclock */
void BSPSerialInit(void)
{
        USART_DeInit();
        /* gpio init */
        GPIO_Init(GPIOC,GPIO_Pin_2,GPIO_Mode_In_FL_No_IT);
        GPIO_Init(GPIOC,GPIO_Pin_3,GPIO_Mode_Out_PP_High_Fast);

        /* Enable USART clock */
        CLK_PeripheralClockConfig(CLK_Peripheral_USART, ENABLE);
       
        USART_ClockInit(USART_Clock_Disable,USART_CPOL_Low,USART_CPHA_1Edge,USART_LastBit_Disable);//reamber to disable the USART_CK pin out
        USART_Init(1200,USART_WordLength_8D,USART_StopBits_1,USART_Parity_No,USART_Mode_Rx|USART_Mode_Tx);
        USART_Cmd(ENABLE);
#ifdef BSP_SERIAL_RX_INT
        USART_ITConfig(USART_IT_RXNE,ENABLE);
       
#endif
}
/* BSP Serial send byte */
void BSPSerialPutChar(uint8_t ch)
{
  USART->DR = ch;       
        while(!(USART->SR & (1<<6)));       
}
void BSPSerialPutString(uint8_t *st)
{
        while(*st)
                BSPSerialPutChar(*st++);
}
/* BSP Serial get byte (polling) */
uint8_t BSPSerialGetChar(void)
{
        unsigned char i;
        while(!(USART->SR & (1<<5)));
        i =  USART->DR;
        return i;
}
/* add BSPSerialRxISR to stm8l10x_it.c */

void BSPSerialRxISR(void)
{
        #ifdef BSP_SERIAL_RX_INT
        if(USART->SR & (1<<5))
        {
                SerBuf[0] = USART->DR;
                if(SerRxLen < SER_BUF_SIZE)
                {
                        SerBuf[SerRxLen] = USART->DR;
                        SerRxLen++;
                }               
        }
        #endif
}

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
摩捏 + 2
8
jiaduo| | 2015-4-14 17:53 | 只看该作者
很可能是你putchar的问题。。。我的程序测试过了。没问题

使用特权

评论回复
9
摩捏|  楼主 | 2015-4-14 18:00 | 只看该作者
小班儿 发表于 2015-4-14 17:44
串口中断函数中接收到一个字符就发送出来,这种方式不太好。如果每次只是发送一个字节,这个就没有问题。如 ...

这个办法试过,我将字符串存在数组里面已经发现是错的。

使用特权

评论回复
10
摩捏|  楼主 | 2015-4-14 18:02 | 只看该作者
jiaduo 发表于 2015-4-14 17:50
我也遇到过,,是发送接收函数的问题,必须清空or标志和,还有就是等待fifo空再发送。。问题解决。 ...

jiaduo,谢谢。我尝试过清空OR,借鉴如下面链接的朋友处理办法。仍存在问题。请问,FIFO怎么等待呢?https://bbs.21ic.com/blog-585281-72686.html

使用特权

评论回复
11
摩捏|  楼主 | 2015-4-14 18:04 | 只看该作者
jiaduo 发表于 2015-4-14 17:50
我也遇到过,,是发送接收函数的问题,必须清空or标志和,还有就是等待fifo空再发送。。问题解决。 ...

jiaduo,你好。谢谢你的提示。我借鉴如下**。
https://bbs.21ic.com/blog-585281-72686.html

处理过OR,无果。但是FIFO没用处理过,请问是怎么等待?能不能提示一下?

使用特权

评论回复
12
摩捏|  楼主 | 2015-4-14 18:04 | 只看该作者
小班儿 发表于 2015-4-14 17:44
串口中断函数中接收到一个字符就发送出来,这种方式不太好。如果每次只是发送一个字节,这个就没有问题。如 ...

谢谢“小班儿”提醒!!!

使用特权

评论回复
13
摩捏|  楼主 | 2015-4-14 18:07 | 只看该作者
jiaduo 发表于 2015-4-14 17:53
很可能是你putchar的问题。。。我的程序测试过了。没问题

jiaduo帮我测试过?顶你啊兄弟。你看我的putchar()  !我要疯掉了。

char putchar(char c)
{

        USART_SendData8(USART1,c);
        while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
        USART_ClearFlag(USART1, USART_FLAG_TC);
        return (c);

}

使用特权

评论回复
14
摩捏|  楼主 | 2015-4-14 18:10 | 只看该作者
jiaduo 发表于 2015-4-14 17:52
#include "BSPSerial.h"
#ifdef BSP_SERIAL_RX_INT
uint8_t SerRxLen = 0;/* SerRxLen should be -1 when r ...

我决定晚上回去详细看看你的。:handshake,感谢啊,兄弟!!不知道你的是哪一款型号?

使用特权

评论回复
15
jiaduo| | 2015-4-14 18:14 | 只看该作者
摩捏 发表于 2015-4-14 18:10
我决定晚上回去详细看看你的。,感谢啊,兄弟!!不知道你的是哪一款型号? ...

stm8L101

使用特权

评论回复
16
摩捏|  楼主 | 2015-4-14 18:16 | 只看该作者

谢谢!我晚上决定用STM8S和stm8L152r6试试。真不相信有那么邪门。

使用特权

评论回复
17
jiaduo| | 2015-4-14 18:32 | 只看该作者
搞单片机还是需要注意细节的,,应该是细节问题

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
摩捏 + 2
18
fhguo1990| | 2015-4-14 21:34 | 只看该作者
是发送接收函数的问题,必须清空or标志和,还有就是等待fifo空再发送。。问题解决。

使用特权

评论回复
19
mmuuss586| | 2015-4-14 22:07 | 只看该作者

是不是中断标志位没有及时清啊;

使用特权

评论回复
20
tong168| | 2015-4-15 07:50 | 只看该作者
你的接收中断可能重叠了,中断没退出,下一个中断又来了

使用特权

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

本版积分规则

5

主题

44

帖子

0

粉丝