UART Buffer problem

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Dear Friends

I have modify tutorial basic UART program for receive 5 different command string from PC RS232.

Now all work good if the command string received is long max 4 Char.

When command string is for example 20 char i must send 5 time the same command. Firmware catch only 4 char at time and reply me:
1....4 receive ok
5....9 receive ok
10..14 receive ok
15..19 receive ok
ecc...

In bold the part that I think should be modify:

// Include
#include
#include
// Fine Include

// Define
#define FOSC 4000000
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
#define sbi(var, mask) ((var) |= (uint8_t)(1 << mask))
#define cbi(var, mask) ((var) &= (uint8_t)~(1 << mask))
#define STATUS_LED 0
// Fine Define

//Prototipi di funzioni
void ioinit(void);
static int uart_putchar(char c, FILE *stream);
uint8_t uart_getchar(void);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
void delay_ms(uint16_t x);
//Fine prototipi di funzioni

int main (void)
{

//Definizioni variabili
uint8_t key_press;
int InBuffer_UID[3];
int InBuffer_20[20];
int InBuffer_new_key_card[20];
int InBuffer_scrivi_record[20];
int InBuffer_new_key_reader[9];
int InBuffer_leggi_record[4];
int i;
//Fine Definizioni variabili

ioinit(); //Setup IO pins and defaults

while(1)
{
key_press = uart_getchar();

switch ((int)key_press)
{

//----------------------------//
// -------- Caso UID ---------//
//----------------------------//
case 49: //Carattere reale <3>

InBuffer_UID[1]=(int)key_press;
printf("1 Carattere = %c" ,key_press);
printf(" ----> Valore ascii = %d\n", InBuffer_UID[1]);

for (i=2; i<4; i++)
{
key_press = uart_getchar();
InBuffer_UID[i]=(int)key_press;
printf("%d Carattere = %c" ,i,key_press);
printf(" ----> Valore ascii = %d\n", InBuffer_UID[i]);
}

if ((InBuffer_UID[1]==49) && (InBuffer_UID[3]==51))
{
printf("Comando UID arrivato con successo \n");
}

break;
// ************* Fine Caso UID ***************

//----------------------------------------------//
// ----- Caso New Key Card & Scrivi Record -----//
//----------------------------------------------//
case 113: //Carattere reale <20>

InBuffer_20[1]=(int)key_press;
printf("1 Carattere = %c" ,key_press);
printf(" ----> Valore ascii = %d\n", InBuffer_20[1]);

for (i=2; i<21; i++)
{
key_press = uart_getchar();
InBuffer_20[i]=(int)key_press;
printf("%d Carattere = %c" ,i,key_press);
printf(" ----> Valore ascii = %d\n", InBuffer_20[i]);
}

// ------------- New Key Card -----------------
// <20> <21>
if ((InBuffer_20[1]==113) && (InBuffer_20[3]==101))
{
for(i=1; i<21; i++)
{
InBuffer_new_key_card[i] = InBuffer_20[i];
}
printf("Comando New Key Card arrivato con successo \n");

}
// ------------- Fine New Key Card -----------------

// ------------- Scrivi Record -----------------
// <20> <14>
if ((InBuffer_20[1]==113) && (InBuffer_20[3]==52))
{
for(i=1; i<21; i++)
{
InBuffer_scrivi_record[i] = InBuffer_20[i];
}
printf("Comando Scrivi Record arrivato con successo \n");

}

break;
//****** Fine Caso New Key Card & Scrivi Record ******

//------------------------------------------//
// -------- Caso New Key in Reader ---------//
//------------------------------------------//
case 51://Carattere reale <9>
InBuffer_new_key_reader[1]=(int)key_press;
printf("1 Carattere = %c" ,key_press);
printf(" ----> Valore ascii = %d\n", InBuffer_new_key_reader[1]);

for (i=2; i<10; i++)
{
key_press = uart_getchar();
InBuffer_new_key_reader[i]=(int)key_press;
printf("%d Carattere = %c" ,i,key_press);
printf(" ----> Valore ascii = %d\n", InBuffer_new_key_reader[i]);
}

// <9> <20>
if ((InBuffer_new_key_reader[1]==51) && (InBuffer_new_key_reader[3]==53))
{
printf("Comando New Key Reader arrivato con successo \n");
}
break;
//************** Fine Caso New Key in Reader ****************

//------------------------------------------//
// ----------- Caso Leggi Record -----------//
//------------------------------------------//
case 53://Carattere reale <4>
InBuffer_leggi_record[1]=(int)key_press;
printf("1 Carattere = %c" ,key_press);
printf(" ----> Valore ascii = %d\n", InBuffer_leggi_record[1]);

for (i=2; i<5; i++)
{
key_press = uart_getchar();
InBuffer_leggi_record[i]=(int)key_press;
printf("%d Carattere = %c" ,i,key_press);
printf(" ----> Valore ascii = %d\n", InBuffer_leggi_record[i]);
}

// <4> <13>
if ((InBuffer_leggi_record[1]==53) && (InBuffer_leggi_record[3]==55))
{
printf("Comando Leggi Record arrivato con successo \n");
}

break;
}

}

return(0);
}

void ioinit (void)
{
//1 = output, 0 = input
DDRB = 0b11101111; //PB4 = MISO
DDRC = 0b11111111; //
DDRD = 0b11111110; //PORTD (RX on PD0)

//USART Baud rate: 9600
UBRRH = MYUBRR >> 8;
UBRRL = MYUBRR;
UCSRB = (1<<RXEN)|(1<<TXEN);
UCSRC = (1<<URSEL)|(3<<UCSZ0);

stdout = &mystdout; //Required for printf init
}

static int uart_putchar(char c, FILE *stream)
{
if (c == '\n') uart_putchar('\r', stream);

loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;

return 0;
}

uint8_t uart_getchar(void)
{
while( !(UCSRA & (1<<RXC)) );
return(UDR);
}
//General short delays
void delay_ms(uint16_t x)
{
uint8_t y, z;
for ( ; x > 0 ; x--){
for ( y = 0 ; y < 80 ; y++){
for ( z = 0 ; z < 40 ; z++){
asm volatile ("nop");
}
}
}
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

int InBuffer_UID[3];

Maybe because this is only 3 wide?

Why make your UART work buffers signed 16-bit?
Why make your buffers local to main() and resident on the stack? Is your stack large enough?

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which chip do you have? (Theuch, are you sure that the int is 16 bit? Could it be 32 bit?) How much RAM do you have? Could you show one too long command that must be sent in parts (to see which values go to to which buffers)?

Debugging is for sissies and delivery for surgeons. Real men do demonstration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ints are 32 bits in pcs. They are 16 bits in most microcontrollers.... its short ints that cause me confusion... need to look in a header file somewhere to see what they really are

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

(Theuch, are you sure that the int is 16 bit? Could it be 32 bit?)

Perhaps. It looks like GCC include file format; AFAIK AVR ints would then be 16 bits. IIRC there may be an option to make them 8 bits. But if doing char work, why not use char or unsigned char? In all probablility OP is just wasting stack space, bloating code on each manipulation and comparison, and perhaps creating complications.

Lee

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.