6845|14

75

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

STC89C52 串口发送XDATA区域数据很奇怪的问题!~ [复制链接]

我用串口发送一个数组,发送函数如下:
void        Uart_Init()   //初始化UART
{
        SCON =0x58;         //选择串口工作方式,打开接收允许
        TMOD|=0x20;         //定时器1工作在方式2,
        TH1  =0xfd;         //实现波特率9600(系统时钟11.0592MHZ)
        TL1=0xfd;
        PCON |= 0x80;       //实现波特率倍增
        TR1  =1;            //启动定时器T1
        ES=1;               //允许串行口中断
        PS=1;               //设计串行口中断优先级
        EA =1;              //单片机中断允许
}
///初始化没有问题。

void UART_SendData(unsigned char *data_buf,unsigned int iCount)//发送程序
{
        bit es;
        iUartSendLen = iCount-1;
        es=ES;
        ES=0;//关闭中断
        for(iSendCounter=0;iSendCounter<=iUartSendLen;iSendCounter++)
        {
                TI=0;
                SBUF = data_buf[iSendCounter];
                while(!TI);
                TI=0;               
        }
        ES=es;
}//这个函数测试也没有问题

void  SendDataToWifi(unsigned char *cCommandPara,unsigned char iLength)
{  
        unsigned char xdata cBuf[300]; //需要发送数据的数组        注意问题就在这行  
        cBuf[0] = 0x01;                // 同步字段31 5f 33 5f 32 33 34
        cBuf[1] = 0x02;           // 控制字段
        cBuf[2]=(iLength+1)>>8;
        cBuf[3]=(iLength+1)&0x00ff;
        cBuf[4]=GetCrc8(&cBuf[1],3);
        memcpy(&cBuf[5],cCommandPara,iLength);
        UART_SendData(cBuf,iLength+12);
}

当我定义下面的这个结构接收串口数据的时候,串口发送出去的内容全部变成了 OX02
        typedef struct Buffer2
        {
                unsigned char  gcATReceData[300];  
                unsigned int   gcATReceCount;
        } Buffer2;
        struct Buffer2  xdata ATReceBuffer[1];//这里也必须把数组定义到XDATA里面

现在问题是:
当我把
unsigned char xdata cBuf[300];
改成
unsigned char cBuf[50];

发送和接收都正常,
但由于一次发送的内容比较多,必须把变量定义到 XDATA空间里面。。
我该怎么解决这个问题?

最新回复

kit
谢谢楼上的大哥,ES的问题我改过来了。。iUartSendLen 由于在其他的地方需要用到这个全局变量,所以在这里赋值了。。你提出的XDATA的问题,我在其他地方还有XDATA的分配空间。我测试过了。确实并不是我之前考虑到的可能。局部变量和全局变量是没有区别的。。我修改了一下SENDBUF[250]就没有问题了。。然而300的时候KEIL没有报错,居然通过了。。 我现在把发送函数改成下面的, unsigned char xdata* cpSendBufPtr; void UART_SendData(unsigned char *data_buf,unsigned int iCount) {         iUartSendLen = iCount-1;         iSendCounter = 0;         SBUF = data_buf[0];         cpSendBufPtr = &data_buf[1]; } 在中断里面再发送余下的。 测试完全没有问题了。。   详情 回复 发表于 2010-4-24 17:34
点赞 关注

回复
举报

72

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
分不够,可以再加!~都快天亮了。。就是卡在这里。。
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
STC可用的xdata空间有多大?你可以再试试定义unsigned char xdata cBuf[50]; 试试效果如何,看发送正常不?

凌晨3点多,呵呵,人人都在睡觉呢,,,,
 
 
 

回复

77

帖子

0

TA的资源

宇宙尘埃

4
 
STC有1280个XDATA。。。我查了一下资料,有可能是void UART_SendData(unsigned char *data_buf,unsigned int iCount)。。这里面声明的unsigned char *data_buf,指向的是 DATA 区域的指针,引用他不能获得XDATA里面的值。。但是我写成这样:
void UART_SendData(unsigned char xdata *data_buf,unsigned int iCount),也还是不行。。真的真的搞不懂。。。有没有高手能碰过类似的问题啊?
 
 
 

回复

84

帖子

0

TA的资源

一粒金砂(初级)

5
 
假如楼主不嫌麻烦,CPU资源充足的话,可以考虑单字节单字节的发送,然后就不需要XDTAT BUF了,直接从unsigned char *cCommandPara 取数据到ram区。
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

6
 
飘过,mark
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

7
 
谢谢,Peasant_Lee大哥。。单字节发送,不是没有想过。。但是做起来的话很麻烦,由于处理的数据是一个自定义的协议,协议已经做好了。。修改起来,几乎等于整个工程重新再做。。我觉得应该可以利用指针来访问,XDATA区域的数据。。但是小弟才疏学浅。。不知道怎么解决这个问题。。两天了。。就是卡着过不了。。
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

8
 
楼主谦虚了,呵呵,我们就是讨论而已。
  你现在用的是数组,其实数组也就是一个指针,传输的时候,也就是传输数组头的地址,当然这众所周知是个指针。问题是,你现在用数组,出问题了,暂时不知道问题在哪,换成指针的话,估计一样,不过楼主可以试试。

   我曾经使用过一个韩国的增强型的51单片机,他的编译器是自做的,曾经出现很多很怪的问题。放在KEIL上是不会出现的。所以,我也想问问,STC也是用keil做编译环境的么?假如不是,到keil编译下,假如通过,下载看看效果。
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

9
 
问题终于解决了。。原来unsigned char xdata cBuf[300];这句话不能在函数里面声明,必须声明为全局变量,我估计可能是在编译的时候,由于有两个XDATA的变量,如果一个是全局变量,一个是局部变量的话,就会导致编译器,自动分配内存的时候出错。。
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

10
 
呵呵,恭喜楼主。这个问题很难看出来,呵呵,看来定义局部变量的时候,特别是占用空间大的数据,要考虑剩余的xdata空间啊,不过也奇怪,编译器连个警告都没有么?这个有点像使用堆栈一样了,使用过程中要小心,时刻注意堆栈是否溢出。
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

11
 
学习了
 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

12
 
引用 8 楼 nhcxc 的回复:
问题终于解决了。。原来unsigned char xdata cBuf[300];这句话不能在函数里面声明,必须声明为全局变量,我估计可能是在编译的时候,由于有两个XDATA的变量,如果一个是全局变量,一个是局部变量的话,就会导致编译器,自动分配内存的时候出错。。

我担心这并非是真正的原因。在函数里声明变量,仅仅是局部变量而已,不会导致什么编译时内存分配错误之类的问题(除非分配太大超出限制)。
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

13
 
  1. void UART_SendData(unsigned char *data_buf,unsigned int iCount)//发送程序
  2. {
  3. bit es;
  4. iUartSendLen = iCount-1;
  5. es=ES;
  6. ES=0;//关闭中断
  7. for(iSendCounter=0;iSendCounter<=iUartSendLen;iSendCounter++)
  8. {
  9. TI=0;
  10. SBUF = data_buf[iSendCounter];
  11. while(!TI);
  12. TI=0;
  13. }
  14. ES=es;
  15. }//这个函数测试也没有问题
复制代码

这个函数中,实现上(并非指功能上)还是稍微有些问题。
1、那个es变量其实没什么用,浪费了。接收前ES=0,接收后ES=1就可以了,不需要保存。
2、在c语言的循环中,往往约定循环变量范围是前闭合后开的半开半闭区间,及[a,b),所以for循环中的iSendCounter变量的范围应该是[0,iCount),即for(iSendCounter=0;iSendCounter 3、关于“长度”变量的命名。一般来说,字符串的长度用length命名,而一般数据的长度用size命名。假设要使用iUartSendLen 这个变量,最好命名为iUartSendSize或nUartSendSize
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

14
 
楼主看一下编译后xdata占用了多少字节。你的程序中,使用xdata类型的只用到这么两处吗?一个unsigned char xdata cBuf[300],一个struct Buffer2 xdata ATReceBuffer[1]。如果是的话,那么编译后xdata的使用应该是这两者之和,也就是602字节。
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

15
 
谢谢楼上的大哥,ES的问题我改过来了。。iUartSendLen 由于在其他的地方需要用到这个全局变量,所以在这里赋值了。。你提出的XDATA的问题,我在其他地方还有XDATA的分配空间。我测试过了。确实并不是我之前考虑到的可能。局部变量和全局变量是没有区别的。。我修改了一下SENDBUF[250]就没有问题了。。然而300的时候KEIL没有报错,居然通过了。。

我现在把发送函数改成下面的,
unsigned char xdata* cpSendBufPtr;

void UART_SendData(unsigned char *data_buf,unsigned int iCount)
{
        iUartSendLen = iCount-1;
        iSendCounter = 0;
        SBUF = data_buf[0];
        cpSendBufPtr = &data_buf[1];
}
在中断里面再发送余下的。

测试完全没有问题了。。
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表