Rev 304 | Blame | Last modification | View Log | Download
//----------------------------------------------------------------------------------// Prevodnik RS232 <--> RS485// pri startbitu na RS232 zapne okamzite vysilac pokud nejsou detekovana data z RS485.//----------------------------------------------------------------------------------////Algoritmus:// Princip je zalozen na mereni nejkratsiho casoveho useku v osmi vzorcich, delka vzorku// se odviji od velikosti prave nejmensiho zmereneho vzorku.////// Tento zpusob detekce neni imuni proti nahodnym chybovim sickam vzniklych v dusledku ruseni.// Proto je nutene napajeni kvalitne stbilizovat, pouzivat blokovaci kondenzatory a// zabezpecit, aby nedochazelo ke zvedani zeme./////////////////////////////////////////////////////////////////////////////////////////TODO:// Optimalizovat kod, (hlavne najit casove vyhodnejsi umisteni pro nastavovani defaultnich hodnot promennych)// Bylo bydobre zavest uspavani pred prijetim bajtu.// Vykouset program na ATtiny13// program neni vyzkousen pri extremne nizkych rychlostech, kdy by teoreticky// mohlo dochazet k preteceni promenne cas.////////////////////////////////////////////////////////////////////////////////////////#include <avr/io.h>#include <avr/interrupt.h>#include <stdlib.h>#include <ctype.h>#include <avr/eeprom.h>#include <avr/pgmspace.h>#define POVOLOVAK_LOW PORTB &= ~(1<<PB3)#define POVOLOVAK_HIGH PORTB |= (1<<PB3)#define DATA (PIND & (1<<PD3))volatile unsigned int preteceni;volatile unsigned int bit;volatile unsigned int bitdelay;volatile unsigned int cas;ISR(TIMER0_OVF_vect) // interrupt od preteceni casovace{preteceni++; // kdyz pretece, poznamenej to.}ISR(INT1_vect){if ((bitdelay=TCNT0+preteceni*0x0100) < cas) cas = bitdelay; //TCNT0 = 0; // zacni znova merit cas zacatku stopbitupreteceni=0;bit++;}// ------------------------------------------------------------------// Main// ------------------------------------------------------------------int main(void){DDRD |= (1<<DDD5); // povoleni vystupu pro blikani ledkou (mozno odebrat)DDRB |= (1<<DDB3); // povoleni vystupu na povolovakTIMSK |= (1 << TOIE0); // Enable timer overflow interruptMCUCR |= (1 << ISC10); // nastaveni preruseni od zmeny vstupu pro interrupt INT0GIMSK |= (1 << INT1); // povoleni interruptu INT0TCCR0B |= (1 << CS00); // Set up timersei(); // enable interruptswhile(1){if(!DATA) // kdyz je 0 na datech{POVOLOVAK_HIGH; // zapni vysilanibitdelay = 0;bit=0;TCNT0=0;preteceni=0;cas = 0xFFFF;while (bit <= 10) // odpocitej dobu 8mi bitu{if ((TCNT0+preteceni*0x0100) > cas){TCNT0 = 0; // zacni znova merit cas zacatku stopbitupreteceni=0;bit++;}}while (!DATA); // cekani na stop bit (detekce pripadneho paritniho bitu)/* for (bit=2;bit >= 0;bit--) // odpocitej dva stopbity{while ((TCNT0+preteceni*0x0100) <= cas){if(!DATA) break;}}*/}else POVOLOVAK_LOW; // kdyz je 1 prepni na prijem}return(0);}