打印
[技术问答]

【转载】新唐N76E003+GPRS 串口乱码故障排除手记

[复制链接]
546|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
LM莫|  楼主 | 2020-3-29 15:16 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
设计目的
单片机采用N76E003,GPRS模块采用AIR208,N76E003使用USART0与AIR208通信,使用USART1与另一个设备通信。由于每个设备在服务的唯一性,每个设备编号都应该是唯一的。而GPRS模块的IMEI号正好是唯一的,所以设计思路是读取该IMEI号码并以此作为设备的唯一编号。


使用特权

评论回复
沙发
LM莫|  楼主 | 2020-3-29 15:17 | 只看该作者
读取IMEI号码出现乱码故障
N76E003发送控制指令,读取AIR208的IMEI号码。遂尝试着定位问题。

1、使用串口助手观察,N76E003确实发送了控制命令,且AIR208确实返回了包含MEI号码的返回数据。问题是,单片机无论是单步运行还是全速运行,读取的数据均有丢失。

2、使用串口助手对GPRS模块发送控制命令,成功接收返回数据,无丢失。

3、使用串口助手对单片机发送24字节数据,单片机成功接收数据,无丢失。

可以得出结论:单片机串口可以发送,可以接收。GPRS模块串口可以发送,可以接收。


使用特权

评论回复
板凳
LM莫|  楼主 | 2020-3-29 15:18 | 只看该作者
尝试解决方法怀疑1、单片机参数配置错误

N76E003单片机初始化函数如下,绑定TIM3,尝试绑定TIM1后,问题并未解决。

同时怀疑启用了其他单片机外设造成冲突,所以禁用/注释了除UART0以外的所有其他外设,问题并未解决。

void timer0_init(void)
{
  TMOD = 0XFF;
  TIMER0_MODE1_ENABLE;
  clr_T0M;
  TH0 = (uint8_t)((65535 - 13334) >> 8); //10mS锟斤拷时锟斤拷始值
  TL0 = (uint8_t)((65535 - 13334) & 0xff);
  set_ET0; //enable Timer0 interrupt
  set_TR0; //Timer0 run
}


使用特权

评论回复
地板
LM莫|  楼主 | 2020-3-29 15:19 | 只看该作者
怀疑2、GPRS与N76E003接口电平兼容问题


1、VBAT电平是4.0V>0.7VCC=3.5V,单片机可以成功识别到高电平

2、将VBAT处电压跳线至VCC=5V,问题未排除

3、将GPRS模块发送引脚直连单片机的接收引脚,问题未排除,遂恢复原有连接

4、怀疑三极管损坏,更换Q1 Q2,问题未排除


使用特权

评论回复
5
LM莫|  楼主 | 2020-3-29 15:20 | 只看该作者
怀疑3、电磁兼容 射频干扰问题
1、恢复最初程序,使用示波器,观测单片机TX0 RX0引脚。结果发现,单片机发送引脚TX0存在大量杂波,由于GPRS模块是DTU透传模块,服务器端收到大量乱码。

2、屏蔽单片机发送的询问GPRS模块IMEI号码的指令,乱码消除。

3、服务器通过GPRS模块发送心跳命令给单片机,此时单片机可以正常返回数据。通信过程正常,虽然通过示波器观察TX0 RX0出现了一些杂波,但是不影响整体通信效果。


使用特权

评论回复
6
LM莫|  楼主 | 2020-3-29 15:20 | 只看该作者
暂时处置方法

通过串口发送命令设定设备编号

以上尝试都失败,并未解决乱码的问题;仅有的收获是:单片机不能发送读取GPRS模块IMEI号码的指令,否则就会出错。所以暂时的解决办法是用电脑串口助手一个一个给设备发送控制命令,设置设备的唯一序列号。



使用特权

评论回复
7
LM莫|  楼主 | 2020-3-29 15:23 | 只看该作者
最终解决方法修改串口发送函数

念念不忘,必有回响。问题得不到解决,笔者反复思考问题到底出在哪里。最后**一闪,单片机发送读IMEI号码的指令就乱码了,那是否问题就出在发送函数呢?问题正在这里。

原有的串口发送函数
void usart0_send_buf(char *buf, char len)
{
  u8 i = 0;
  for (i = 0; i < len; i++)
  {
    usart0_send_byte(buf[i]);
  }
}
      更改后的串口发送函数
void usart0_send_buf(char *buf, char len)
{
  while (*buf != '\0')
  {
    usart0_send_byte(*buf);
    buf++;
  }
}



使用特权

评论回复
8
LM莫|  楼主 | 2020-3-29 15:24 | 只看该作者
总结:数组的初始化及其元素个数

1、表面上看,是USART0的发送函数不规范引起的问题。单片机执行跑飞。

2、深层的看,是数组的元素个数问题,如果使用原有的打印函数,只要保证数组边界不溢出,也是可以的。正如下图所示,"rrpc,getimei\r\n",我们认为是14个字节,但是如果数组长度也定义为14或只发生14个字节,就会出问题。编译器提示,这个数组要准备15个字节的存储空间。

3、今后发送串口数据,尽量采用while (*buf != '\0')的发送方式,不得已采用逐个发送的方法时,要注意数据的边界,不要溢出。


使用特权

评论回复
9
734774645| | 2020-3-29 15:27 | 只看该作者
void usart0_send_buf(char *buf, char len)
{
  while (*buf != '\0')
  {
    usart0_send_byte(*buf);
    buf++;
  }
}

这个函数有问题啊。len多余。

使用特权

评论回复
10
734774645| | 2020-3-29 15:28 | 只看该作者
void usart0_send_buf(char *buf)
{
  while (*buf != '\0')
  {
    usart0_send_byte(*buf);
    buf++;
  }
}

一般都是这么写的。

使用特权

评论回复
11
磨砂| | 2020-4-6 15:50 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
12
晓伍| | 2020-4-6 15:51 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
13
八层楼| | 2020-4-6 15:51 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
14
观海| | 2020-4-6 15:51 | 只看该作者
非常感谢楼主分享

使用特权

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

本版积分规则

61

主题

447

帖子

3

粉丝