UART w ATmega8

Witam. Mecze sie juz jakis czas z oprogramowaniem UARTu w atmedze na przerwaniach. Napisalem takie cos:

______________________________________________________________ #define UART_TX_DATA_INT_ENABLE UCSRB = UCSRB | (1<<UDRIE) #define UART_TX_DATA_INT_DISABLE UCSRB = UCSRB & 223 #define UART_IN_BUFF_SIZE 10 #define UART_OUT_BUFF_SIZE 10 #define CRYSTAL 11059200 #define BAUDRATE 9600

void uartInit(unsigned long crystal, unsigned long baudrate) { unsigned char ubrr_value = 0; UCSRB = 0; cli(); ubrr_value = (((crystal/baudrate)/16)-1); UBRRH = (unsigned char) ((ubrr_value)>>8); UBRRL = (unsigned char) ubrr_value; UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); UCSRB = (1<<RXEN)|(1<<TXEN); sei(); }

unsigned char uartSendCharacter(unsigned char character) { if(uart_out_filling != UART_OUT_BUFF_SIZE) { uart_out_buff[uart_out_wr_ptr] = character; uart_out_wr_ptr == (UART_OUT_BUFF_SIZE - 1) ? uart_out_wr_ptr = 0 : uart_out_wr_ptr++; uart_out_filling++; UART_TX_DATA_INT_ENABLE; return 0; } else return 1; }

SIGNAL(SIG_UART_DATA) { if(uart_out_filling) { UDR = uart_out_buff[uart_out_rd_ptr]; uart_out_rd_ptr == (UART_OUT_BUFF_SIZE - 1) ? uart_out_rd_ptr = 0 : uart_out_rd_ptr++; uart_out_filling--; } else { UART_TX_DATA_INT_DISABLE; } }

int main(void) //program główny { uartInit(CRYSTAL, BAUDRATE); uartSendCharacter(60); uartSendCharacter(61); uartSendCharacter(62); uartSendCharacter(63); uartSendCharacter(64); uartSendCharacter(65); while(1); } ______________________________________________________________

Ladnie sie kompiluje, ale nie dziala. W debugerze w AVRStudio widac ze w przerwaniach dwa kolejne znaki sa ladowane do UDR, potem jednak flaga UDRE przyjmuje wartosc 0 i koniec. Dalej nic juz nie wychodzi z bufora, a flaga nie zmienia stanu na 1 nie zglaszajac tym samym przerwania. Nie wiem co z ta flaga bo przeciez ona podobno jest ustawiana na 1 gdy sie oprozni bufor. Gdzie jest "byk" ? Na sprzecie rowniez nie dziala, nie pojawiaja sie nawet te dwa znaki ktore wedlug debugera sa ladowane do UDR.

Reply to
Krzysztof Urbanski
Loading thread data ...

Nie wnikam w Twoj program. Zobacz moj -- moze dojdziesz, co jest nie tak u Ciebie.

#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

#include <string.h>

#include "uart.h"

enum { RECVBUF_MAX = 16, /* max. rozmiar bufora odbiorczego

*/ RECVBUF_USER_MAX = RECVBUF_MAX + 2, VUBRR = 19 /* wpis do UBRR, 18.4320MHz, 57600 */ };

/* initUART: inicjalizuje UART */ void initUART(void) { /* zabronienie przerwan na czas inicjalizacji */ cli();

/* ustawienie predkosci transmisji */ UBRRH = (unsigned char)(VUBRR >> 8); UBRRL = (unsigned char)VUBRR;

/* zezwolenie na przerwania od odbiornika i nadajnika */ UCSRB = (1 << RXCIE) | (1 << TXCIE) | (1 << RXEN);

/* ustawienie formatu ramki: 8, 1 stop */ UCSRC = (1 << URSEL) | (3 << UCSZ0);

/* zezwolenie na przerwania */ sei(); }

char recvBuf[RECVBUF_USER_MAX] = "\0"; volatile char *recvBufPtr = recvBuf; volatile unsigned char zzz;

/* SIG_UART_RECV: obsluguje odbiornik */ SIGNAL (SIG_UART_RECV) { // cbi(UCSRB, RXEN); /* zablokowanie odbiornika */

if (recvBufPtr - recvBuf < RECVBUF_MAX) *recvBufPtr++ = zzz = UDR;

// sbi(UCSRB, RXEN); /* zablokowanie odbiornika */ }

/* recvTxt: zwraca odczytany napis */ int recvTxt(char *s) { int p;

if ((recvBufPtr == recvBuf) || (*(recvBufPtr - 1) != '\0')) return 0;

cbi(UCSRB, RXEN); /* zablokowanie odbiornika */

strncpy(s, recvBuf, p = (recvBufPtr - recvBuf)); s[p] = '\0';

recvBufPtr = recvBuf;

sbi(UCSRB, RXEN); /* odblokowanie odbiornika */

return p; }

//volatile char txt[RECVBUF_USER_MAX] = "\0"; volatile char *txt = NULL; volatile unsigned char flagTrans = 0;

/* SIG_UART_TRANS: obsluguje nadajnik * -- wywolywana automatycznie po wyslaniu znaku */ SIGNAL (SIG_UART_TRANS) { if (flagTrans == 0) { if (*txt == '\0') flagTrans = 1;

UDR = *txt++; } else {

cbi(UCSRB, TXEN); /* wylaczanie nadajnika */ flagTrans = 0; // cbi(UCSRB, UDRIE); } }

/* sendTxt: wysyla napis */ void sendTxt(const char *s) { if ((s == NULL) || (s[0] == '\0')) return;

/* oczekiwanie na wyslanie calego poprzedniego lancucha */ while (!(UCSRA & (1 << UDRE))) ;

flagTrans = 0;

// strcpy((char *)_txt, (char *)s); // txt = _txt;

txt = (char *)s;

sbi(UCSRB, TXEN); /* wlaczanie nadajnika */ UDR = (unsigned char)*txt++; /* wyslanie pierwszego znaku, reszta przez przerw. */ }

Reply to
Vicky

Vicky napisał(a):

Dzieki. Na pewno sie przyda, szczegolnie jak nie uda mi sie uruchomic mojego. Roznica miedzy nimi jest taka ze ja uzywam przerwania od oproznienia rejestru przesuwnego nadajnika, a w Twoim wykorzystane jest przerwanie od oproznienia bufora.

Reply to
Krzysztof Urbanski

To moze zerknij jeszcze na moj kod:

formatting link
bardzo podobny mechanizm jak twoj. Bufor kolowy i asynchroniczne wysylanie/obdieranie w przerwaniach. Napisalem ten modulik w ramach zabawy z AVRka i nie meczylem go specjalnie testami, ale jak do tej pory dziala w miare bezblednie

pzdr. j.

Reply to
Jacek R. Radzikowski

chodzi o tx? /ja to nawet w maile nie wnikam :), taki len :)

a jesli chodzi o tx to ja do transferu uzywam "udr empty" a nie "tx comlete", praktycznie nie zauwazysz roznicy, jednak ja uzywam tak, bo uwazam, ze to bardziej "logiczne" :)

Reply to
Q

Jeszcze raz ja. Moze to nie potrzebne, ale dodam, ze mialem problemy z UART, jesli niewlasciwie ustawione byly kierunki Tx i Rx poprzez DDR.

Vicky.

Reply to
Vicky

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.