| 297 | kaklik | 1 | //----------------------------------------------------------------------------------
 | 
        
           | 300 | kaklik | 2 | //	Prevodnik RS232 <--> RS485
 | 
        
           | 299 | kaklik | 3 | //	pri startbitu na RS232 zapne okamzite vysilac pokud nejsou detekovana data z RS485.
 | 
        
           | 297 | kaklik | 4 | //----------------------------------------------------------------------------------
 | 
        
           | 305 | kaklik | 5 | //
 | 
        
           |  |  | 6 | //Algoritmus:
 | 
        
           |  |  | 7 | //  Princip je zalozen na mereni nejkratsiho casoveho useku v osmi vzorcich, delka vzorku 
 | 
        
           |  |  | 8 | //  se odviji od velikosti prave nejmensiho zmereneho vzorku.
 | 
        
           | 306 | kaklik | 9 | //  delka vzorku se meri pomoci 8mi bitoveho casovace a interruptu od zmeny vstupu. casovac je osetren
 | 
        
           |  |  | 10 | //  proti pretekani (pocet preteceni se uklada, do promenne s ktere se zpetne vypocita 16bitove cislo, 
 | 
        
           |  |  | 11 | //  casovac se tedy virtualne chova jako 16ti bitovy.)
 | 
        
           | 305 | kaklik | 12 | //
 | 
        
           | 306 | kaklik | 13 | // Tento zpusob detekce neni imuni proti nahodnym chybovim spickam vzniklych v dusledku ruseni. 
 | 
        
           | 305 | kaklik | 14 | // Proto je nutene napajeni kvalitne stbilizovat, pouzivat blokovaci kondenzatory a 
 | 
        
           |  |  | 15 | // zabezpecit, aby nedochazelo ke zvedani zeme.
 | 
        
           |  |  | 16 | /////////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 17 | //
 | 
        
           |  |  | 18 | //TODO:
 | 
        
           |  |  | 19 | //  Optimalizovat kod, (hlavne najit casove vyhodnejsi umisteni pro nastavovani defaultnich hodnot promennych)
 | 
        
           |  |  | 20 | //  Bylo bydobre zavest uspavani pred prijetim bajtu.
 | 
        
           |  |  | 21 | //  Vykouset program na ATtiny13
 | 
        
           | 306 | kaklik | 22 | //  Program neni vyzkousen pri extremne nizkych rychlostech, kdy by teoreticky 
 | 
        
           | 305 | kaklik | 23 | //  mohlo dochazet k preteceni promenne cas.
 | 
        
           | 306 | kaklik | 24 | //  Neni vyzkousen break, byly testovany pouze ASCII znaky vysilane pres terminal z klavesnice.  
 | 
        
           | 305 | kaklik | 25 | //////////////////////////////////////////////////////////////////////////////////////
 | 
        
           |  |  | 26 | //
 | 
        
           | 297 | kaklik | 27 |   | 
        
           | 305 | kaklik | 28 |   | 
        
           | 297 | kaklik | 29 | #include <avr/io.h>
 | 
        
           |  |  | 30 | #include <avr/interrupt.h>
 | 
        
           |  |  | 31 | #include <stdlib.h>
 | 
        
           |  |  | 32 | #include <ctype.h>
 | 
        
           |  |  | 33 | #include <avr/eeprom.h>
 | 
        
           |  |  | 34 | #include <avr/pgmspace.h>
 | 
        
           |  |  | 35 |   | 
        
           | 306 | kaklik | 36 | #define POVOLOVAK_LOW	PORTB &= ~(1<<PB3)   // nastaveni nuly na vystup, krery zapina povoleni vysilani RS485
 | 
        
           |  |  | 37 | #define POVOLOVAK_HIGH  PORTB |= (1<<PB3)    // nastaveni jednicky na tentyz vystup
 | 
        
           |  |  | 38 | #define DATA	(PIND & (1<<PD3))			// nastaveni vstupu, na kterem se budou detekovat data, musi byt stejny jako vstup pouziteho interruptu 
 | 
        
           | 297 | kaklik | 39 |   | 
        
           | 306 | kaklik | 40 | volatile unsigned int preteceni;  // promenna na ukladani poctu preteceni casovace
 | 
        
           |  |  | 41 | volatile unsigned int bit;		// promena pro pocitani bitu v bajtu
 | 
        
           |  |  | 42 | volatile unsigned int bitdelay; // obsahuje aktualni zmereny cas delky bitu
 | 
        
           |  |  | 43 | volatile unsigned int cas;		// urcuje nejkratsi nalezeny cas delky bitu
 | 
        
           | 302 | kaklik | 44 |   | 
        
           | 303 | kaklik | 45 | ISR(TIMER0_OVF_vect)   // interrupt od preteceni casovace
 | 
        
           |  |  | 46 | {
 | 
        
           |  |  | 47 |   preteceni++;			// kdyz pretece, poznamenej to.
 | 
        
           |  |  | 48 | }
 | 
        
           |  |  | 49 |   | 
        
           | 306 | kaklik | 50 | ISR(INT1_vect)   // interrupt od zmeny vstupu na datech
 | 
        
           | 305 | kaklik | 51 | {
 | 
        
           | 306 | kaklik | 52 |   if ((bitdelay=TCNT0+preteceni*0x0100) < cas) cas = bitdelay; // provnani jestli zrovna zmereny cas je kratsi nez nejmensi znamy cas   
 | 
        
           | 305 | kaklik | 53 |   TCNT0 = 0;					// zacni znova merit cas zacatku stopbitu
 | 
        
           | 306 | kaklik | 54 |   preteceni=0;				// vynuluj vsechny casove promenne
 | 
        
           |  |  | 55 |   bit++;		// posun pocitadlo bitu o jednicku 
 | 
        
           | 305 | kaklik | 56 | }
 | 
        
           | 303 | kaklik | 57 |   | 
        
           | 297 | kaklik | 58 | // ------------------------------------------------------------------
 | 
        
           |  |  | 59 | //	Main
 | 
        
           |  |  | 60 | // ------------------------------------------------------------------
 | 
        
           |  |  | 61 | int main(void)
 | 
        
           |  |  | 62 | {
 | 
        
           | 306 | kaklik | 63 | int stopbit;
 | 
        
           | 297 | kaklik | 64 |   | 
        
           | 306 | kaklik | 65 | //  DDRD |= (1<<DDD5);     // povoleni vystupu pro blikani ledkou (mozno odebrat)
 | 
        
           | 297 | kaklik | 66 |   | 
        
           | 305 | kaklik | 67 |   DDRB |= (1<<DDB3);     // povoleni vystupu na povolovak 
 | 
        
           |  |  | 68 |   | 
        
           |  |  | 69 |   TIMSK |= (1 << TOIE0); // Enable timer overflow interrupt
 | 
        
           |  |  | 70 |   | 
        
           |  |  | 71 |   MCUCR |= (1 << ISC10); // nastaveni preruseni od zmeny vstupu pro interrupt INT0
 | 
        
           |  |  | 72 |   GIMSK |= (1 << INT1);  // povoleni interruptu INT0
 | 
        
           |  |  | 73 |   | 
        
           |  |  | 74 |   TCCR0B |= (1 << CS00);  // Set up timer 
 | 
        
           |  |  | 75 |   | 
        
           | 303 | kaklik | 76 |   sei();   // enable interrupts
 | 
        
           | 297 | kaklik | 77 |   | 
        
           |  |  | 78 |   while(1)
 | 
        
           |  |  | 79 |   {
 | 
        
           | 300 | kaklik | 80 | 	if(!DATA)   // kdyz je 0 na datech 
 | 
        
           | 297 | kaklik | 81 | 	{ 
 | 
        
           | 300 | kaklik | 82 | 	  POVOLOVAK_HIGH;    // zapni vysilani
 | 
        
           | 303 | kaklik | 83 |   | 
        
           | 306 | kaklik | 84 | 	  bit=0;			// vynuluj vsechny promenne pro mereni casu a pocitani bitu
 | 
        
           | 305 | kaklik | 85 |       TCNT0=0;
 | 
        
           |  |  | 86 |       preteceni=0;
 | 
        
           | 306 | kaklik | 87 | 	  cas = 0xFFFF;    // nastav cas delky bitu na nejvetsi mozny
 | 
        
           | 305 | kaklik | 88 |   | 
        
           | 306 | kaklik | 89 | 	  while (bit <= 8)  // odpocitej dobu 8mi bitu
 | 
        
           | 299 | kaklik | 90 | 	  {
 | 
        
           | 306 | kaklik | 91 | 	    if ((100+TCNT0+preteceni*0x0100) >= cas) // zkontroluj jestli necekame na dalsi bit dele nez je nekratsi znema delka bitu
 | 
        
           | 299 | kaklik | 92 | 		{
 | 
        
           | 306 | kaklik | 93 |           TCNT0 = 0;					// zacni znova merit cas do dalsiho mozneho bitu
 | 
        
           | 305 | kaklik | 94 |           preteceni=0;
 | 
        
           | 306 | kaklik | 95 | 		  bit++;						// pokud jsme cekali dele, tak bit uz ubehl, to znamena, ze muzeme pocitadlo bitu posunout o jednicku
 | 
        
           | 305 | kaklik | 96 | 		} 
 | 
        
           | 298 | kaklik | 97 | 	  }
 | 
        
           | 300 | kaklik | 98 |   | 
        
           | 306 | kaklik | 99 | /*	  while (!DATA);				// cekani na stop bit (detekce pripadneho paritniho bitu)
 | 
        
           |  |  | 100 |   | 
        
           |  |  | 101 | 	  for (stopbit=2;stopbit >= 0;stopbit--)    // odpocitej dva stopbity
 | 
        
           | 303 | kaklik | 102 | 	  {
 | 
        
           |  |  | 103 | 	    while ((TCNT0+preteceni*0x0100) <= cas) 
 | 
        
           |  |  | 104 | 		{
 | 
        
           |  |  | 105 | 		  if(!DATA) break;
 | 
        
           |  |  | 106 |         }
 | 
        
           |  |  | 107 | 	  }*/
 | 
        
           | 297 | kaklik | 108 |     }
 | 
        
           | 300 | kaklik | 109 |     else  POVOLOVAK_LOW;  	// kdyz je 1 prepni na prijem 
 | 
        
           | 297 | kaklik | 110 |   }
 | 
        
           | 298 | kaklik | 111 |   return(0);
 | 
        
           | 297 | kaklik | 112 | }
 |