Witam,
Od kilku dniu próbuję uporać się z komunikacją po RS485, no i napotkałem problem z którym sobie nie radzę.
Korzystam z płytki testowej ZL2AVR ( http://www.btc.pl/pdf/zl2avr.pdf ) oraz układu MAX485 ( http://ecee.colorado.edu/~mcclurel/max485ds.pdf ) (pomiędzy zasilanie a masę kondensatory 47uF i 100nF, piny !RE i DE połączone razem i podłączone do PB0 uC, RO do RxD od uC, a DI do TxD, B idzie do wejścia przejściówki -485, A do +485, pomiędzy A i B jest opornik 120, przejściówka to kupiony konwerter RS485 na USB zrobiony na FTDI).
Z wysyłaniem nie ma problemów. Procesor wszystko ładnie wysyła i komputer odbiera. Problem pojawia się przy próbie odbierania. Tuż po włączeniu uC zaczyna odbierać bez przerwy losowe znaki (a nic nie wysyłałem przez terminal). Gdy podłączyłem oscyloskop do pinu RxD od uC układ nagle zaczął częściowo działać. Odbierał jeden bajt poprawnie, następnie drugi bajt 0x00, potem znowu kolejny poprawnie i kolejny 0x00, i tak cały czas. Po odłączeniu oscyloskopu znowu zaczął wariować i w kółko odbierać losowe bajty. Próbowałem programowo podciągać pin RxD pull-up'em, ale nic to nie zmieniło, również dawałem w różnych miejscach opóźnienia, żeby sprawdzić czy może gdzieś za krótko trwa jakiś stan albo coś nie zdążyło się zmienić - no i nadal nic.
Zamieszczam fragment programu, z którym mam problem (Atmega pracuje na zewnętrznym kwarcu 8MHz).
Naprawdę nie rozumiem, dlaczego po podłączeniu oscyloskopu odbiera prawie poprawnie (oprócz tego ekstra bajtu 0x00), a po odłączeniu szaleje. Wysyłanie działa dobrze, więc to raczej nie kwestia Baud Rate'a czy jakiś innych ustawień. Może musze dać jakiś zewnętrzny rezystor podciągający?
Od kilku dniu próbuję uporać się z komunikacją po RS485, no i napotkałem problem z którym sobie nie radzę.
Korzystam z płytki testowej ZL2AVR ( http://www.btc.pl/pdf/zl2avr.pdf ) oraz układu MAX485 ( http://ecee.colorado.edu/~mcclurel/max485ds.pdf ) (pomiędzy zasilanie a masę kondensatory 47uF i 100nF, piny !RE i DE połączone razem i podłączone do PB0 uC, RO do RxD od uC, a DI do TxD, B idzie do wejścia przejściówki -485, A do +485, pomiędzy A i B jest opornik 120, przejściówka to kupiony konwerter RS485 na USB zrobiony na FTDI).
Z wysyłaniem nie ma problemów. Procesor wszystko ładnie wysyła i komputer odbiera. Problem pojawia się przy próbie odbierania. Tuż po włączeniu uC zaczyna odbierać bez przerwy losowe znaki (a nic nie wysyłałem przez terminal). Gdy podłączyłem oscyloskop do pinu RxD od uC układ nagle zaczął częściowo działać. Odbierał jeden bajt poprawnie, następnie drugi bajt 0x00, potem znowu kolejny poprawnie i kolejny 0x00, i tak cały czas. Po odłączeniu oscyloskopu znowu zaczął wariować i w kółko odbierać losowe bajty. Próbowałem programowo podciągać pin RxD pull-up'em, ale nic to nie zmieniło, również dawałem w różnych miejscach opóźnienia, żeby sprawdzić czy może gdzieś za krótko trwa jakiś stan albo coś nie zdążyło się zmienić - no i nadal nic.
Zamieszczam fragment programu, z którym mam problem (Atmega pracuje na zewnętrznym kwarcu 8MHz).
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#define USART_BAUD 9600ul
#define USART_UBBR_VALUE ((F_CPU/(USART_BAUD<<4))-1)
void USART_Init()
{
UBRRH = (uint8_t)(USART_UBBR_VALUE>>8);
UBRRL = (uint8_t)USART_UBBR_VALUE;
UCSRB = (1<<RXEN)|(1<<TXEN);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
}
void USART_Transmit(unsigned char c)
{
while (!( UCSRA & (1<<UDRE))) {};
UDR = c;
while (!( UCSRA & (1<<UDRE))) {};
}
unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) ){};
/* Get and return received data from buffer */
return UDR;
}
void USART_SendString(unsigned char* s, int size)
{
int i;
for(i=0;i<size;i++)
{
USART_Transmit(s[i]);
}
}
int main(void)
{
unsigned char data;
char licznik = '1';
//PB0 jako wyjscie, do sterowania kierunku transmisji max485
DDRB |= (1<<0);
USART_Init();
while(1)
{
//max485 na wysylanie
PORTB |= (1<<0);
USART_SendString("Podejscie: ",11);
USART_Transmit(licznik);
USART_Transmit('\n');
//max485 na odbieranie
PORTB &= ~(1<<0);
data = USART_Receive();
//max485 na wysylanie
PORTB |= (1<<0);
USART_SendString("Odebralem: ",11);
USART_Transmit(data);
USART_Transmit('\n');
licznik++;
}
}Naprawdę nie rozumiem, dlaczego po podłączeniu oscyloskopu odbiera prawie poprawnie (oprócz tego ekstra bajtu 0x00), a po odłączeniu szaleje. Wysyłanie działa dobrze, więc to raczej nie kwestia Baud Rate'a czy jakiś innych ustawień. Może musze dać jakiś zewnętrzny rezystor podciągający?
