Subversion Repositories svnkaklik

Compare Revisions

Ignore whitespace Rev 304 → Rev 305

/programy/Atmel_C/RS232toRS485/P232.c
2,7 → 2,27
// 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>
12,13 → 32,12
 
#define POVOLOVAK_LOW PORTB &= ~(1<<PB3)
#define POVOLOVAK_HIGH PORTB |= (1<<PB3)
#define DATA (PIND & (1<<PD1))
#define DATA (PIND & (1<<PD3))
 
volatile unsigned int preteceni;
unsigned int bit;
unsigned int bitdelay;
unsigned int last;
unsigned int cas;
volatile unsigned int bit;
volatile unsigned int bitdelay;
volatile unsigned int cas;
 
ISR(TIMER0_OVF_vect) // interrupt od preteceni casovace
{
25,6 → 44,13
preteceni++; // kdyz pretece, poznamenej to.
}
 
ISR(INT1_vect)
{
if ((bitdelay=TCNT0+preteceni*0x0100) < cas) cas = bitdelay; //
TCNT0 = 0; // zacni znova merit cas zacatku stopbitu
preteceni=0;
bit++;
}
 
// ------------------------------------------------------------------
// Main
32,11 → 58,17
int main(void)
{
 
DDRD |= (1<<DDD5);
DDRB |= (1<<DDB3);
DDRD |= (1<<DDD5); // povoleni vystupu pro blikani ledkou (mozno odebrat)
 
TIMSK |= (1 << TOIE0); // Enable timer overflow interrupt
TCCR0B |= (1 << CS10); // Set up timer
DDRB |= (1<<DDB3); // povoleni vystupu na povolovak
 
TIMSK |= (1 << TOIE0); // Enable timer overflow interrupt
 
MCUCR |= (1 << ISC10); // nastaveni preruseni od zmeny vstupu pro interrupt INT0
GIMSK |= (1 << INT1); // povoleni interruptu INT0
TCCR0B |= (1 << CS00); // Set up timer
 
sei(); // enable interrupts
 
while(1)
45,32 → 77,25
{
POVOLOVAK_HIGH; // zapni vysilani
 
bitdelay = 0;
bit=0;
TCNT0=0;
preteceni=0;
cas = 0xFFFF;
bitdelay = 0;
for (bit=0;bit<=7;bit++) // odpocitej dobu 8mi bitu
while (bit <= 10) // odpocitej dobu 8mi bitu
{
last = DATA;
TCNT0 = 0; // vynuluj citac pred tim, než smazes preteceni, protoze jinak by se mohlo stat, ze se nastavi preteceni driv, nez ma
preteceni = 0;
 
while ((TCNT0+preteceni*0x0100) <= cas) // bit poznas tak, ze je to nejmensi nalezena delka trvaleho stavu
if ((TCNT0+preteceni*0x0100) > cas)
{
bitdelay=TCNT0+preteceni*0x0100;
if(DATA != last) // zkontroluj, jestli se nezmenil stav dat.
{
if (bitdelay < cas) cas = bitdelay; //kdyz se zmenil a trvalo to kratsi dobu nez pred tim poznemenej, jak dlouho to trvalo
break;
}
}
TCNT0 = 0; // zacni znova merit cas zacatku stopbitu
preteceni=0;
bit++;
}
}
while (!DATA); // cekani na stop bit
while (!DATA); // cekani na stop bit (detekce pripadneho paritniho bitu)
 
/* for (bit=2;bit >= 0;bit--) // odpocitej dva stopbity
{
TCNT0 = 0; // zacni znova merit cas zacatku stopbitu
preteceni=0;
 
while ((TCNT0+preteceni*0x0100) <= cas)
{
if(!DATA) break;