Как правильно сбросить буфер, чтобы следующее чтение было правильным?
Мой проект предусматривает отправку команд из PuTTY на плату разработки Dragon12-Plus2 (CodeWarrior 5.1) через Wi-Fi XBEE. Я использую 4 команды для управления светодиодами на плате Дракона {led_enable(), leds_on(здесь целое число в шестнадцатеричном или десятичном виде), leds_off() и led_disable()} из проекта LBE_DRAGON12_Plus из LBEbooks.com. Вот мой код:
// 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 соответствующих светодиода), но любая команда, которую я посылаю после, ничего не делает. Я не уверен, как правильно сбросить cbuff, чтобы он работал одинаково каждый раз, а не только в первый раз.
ИЗМЕНЕНО, ЧТОБЫ ПОКАЗАТЬ ПРЕДЛАГАЕМЫЕ ИЗМЕНЕНИЯ!
2 ответа
Если вы хотите очистить все элементы в массиве, то memset
будет мудрым выбором
memset(cbuff, 0, 20);
При этом я бы полностью согласился с @John Bollinger, что было бы разумно разделять ввод и функциональность интерпретации.
Тем не менее, в зависимости от приложения memset
может быть излишним. Простой очищенный массив также можно получить, просто установив для элементов массива нулевой символ ('\0'
). Просто позвони cbuff[0] = '\0'
для каждого элемента в массиве.
Что за странный парсер. Я бы посоветовал вам отделить этап ввода от этапа интерпретации команд. То есть читайте и считайте символы, пока не получите точку с запятой (;
) терминатор команды, и только потом попытайтесь интерпретировать команду.
Сбросить parser
переменная (которая была бы более точно названа как command_length
) только после каждой попытки интерпретировать команду, независимо от того, была она успешной или нет, или если буфер собирается переполниться.