如何正确地重置缓冲区,以便下次读取正确?

问题描述:

我的项目涉及通过XBEE Wifi将命令从PuTTY发送到Dragon12-Plus2开发板(CodeWarrior 5.1)。我使用4个命令来控制来自LBEbooks.com的LBE_DRAGON12_Plus项目中龙板{led_enable(),leds_on(十六进制或十进制整数),leds_off()和led_disable()}上的LED。这里是我的代码:如何正确地重置缓冲区,以便下次读取正确?

// Final Project: Control leds via XBEE Wifi 
#include <hidef.h>  /* common defines and macros */ 
#include <mc9s12dg256.h>  /* derivative information */ 
#include "queue.h" 
#pragma LINK_INFO DERIVATIVE "mc9s12dg256b" 

#include "main_asm.h" /* interface to the assembly module */ 

void main(void){ 
    int x,y,z,parser; 
    int cmdLen = 0;      
    char c,d,e; 
    char cbuff[20]; 
    PLL_init();        // set system clock frequency to 24 MHz 
    lcd_init();        // enable lcd 
    SCI1_init(9600);      // initialize SCI1 at 9600 baud 
    SCI0_init(9600);      // initialize SCI0 at 9600 baud 
    seg7_disable();       // disable 7 segment display 
    led_enable();       // enable 8 leds 
    while(1){ 
    if(SCI1SR1_RDRF == 1){ 
     c = inchar1(); 
     cbuff[cmdLen] = c; 
     outchar0(cbuff[cmdLen]); 
     if(c == ';'){ 
     if((cbuff[0] == 'l') && (cbuff[10] == ';')){ 
      leds_off(); 
      cmdLen = 0; 
     } 
     else if((cbuff[0] == 'l') && (cbuff[12] == ';')){ 
      led_enable(); 
      cmdLen = 0; 
     } 
     else if((cbuff[0] == 'l') && (cbuff[4] == 'd')){ 
      led_disable(); 
      cmdLen = 0; 
     } 
     else if((cbuff[0] == 'l') && (cbuff[13] == ';')){ 
      d = cbuff[10]; 
      e = cbuff[11]; 
      switch(d){      // change first number to integer 
      case('0'): 
       x = 0x00; 
       break; 
      case('1'): 
       x = 0x10; 
       break; 
      case('2'): 
       x = 0x20; 
       break; 
      case('3'): 
       x = 0x30; 
       break; 
      case('4'): 
       x = 0x40; 
       break; 
      case('5'): 
       x = 0x50; 
       break; 
      case('6'): 
       x = 0x60; 
       break; 
      case('7'): 
       x = 0x70; 
       break; 
      case('8'): 
       x = 0x80; 
       break; 
      case('9'): 
       x = 0x90; 
       break; 
      case('a'): 
       x = 0xa0; 
       break; 
      case('b'): 
       x = 0xb0; 
       break; 
      case('c'): 
       x = 0xc0; 
       break; 
      case('d'): 
       x = 0xd0; 
       break; 
      case('e'): 
       x = 0xe0; 
       break; 
      case('f'): 
       x = 0xf0; 
       break; 
      default: 
       break; 
      } 
      switch(e){      // change second number to integer 
      case('0'): 
       y = 0x00; 
       break; 
      case('1'): 
       y = 0x01; 
       break; 
      case('2'): 
       y = 0x02; 
       break; 
      case('3'): 
       y = 0x03; 
       break; 
      case('4'): 
       y = 0x04; 
       break; 
      case('5'): 
       y = 0x05; 
       break; 
      case('6'): 
       y = 0x06; 
       break; 
      case('7'): 
       y = 0x07; 
       break; 
      case('8'): 
       y = 0x08; 
       break; 
      case('9'): 
       y = 0x09; 
       break; 
      case('a'): 
       y = 0x0a; 
       break; 
      case('b'): 
       y = 0x0b; 
       break; 
      case('c'): 
       y = 0x0c; 
       break; 
      case('d'): 
       y = 0x0d; 
       break; 
      case('e'): 
       y = 0x0e; 
       break; 
      case('f'): 
       y = 0x0f; 
       break; 
      default: 
       break; 
      } 
      z = (x + y);      // add integers together 
      leds_on(z);      // display hex number on leds 
      cmdLen = 0;      // reset parser 

     } 
     for(parser = 0; parser < 20; parser++){ 
      cbuff[parser] = '\0'; 
     } 
     } 
     cmdLen++; 
    } 
    } 
} 

第一个命令我把作品发送预期(例如,如果我输入leds_on(和0xAA); PuTTY中4米对应的LED点亮),但我发出任何命令不执行任何操作之后。我不知道如何正确地重置cbuff,使其每次都以相同的方式运行,而不仅仅是第一次。

编辑显示建议的更改!

+0

你说得对,问题的一部分是你没有在命令之间清除'cbuff'的内容,但你不需要这样做。更大的问题是,在每次击键之后都要测试缓冲区是否包含可识别的命令,如果是,则重置解析器。 –

+0

这一行:'void main(void){'无效,应该引发编译器警告。正确的行是:'int main(){' – user3629249

+0

一个所需值的表,并且使用(当前切换(parm))parm作为表中的索引将使得代码的数量级更小且明显更快。 – user3629249

多么奇怪的解析器。我建议你将你的输入阶段与命令解释阶段分开。也就是说,读取和计数字符,直到您收到一个分号(;)命令终止符,然后才尝试解释该命令。

只有在每次尝试解释命令(无论是否成功)或者缓冲区即将溢出后,才会重置parser变量(将更准确地将其命名为command_length)。

+0

我考虑了这一点,并提出了建议的更改。现在第一个命令“leds_on(0x55);”打开正确的LED,但然后我键入“leds_off();”和位8和位6 LED来?这真的很棘手...... – Carsomyr

+0

对新行为的最可能的解释是:(1)当你的程序收到命令“leds_off()”时,会执行与调用'leds_off()'不同的东西。 (2)'leds_off()'函数无法正常工作; (3)通过调用'leds_off()'处理“leds_off()”命令后,程序会调用一些其他函数(即'leds_on()')来重新打开一些LED。 –

如果你想清除所有的数组中的元素,然后将memset是一个明智的选择:

memset(cbuff, 0, 20); 

话虽这么说,我会强烈@约翰布林同意分离输入和解释功能将是明智的。

但是,根据应用memset可能是矫枉过正。简单的清除数组也可以通过简单地将数组的元素设置为空字符来实现('\0')。只需为阵列中的每个元素调用cbuff[0] = '\0'即可。

+0

使用这会给我一个错误“函数调用的结果被忽略”。 – Carsomyr

+0

我更新了答案;尝试一下。 – Willis

+0

仍然返回调用结果被忽略。 – Carsomyr