OpenEdv-开源电子网

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

stm8L gpio 模拟串口接收数据异常

[复制链接]

3

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2015-9-5
在线时间
8 小时
发表于 2017-4-18 10:31:57 | 显示全部楼层 |阅读模式
10金钱
gpio 模拟串口 接收数据异常, 什么原因


发送:12 34 56 78 90
接收:48 D0 58 E0 40


总结的规律, 去掉最高两位,低两位补0

验证如下:

0001 0010  12
0100  1000  48

0011 01000   34
1101 0000    D0

0101  0110   56
0101  1000   58

0111  1000   78
1110  0000   E0

1001 0000   90
0100 0000   40

思路是接收管脚设置为 浮空输入带外部中断, 外部中断处理程序中进行以下操作:
1. 关闭外部中断;
2. 开启定时器; (定时器的采样频率为波特率的4倍,取第2次采样值,  经示波器观测,正常);
3. 开始接受数据

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165186
金钱
165186
注册时间
2010-12-1
在线时间
2106 小时
发表于 2017-4-20 01:09:09 | 显示全部楼层
回复

使用道具 举报

3

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
55
金钱
55
注册时间
2015-9-5
在线时间
8 小时
 楼主| 发表于 2017-4-28 10:03:02 | 显示全部楼层
原因找到了,是stm8 的库文件读管脚电平函数有问题, 读出来的数据并非 1 和 0
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin)  
{  
    return ((BitStatus)(GPIOx->IDR & (uint8_t)GPIO_Pin));  
}  
改成  以下就没有问题
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin)  
{  
      return ((GPIOx->IDR & (uint8_t)GPIO_Pin) ? SET : RESET);  
}  

但是新的问题来了,现在我的模拟串口和PC端通信正常, 和我们的光电模块终端通信的时候,接收的数据有问题, 但是截取报文, pc解析正常,说明还是我的串口解析的问题。
以下是pc 解析的数据(正确的)
FE FE FE 68 10 14 00 00 00 00 00 00 81 09 90 1F 00 00 07 01 00 00 FF CC 16
我的串口解析的数据:
FE FE FE 68 10 14 00 00 00 00 00 00 81 4B 90 FB 1C 00 07 01 00 00 FF 63 B3 FC

我的思路是接收引脚外部中断,进入中断后关闭中断, 延时一段时间, 开启定时器, 依次检测引脚电平, 读完8个数据位后,开始时钟同步,即检测一个下降沿,开始下一个字节的读取。
以下是我的时钟同步部分代码
/*
* 同步串口时钟
*/
unsigned long my_count = 0;

void    sync_clock(void)
{
   BitStatus old_val, new_val;
   disableInterrupts();
   old_val = read_rx_line();
   disableInterrupts();
    while(my_count< 5000)
    {
       new_val = read_rx_line();
      
        //  检测到下降沿,即起始位
        if(old_val == SET && new_val== RESET)
          break;
        old_val = new_val;
        my_count++;
    }
  
    my_count = 0;
    enableInterrupts();
    rx_flag = 0;
    //stop timer
    TIM3->CR1 &= (uint8_t)(~TIM_CR1_CEN);
    TIM3->CR1 &= ~TIM_CR1_CEN;
    TIM3->CNTRH = 0;//timer3_val >> 8;
    TIM3->CNTRL = 5;//timer3_val & 0xff;
    TIM3->CR1 |=  TIM_CR1_CEN;
}

我有以下疑问, 异步通信每一个字节都是相互独立的,每个字节停止位都进行了时钟同步,不存在累积误差,前面的数据正常, 中间的数据突然异常, 初步断定是中断引起的, 但是除了用于产生接收中断的定时器3 以外, 我没有开其他中断啊,降低波特率也不行, 搞了好多天, 求大神们给我支支招啊,万分感谢!!!!
回复

使用道具 举报

58

主题

6289

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11355
金钱
11355
注册时间
2014-4-1
在线时间
1269 小时
发表于 2017-4-28 10:51:00 | 显示全部楼层

思路应当没错。


回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-9-27 06:43

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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