4253|15

66

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

大家帮我看下这代码哪问题?关于字符串接收! [复制链接]

STC的单片机89C52RC
串口调试助手软件做为发送方,ASCII方式送出“888 777 666”格式的字符串(空格分割),问题是接收处理后分离出里面的一段数据用数码管显示只能是第一次发送的数据,我要是在调试助手里更改了数据再发(手动),显示的还是第一次的数据,而且闪烁,除非关电源再开还是重复如此,反正是只能第一次显示正确,大家帮帮忙!


代码如下:
#include
#include
#include
#include
#include
#define uchar unsigned char
#define uint  unsigned int
#define max 15
uchar code table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar stringa[15]={0};//接收缓冲
uchar stringa1[15]={0};
uchar a[20];
uchar i=0;
uint record;
uint numaz;
/********************************************************************
* 名称 : Delay_1ms()
* 功能 : 延时子程序,延时时间为 1ms * x
* 输入 : x (延时一毫秒的个数)
* 输出 : 无
***********************************************************************/
void Delay_1ms(uint i)//1ms延时
{
        uchar x,j;
        for(j=0;j         for(x=0;x<=148;x++);       
}

/********************************************************************
* 名称 : Com_Int()
* 功能 : 串口中断子函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Int(void) interrupt 4
{

         if(RI && i < max)
         {  
       RI = 0;
           stringa[i++]=SBUF;
           record = 1;       //取数标志
     }

}

/********************************************************************
* 名称 : Com_Init()
* 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Com_Init(void)
{
     TMOD = 0x20;
     PCON = 0x00;
     SCON = 0x50;                       
     TH1 = 0xFd;    //设置波特率 9600
     TL1 = 0xFd;
     TR1 = 1;                //启动定时器1
         ES = 1;                //开串口中断
         EA = 1;                //开总中断               
}

/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Main()
{
       
        Com_Init(); //串口初始化
       
        while(1)
        {
               if(record==1)
                        {
                       record = 0;
                        sprintf(stringa1,"%s",stringa);//将stringz附给stringa1,此时格式是888 777 666,不知道对不对
                        sscanf(stringa1,"%*s%s%s",a);//用sscanf函数分离出第一个数据段888,这个应该是字符串吗?不知道这样能不能用
                         numaz=atoi(stringa1); //将字符型的888转换为数值型
                      }
                      P0 = table[numaz/100];  //888的百位数
                      P2 = 0x05;             //数码管位选,百位
                      Delay_1ms(1);
                          P0 = table[numaz%100/10]; //十位数
                     P2 = 0x06;
                      Delay_1ms(1);
                   P0 = table[numaz%100%10];
                   P2 = 0x07;
                   Delay_1ms(1);
                  
        }     

}               

不知道这代码合理吗?感觉在调试助手里第一次送出的时候显示正确的话,那应该在串口数据接收和数据处理转换环节应该是对的,哪里不知道出了岔子?

最新回复

解决!谢了老大,所犯错误:处理负数一个初鸟对一些基本方面的知识缺乏考虑,把uint换int就ok了!!  详情 回复 发表于 2010-1-2 14:00
点赞 关注

回复
举报

79

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
各位大哥不好意思格式没编辑好,看的有点累!
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
恐怕楼主还没有太深刻理解c语言中何为“字符串”。
char string[11] = "hello world";这句是字符串吗?如果回答是,就说明还需要加强一下对字符串的理解。一定要注意,字符串是以'\0',也就是十进制的0为结尾的。注意,这里所说的“结尾”可并不一定非得是字符串的最后一个字符。如果'\0'在字符串的中间,那么很遗憾,所有针对字符串的函数(比如sprintf(),以"%s"为参数)只能识别到'\0'之前。如果字符串中没有'\0'呢,那更危险,字符串函数会一直找到内存中地址中数据为0位置,这个位置可就不一定在哪里了。一旦访问到了这样的内存位置,程序崩溃很正常。
楼主仔细看看你的接受缓冲是否存在这样的问题?
 
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

4
 
楼主还有一个基本问题需要加强,ascii格式,十六进制,十进制和二进制,bcd码究竟是什么关系?它们之间如何转化,这个问题如果不清楚的话,这个程序基本上没法正确写出来。这几个问题搞清楚了,以后有关断码管的显示游刃有余。
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

5
 
多谢楼上的朋友,是的,数组对一个初学的来说真的很难搞哦!代码该怎么改下?
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

6
 
void Com_Int(void) interrupt 4
{

         if(RI)
         {  
       RI = 0;
           stringaz=SBUF;
           i++;
          if(iaz==12)
           {
           stringaz='\0';
           iaz=0;
           record=1;
           }
     }

}

老大这样可以么?回去试下
 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

7
 
void Com_Int(void) interrupt 4
{

if(RI)
{  
      RI = 0;
  stringaz=SBUF;
  i++;
  if(i==12)
  {
  stringaz='\0';
  i=0;
  record=1;
  }
    }

}


重新改下
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

8
 
楼主可以用proteus仿真一下,结果不就很明了了.楼上从功能上讲可以实现将stringaz变为12字节的字符串
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

9
 
呵呵呵
 
 
 

回复

78

帖子

0

TA的资源

一粒金砂(初级)

10
 
TO:tcdzyq
  关键是我的串口送出的是不定长的字符串,刚试了下,可以显示程序也不跑飞,但是字符串长度稍微变下,显示就乱,还是数组弄不来,标准送出在12个字节。再改,郁闷!!!!
 
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

11
 
再请教下:如果字符串中有类似的负数,比如“AAA 234 -78”如何将-78换算成负数送数码管显示?
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

12
 
引用 9 楼 jazzlam 的回复:
TO:tcdzyq
? 关键是我的串口送出的是不定长的字符串,刚试了下,可以显示程序也不跑飞,但是字符串长度稍微变下,显示就乱,还是数组弄不来,标准送出在12个字节。再改,郁闷!!!!

既然是不定长的字符串,楼主是如何判断一次接受完成了呢?
 
 
 

回复

64

帖子

0

TA的资源

一粒金砂(初级)

13
 
void Com_Int(void) interrupt 4
{

if(RI)
{  
      RI = 0;
  stringaz=SBUF;
  i++;
  if(i==12)
  {
  stringaz='\0';
  i=0;
  record=1;
  }
    }

}

   请教:串口送出不定长字符串,最大12个,最小也就11个,比如"AAA 123 34"上面的代码如果接收的是11个字符的话,那么stringaz数组里的结构是不是这样的:stringaz[0]-[2]是等于A,stringaz[3]=空格,stringaz[4]-[6]是等于123,stringaz[7]=空格,stringaz[8]-[9]等于是3 4,后面2个stringaz[10]-[11]是不是就是2个'\0'.我的理解是不是这样的?老大请赐教啊!都晕了~~~~~
再用sprintf函数区分后存另外个数组stringaz1,sprintf只是碰到'\0'就认为字符串结束,所以不管后面有几个'\0',所以数组大小11或是12没什么问题?
   现在的问题是;字符串”AAA 123 234“这样的可以完全显示,换成”AAA 123 43“这样的就不行了,
琢磨中,哪位指点下啊?
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

14
 
不知道楼主有没有处理过通讯协议.
如果不定长,要有个判断接收结束标志,否则串口哪里会知道什么时候结束,什么时候在后面插入'\0'呢.
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

15
 
void Com_Int(void) interrupt 4
{

         if(RI)
         {  
       RI = 0;
           stringaz[iaz]=SBUF;
           iaz++;
          if(SBUF == '*')
           {
           stringaz[iaz]='\0';
           iaz=0;
           record=1;
           }
     }
}
晕,加个结束符就行了,不好意思初鸟一个!!!才学了2个月,就靠一学习扳,还有个小问题顺便搭车问下,如果字符串”AAA 123 234 *“这样的要是换成有类似负数的如”AAA 123 -34 *“这样的。这个负号怎么处理?给个解决原理就行?
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

16
 
解决!谢了老大,所犯错误:处理负数一个初鸟对一些基本方面的知识缺乏考虑,把uint换int就ok了!!
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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