/*
UART-stuff voor de ATmega32
Pros 2007
*/
#define UART_RX_BUFFER_SIZE 129
#define uart_sendstr_P(__s) uart_sendstr_p(P(__s))
#define reply_err() uart_sendstr_P("Err\n")
// Wait until tx holding register is empty, then send character c down the UART Tx.
#define uart_sendchar(x) loop_until_bit_is_set(UCSRA, UDRE);\
UDR = x
#define nl() loop_until_bit_is_set(UCSRA, UDRE);\
UDR = '\n'
static char uart_outbuf[UART_RX_BUFFER_SIZE + 1];
static char uart_rxbuf[UART_RX_BUFFER_SIZE + 1];
volatile static unsigned char uart_rx_pos; // end of string in rx
volatile static unsigned char uart_rx_linecomplete; // one complete line in buffer
// Deze functie wordt aangeroepen, telkens er een karakter binnenkomt
ISR(SIG_UART_RECV)
{
unsigned char c;
c = UDR;
uart_rxbuf[uart_rx_pos] = c;
if ((c == '\n') || (uart_rx_pos > UART_RX_BUFFER_SIZE - 1)) {
uart_rxbuf[uart_rx_pos] = 0;
strcpy(uart_outbuf, uart_rxbuf);
uart_rx_linecomplete = 1;
} else {
uart_rx_pos++;
}
}
void uart_init(void)
{
uart_rx_pos = 0;
uart_rx_linecomplete = 0;
UCSRA = 0x00;
UCSRB = _BV(TXEN) | _BV(RXEN) | _BV(RXCIE); // enable tx/rx and interrupt on rx
UCSRC = _BV(URSEL) | _BV(USBS) | _BV(UCSZ1) | _BV(UCSZ0); // Set frame format: 8data, 2stop bit
UBRRH = 0;
UBRRL = (F_CPU / (16 * 38400UL)) - 1; // set baudrate - 38400bd
}
void ok(void)
{
loop_until_bit_is_set(UCSRA, UDRE);
UDR = 'O';
loop_until_bit_is_set(UCSRA, UDRE);
UDR = 'K';
loop_until_bit_is_set(UCSRA, UDRE);
UDR = '\n';
}
void err(void)
{
loop_until_bit_is_set(UCSRA, UDRE);
UDR = 'E';
loop_until_bit_is_set(UCSRA, UDRE);
UDR = 'r';
loop_until_bit_is_set(UCSRA, UDRE);
UDR = 'r';
loop_until_bit_is_set(UCSRA, UDRE);
UDR = '\n';
}
// send string to the rs232
void uart_sendstr(char *s)
{
while (*s) {
uart_sendchar(*s);
s++;
}
}
// print string from program memory on rs232
void uart_sendstr_p(const prog_char * progmem_s)
{
unsigned char c;
while (1) {
c = PRG_RDB(progmem_s++);
if ((c == 0) || (c > 252)) {
return;
} else {
uart_sendchar(c);
}
}
}
void reply(int r)
{
if (r == 0) {
uart_sendstr_P("Err: ");
uart_sendstr(uart_outbuf);
uart_sendchar('\n');
}
}
// Verstuur een (16-bits) unsigned int over de RS232-lijn
void dec2RS232(unsigned int getal)
{
unsigned long deeltal = 10000;
char tmp, cnt, zeroflag = 0;
if (getal == 0) {
uart_sendchar('0');
uart_sendchar(' ');
return;
} else {
for (cnt = 0; cnt < 5; cnt++) {
tmp = 0;
while (getal >= deeltal) {
tmp++;
getal -= deeltal; // decade berekenen
}
if (tmp > 0) { // als dat geen 0 is
zeroflag = 1; // worden alle volgende decaden afgedrukt
uart_sendchar(tmp + '0'); // ascii-teken verzenden
} else if (zeroflag == 1) { // Is dit de eerste 0?
uart_sendchar('0'); // nee; '0' verzenden
}
deeltal /= 10; // deeltal aanpassen voor volgende decade
}
uart_sendchar(' ');
}
}
// Verstuur een unsigned long over de RS232-lijn
void UL2RS232(unsigned long getal)
{
unsigned long deeltal = 1000000000UL;
char tmp, cnt, zeroflag = 0;
if (getal == 0UL) {
uart_sendchar('0');
uart_sendchar('.');
return;
} else {
for (cnt = 0; cnt < 10; cnt++) {
tmp = 0;
while (getal >= deeltal) {
tmp++;
getal -= deeltal; // decade berekenen
}
if (tmp > 0) { // als dat geen 0 is
zeroflag = 1; // worden alle volgende decaden afgedrukt
uart_sendchar(tmp + '0'); // ascii-teken verzenden
} else if (zeroflag == 1) { // Is dit de eerste 0?
uart_sendchar('0'); // nee; '0' verzenden
}
deeltal /= 10UL; // deeltal aanpassen voor volgende decade
}
uart_sendchar('.');
}
}
// Verstuur de cijfers na de komma (duizendsten) over de RS232-lijn
void DS2RS232(unsigned long getal)
{
char tmp;
if (getal > 999) {
return;
}
tmp = 0;
while (getal >= 100) {
tmp++;
getal -= 100; // tienden berekenen
}
uart_sendchar(tmp + '0'); // ascii-teken verzenden
tmp = 0;
while (getal >= 10) {
tmp++;
getal -= 10; // honderdsten berekenen
}
uart_sendchar(tmp + '0');
uart_sendchar((unsigned char) getal + '0'); // Duizendsten verzenden
}
// Voorbeeld: 123.056
void float2RS232(double getal)
{
unsigned long eenheden;
unsigned long duizendsten;
eenheden = (unsigned long) getal; // eenheden = 123
getal -= (double) eenheden; // getal = 0.056
duizendsten = (unsigned long) (getal *= 1000.0); // duizendsten = 56
UL2RS232(eenheden);
//uart_sendchar('.');
DS2RS232((unsigned long) duizendsten);
}