OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3577|回复: 11

stm8s103f3串口接收数据串问题

[复制链接]

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
发表于 2017-3-21 17:41:03 | 显示全部楼层 |阅读模式
1金钱
我用stm8s103f3做串口的数据收发,数据发送正常,但是数据接收不管是中断方式还是轮训方式都无法接收数据串,只能收到每次数据串的第一个字节,下面是我的程序:[mw_shl_code=c,true]static volatile char rx;
static volatile bool new_rx = FALSE;
void main(void)
{
  ErrorStatus clk_return_status = ERROR;
  clk_return_status = CLK_ClockSwitchConfig(CLK_SWITCHMODE_MANUAL, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_ENABLE);
  if (clk_return_status == SUCCESS)  //SUCCESS or ERROR
  {
    CLK_HSECmd(ENABLE);
    CLK_HSICmd(DISABLE);
    CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV4);
  }
  
  led_init();
  UART1_Init((u32)460800, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);
  UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);
  UART1_Cmd(ENABLE);
  
  enableInterrupts();
  
  led_on(0);  
  
  while(1)
  {
    if(new_rx)
    {
      new_rx = FALSE;
      UART1_SendData8(rx);
      led_toggle(0);
    }
  }
}

//UART1 RX Interrupt routine.
INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
  new_rx = TRUE;
  UART1_GetITStatus(UART1_IT_OR);
  if(UART1_GetITStatus(UART1_IT_RXNE))
  {
    rx = UART1_ReceiveData8();
  }
}[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

我这里用的是stm8152k4,接收字符串,在发送回来,没问题[mw_shl_code=c,true]u8 receive_data[50]; u8 receive_data_num = 0; //接收字节数,以0x0d,0x0a结束 u8 end_flag = 0; /* 名称:usart_init 功能:初始化串口 输入:无 输出:无 */ void usart_init() { //打开时钟 CLK_PeripheralClockConfig(CLK_Peripheral_USART1,ENABLE); //初始化参数,115200N81 U ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

93

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
317
金钱
317
注册时间
2016-11-1
在线时间
64 小时
发表于 2017-3-21 17:41:04 | 显示全部楼层
本帖最后由 fankai 于 2017-3-22 12:44 编辑

我这里用的是stm8152k4,接收字符串,在发送回来,没问题[mw_shl_code=c,true]u8 receive_data[50];
u8 receive_data_num = 0;        //接收字节数,以0x0d,0x0a结束
u8 end_flag = 0;

/*
名称:usart_init
功能:初始化串口
输入:无
输出:无
*/
void usart_init()
{
        
        //打开时钟
        CLK_PeripheralClockConfig(CLK_Peripheral_USART1,ENABLE);
        //初始化参数,115200N81
        USART_Init(USART1,115200,USART_WordLength_8b,USART_StopBits_1,USART_Parity_No,USART_Mode_Tx|USART_Mode_Rx);
        //使能接收中断
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
        //打开串口
        USART_Cmd(USART1, ENABLE);
        enableInterrupts();
}

//中断配置函数
INTERRUPT_HANDLER(USART1_RX_TIM5_CC_IRQHandler,28)
{
        if(USART_GetITStatus(USART1, USART_IT_RXNE))                         //判断中断标志
        {
                USART_ClearITPendingBit(USART1, USART_IT_RXNE);                //清除标志
                if(0x00 == end_flag)                                                                //没结束
                {
                        if(USART_ReceiveData8(USART1) == 0x0d)
                        {
                                end_flag = 0x0d;                //赋值0x0d        
                        }
                        else
                        {
                                receive_data[receive_data_num] = USART_ReceiveData8(USART1);
                                receive_data_num++;
                        }
                }
                else if(0x0d == end_flag)                //等于0x0d的时候,再检测是否等于0x0a
                {
                        if(USART_ReceiveData8(USART1) == 0x0a)
                        {
                                end_flag = 0x0a;                //赋值0x0a,一串数据接收完毕        
                                receive_data_num = 0;
                        }
                        else
                        {
                                //接收错误
                                  printf("数据接收错误\r\n");
                                end_flag = 0x00;                //重新开始接收
                                receive_data_num = 0;
                        }
                }
        }
}


int putchar(int ch)                 //重新定义
{
        // 将Printf内容发往串口
        USART_SendData8(USART1,(unsigned char) ch);
        while (!USART_GetFlagStatus(USART1,USART_FLAG_TXE));//如果发送未完成, //标志位未置位,则循环等待
        return (ch);
}

void main(void)
{
        delay_init();
//        lowpower_init();
        usart_init();

    while (1)
    {
                if(0x0a == end_flag)
                {
                        end_flag = 0x00;
                        //接收完毕
                        printf("%s\r\n",receive_data);
                        LED_ON;
                        delay_ms(10);
                        LED_OFF;
                        
                }
    }
  
}
[/mw_shl_code]

回复

使用道具 举报

6

主题

93

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
317
金钱
317
注册时间
2016-11-1
在线时间
64 小时
发表于 2017-3-21 19:08:14 | 显示全部楼层
第一、接收中断里面,标志位置位了应该清除标志位,否则下次不能进入,所以只收到了一个字节
第二、要接收字符串,得定义一个数组,依次把所有的字节都存下来,程序里,即使能够接收多个字节了,后面的也会把前面的覆盖,while循环里,每接收一个字节就会发送出去,但在接收多个字节的时候,估计只能发送有限的几个字节,中断优先,直接把前面的值覆盖了
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165186
金钱
165186
注册时间
2010-12-1
在线时间
2106 小时
发表于 2017-3-21 19:15:42 | 显示全部楼层
帮顶
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2017-3-21 19:23:04 | 显示全部楼层
按照手册说的,读SR寄存器和读DR寄存器可以清除相应的标志位,而且如果是因为没有清标志位的话,应该是收到第一个字节后一直就循环进入中断了。然后我用下面这个程序来累计进入rx中断的次数,不管我从串口助手一次性发送
多少个字节的数据,这个rx_it_cnt每次只累加1

[mw_shl_code=c,true]INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)
{
  
  rx_it_cnt++;
  UART1_GetITStatus(UART1_IT_OR);
  rx = UART1_ReceiveData8();
}[/mw_shl_code]
回复

使用道具 举报

6

主题

93

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
317
金钱
317
注册时间
2016-11-1
在线时间
64 小时
发表于 2017-3-21 19:32:48 | 显示全部楼层
本帖最后由 fankai 于 2017-3-21 19:44 编辑
旦丁中号 发表于 2017-3-21 19:23
按照手册说的,读SR寄存器和读DR寄存器可以清除相应的标志位,而且如果是因为没有清标志位的话,应该是收到 ...

只累加1说明什么呢,不管你发多少字节只进入一次中断,后面的就进不去了
加一句  等待  接收寄存器 非空试试,然后再读取数据。。。
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2017-3-22 08:51:10 | 显示全部楼层
fankai 发表于 2017-3-21 19:32
只累加1说明什么呢,不管你发多少字节只进入一次中断,后面的就进不去了
加一句  等待  接收寄存器 非空 ...

也不行额,好郁闷。。你之前有遇到类似的情况么?
回复

使用道具 举报

6

主题

93

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
317
金钱
317
注册时间
2016-11-1
在线时间
64 小时
发表于 2017-3-22 08:57:59 | 显示全部楼层
旦丁中号 发表于 2017-3-22 08:51
也不行额,好郁闷。。你之前有遇到类似的情况么?

别急,我改改程序试试
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2017-3-22 15:19:52 | 显示全部楼层
fankai 发表于 2017-3-22 12:40
我这里用的是stm8152k4,接收字符串,在发送回来,没问题[mw_shl_code=c,true]u8 receive_data[50];
u8 re ...

写了这么多,真是多谢了~
你的stm8152k4?是什么呢?
我感觉我这边可能是因为波特率太高了
回复

使用道具 举报

6

主题

93

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
317
金钱
317
注册时间
2016-11-1
在线时间
64 小时
发表于 2017-3-22 15:36:08 | 显示全部楼层
旦丁中号 发表于 2017-3-22 15:19
写了这么多,真是多谢了~
你的stm8152k4?是什么呢?
我感觉我这边可能是因为波特率太高了

是stm8l152k4,L系列,在原来的基础上改了下,波特率改了之后呢,可以正常了吗
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2017-3-22 16:55:51 | 显示全部楼层
fankai 发表于 2017-3-22 15:36
是stm8l152k4,L系列,在原来的基础上改了下,波特率改了之后呢,可以正常了吗

好的谢谢。我波特率用115200就可以正常工作,用460800就会出现接收溢出错误,它的官方手册还这么说,我按照里面说的设置 fCPU/16 也没啥作用打算再换个芯片跑高点的波特率,真是谢谢你了~
回复

使用道具 举报

6

主题

68

帖子

0

精华

高级会员

Rank: 4

积分
513
金钱
513
注册时间
2016-3-16
在线时间
166 小时
 楼主| 发表于 2017-3-22 16:56:20 | 显示全部楼层
fankai 发表于 2017-3-22 15:36
是stm8l152k4,L系列,在原来的基础上改了下,波特率改了之后呢,可以正常了吗

好的谢谢。我波特率用115200就可以正常工作,用460800就会出现接收溢出错误,它的官方手册还这么说,我按照里面说的设置 fCPU/16 也没啥作用打算再换个芯片跑高点的波特率,真是谢谢你了~
UART.png
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-9-27 20:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表