请教一个有关picc18大数组实际使用的问题,附图片

[复制链接]
6177|21
 楼主| YaphetS 发表于 2013-4-18 20:51 | 显示全部楼层 |阅读模式
本帖最后由 YaphetS 于 2013-4-19 11:10 编辑

编译环境 picc18 v9.8 pro + mplab x  单片机 PIC18F6628
问题描述:定义了一个较大的局部变量数组,64个char在局部函数中执行串口缓冲数组时好像发生了传说中的元素错乱的情况,可能有点说得不清楚具体看代码:
首先是出问题的函数:
  1. u8t dc_ip_addr[4] = {115, 238, 188, 206};
  2. u16t dc_ip_port = 5555;

  3. static u8t GPRS_CIPSTART(UART_RX_FIFO *pUART_FIFO, const u8t uart_port, u16t time_wait)
  4. {

  5.     u8t jmp = 0;
  6.     u8t tcp_buf[64];

  7.     sprintf(tcp_buf, "%s"%d.%d.%d.%d","%d"\r\n","AT+CIPSTART="TCP",",
  8.                      dc_ip_addr[0], dc_ip_addr[1], dc_ip_addr[2], dc_ip_addr[3],
  9.                      dc_ip_port);                           //按格式输出到字符串

  10.     DataFIFO_CLR(pUART_FIFO);//!!!!!!!!!!
  11.    
  12.     UART_PutStr(uart_port, tcp_buf);
  13. }
有段无关的代码没有放出来
再看看其中的一个子函数,因为问题就出在
DataFIFO_CLR(pUART_FIFO);
这个函数里面,该函数用来清空初始化环形数组结构体里面的变量的
  1. void DataFIFO_CLR(UART_RX_FIFO *pUART_FIFO)
  2. {
  3.     u8t i;

  4.     pUART_FIFO->wr_index = 0;
  5.     pUART_FIFO->rd_index = 0;
  6.     pUART_FIFO->count = 0;
  7.     pUART_FIFO->size = UART_RX_FIFO_SIZE;//UART_RX_FIFO_SIZE=128

  8.     for (i = 0; i < UART_RX_FIFO_SIZE; i++)
  9.         pUART_FIFO->FIFO[i] = 0;
  10. }
经过查了好久的资料发现,这边主要用到两个较大的局部变量数组,一个是tcp_buf[64] 一个是结构体里面的FIFO[128]
我有理由怀疑越界了,但是刚刚接触不是很熟悉,而问题就是
我打算通过串口发给从机这样的指令
输出的结果应该是  AT+CIPSTART="TCP","115.238.188.206","5555"

事实却是          AT+CIPSTART="TCP","115.238.188.200005555"
后几位却被程序篡改了,经过单步分析在执行 DataFIFO_CLR(pUART_FIFO);之前tcp_buf数组内的内容都是正确的,执行过初始化之后却不再正确,就变成下面输出的错误的字符,即被篡改的。
后来一直再寻找解决方案
找到两个解决的办法
1 将    DataFIFO_CLR(pUART_FIFO);放到sprintf之前执行  可以输出正确的结果
2 将    tcp_buf声明成全局变量,虽然这样可以解决,但是心底却一点都不踏实,因为还是不明白为什么之前那样不行
希望yewuyi还有其他网友给出一些指导
现在准备实验的其他办法 一是采用malloc动态申请空间 其次准备在声明局部变量tcp_buf之前加上bank0这样的关键字
 楼主| YaphetS 发表于 2013-4-18 21:42 | 显示全部楼层
坐等
@yewuyi
弓长月月鸟 发表于 2013-4-18 22:05 | 显示全部楼层
看了半天,能力有限。同等大侠指点。
yklstudent 发表于 2013-4-18 22:59 | 显示全部楼层
楼主的速度够快的啊 这边就把sprintf的问题给解决了啊
 楼主| YaphetS 发表于 2013-4-18 23:17 | 显示全部楼层
yklstudent 发表于 2013-4-18 22:59
楼主的速度够快的啊 这边就把sprintf的问题给解决了啊

....是的  解决了
yklstudent 发表于 2013-4-19 06:42 | 显示全部楼层
那就把怎么解决的讲讲啊
 楼主| YaphetS 发表于 2013-4-19 08:29 | 显示全部楼层
yklstudent 发表于 2013-4-19 06:42
那就把怎么解决的讲讲啊

原来在mplab下 现在反倒mplab x  你的mikroc 是买的正版的那?》
xg_qing 发表于 2013-4-19 10:05 | 显示全部楼层
有没有栈溢出啊?Sprintf要慎用,栈需求很高。建议用Freertos里的栈优化版本替代。
yewuyi 发表于 2013-4-19 10:31 | 显示全部楼层
1、俺是最讨厌给别人给别人看代码的,实在没有耐心一点一点看。

2、按照BBS的默认规矩,尽量不要指名道姓的指定网友回答问题。

3、此类问题多数都是出在指针使用不当、类型隐形被强制转换、数组元素越界、中断等造成临界代码等造成的。

4、C编译器自带的sprintf等函数库往往都比较大,实验练手写写就算了,如果是实际产品还是尽量自己写这个函数,不然代码量会急剧膨胀。
 楼主| YaphetS 发表于 2013-4-19 11:13 | 显示全部楼层
yewuyi 发表于 2013-4-19 10:31
1、俺是最讨厌给别人给别人看代码的,实在没有耐心一点一点看。

2、按照BBS的默认规矩,尽量不要指名道姓 ...

您好  我也不想给别人贴代码 这里只是辅助说明问题 我也不是把工程所有代码贴出来,只贴了关键的部分
忘您谅解
如果你可以仔细看看,
我昨晚找到了第个解决办法 吧缓冲区的宏定义128改成了64 还是可以的
这愈加坚定了我认定的bank0越界的问题
后来试验中我在tcpbuf定义处指定了bank1问题还是一样的
请您不要生气
yklstudent 发表于 2013-4-19 12:20 | 显示全部楼层
YaphetS 发表于 2013-4-19 08:29
原来在mplab下 现在反倒mplab x  你的mikroc 是买的正版的那?》

不是 用的试用版
yewuyi 发表于 2013-4-19 14:33 | 显示全部楼层
1、如果怀疑是BANK越界,你自己软仿真看一下过程中变量的位置变化不就知道了吗?
2、和生气无关,只是告诉你BBS一些通常的习惯。
 楼主| YaphetS 发表于 2013-4-19 15:27 | 显示全部楼层
yewuyi 发表于 2013-4-19 14:33
1、如果怀疑是BANK越界,你自己软仿真看一下过程中变量的位置变化不就知道了吗?
2、和生气无关,只是告诉 ...

确定是越界的话 我应该如何修改呢  除了我上面提到的办法
yewuyi 发表于 2013-4-19 17:29 | 显示全部楼层
腾空一个RAM区给它,把别的变量定义到其他RAM区。

我没用过PICC18 V9.8编译器,你可以找找最新版本编译器看看是否支持,原来PICC16也需要手工指定RAM,但最新的好像已经不需要了。
375606426 发表于 2013-4-21 22:39 | 显示全部楼层
 楼主| YaphetS 发表于 2013-4-22 14:32 | 显示全部楼层
我觉得还是没有人提出解决的方法 以及原因的分析
vvip496 发表于 2013-4-22 22:57 | 显示全部楼层
看不出来。。。
huangxz 发表于 2013-4-30 17:23 | 显示全部楼层
YaphetS 发表于 2013-4-22 14:32
我觉得还是没有人提出解决的方法 以及原因的分析

楼主解决问题了没?
在c18里面是可以通过改变优化选项来每次使用内存都选择bank,这样bank就不会出现越界问题了
兰天白云 发表于 2013-5-4 14:59 | 显示全部楼层
在配置文件里把BANK并成一个试试
 楼主| YaphetS 发表于 2013-7-4 09:07 | 显示全部楼层
huangxz 发表于 2013-4-30 17:23
楼主解决问题了没?
在c18里面是可以通过改变优化选项来每次使用内存都选择bank,这样bank就不会出现越界问 ...

在哪里设置 能够截图说明吗
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

21

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部