Wątek przeniesiony 2018-11-07 15:14 z C/C++ przez Marooned.

Mikrokontrolery, timery

0

Witam, posiadam kod do programu, który wykonuje odmierzanie czasu dla dwóch timerów. Przy pomocy guzików mogę zatrzymywać te timery, bądź też jeden lub drugi przyspieszać. Czy jest ktoś mi wstanie wyjaśnić krok po kroku jak działa cały kod? Mam na myśli do czego dana linijka lub funkcja służy. Dziękuję i pozdrawiam.
MistrzKontrolerów

#include <51\AnalogDevices\ADuC834.h>
at 0x8000 xdata volatile char daneLCD; //skad sie to wzielo (adres w pamieci zewnetrznej, konkretny)
at 0x8001 xdata volatile char rozkazLCD;
at 0xA2 sbit LED2;
at 0xA0 sbit LED1;
at 0xA1 sbit KL1;
at 0xA3 sbit KL2;
at 0xA5 sbit KL3;
at 0x90 sbit klaw_dane;
char licz_klaw=0; //numer odebranego bitu
char klaw; //odebrany znak
char znak_odebr;
char zaw_sbuf=0x00;
bit klaw_ok; //potwierdzenie odebrania znaku
bit bFO=0; //informacja o tym, ze byl bit F0 w znaku
bit CapsL; //wcisnieto capslocka
int pozycja=0x1000;
bit RSod;
char licz_T0=0x00; 
char licz_T2=0x00; 
    int liczsek0=0;
    int liczsek2=0;


void zap_dane_LCD(char wart) //procedura zapisu danych
    {
        daneLCD=wart;
        while(rozkazLCD&0x03!=0x03); //czeka az na koncu nie pojawi sie 11
    }

void zap_rozkaz_LCD(char wart) //procedura zapisu rozkazu
    {
        rozkazLCD=wart;
        while(rozkazLCD&0x03!=0x03);
    }
void initLCD() //inicjalizacj LCD
    {
        zap_rozkaz_LCD(0x80);
        zap_dane_LCD(0x00);
        zap_dane_LCD(0x00);
        zap_rozkaz_LCD(0x42);
        zap_dane_LCD(0x1E);
        zap_dane_LCD(0x00);
        zap_rozkaz_LCD(0x43);
        zap_dane_LCD(0x00);
        zap_dane_LCD(0x10);
        zap_rozkaz_LCD(0x40);
        
        zap_dane_LCD(0x1E);
        zap_dane_LCD(0x00);
        zap_rozkaz_LCD(0x41);
        
        zap_rozkaz_LCD(0x94);
    }
    
void wyslijznakLCD() //wyswietla znak u (150 str)
{
    zap_dane_LCD(0x00);
    zap_dane_LCD(0x10);
    zap_rozkaz_LCD(0x24);
    
    zap_dane_LCD(0x54); //kod znaku
    zap_rozkaz_LCD(0xC0);
    
}

void ustaw_wsk_WK_LCD(char wiersz, char kolumna)
{ 
char adrLS; //najmniej wazny adres (00)
adrLS = (wiersz-0x01)*0x1E+kolumna;
zap_dane_LCD(adrLS);
zap_dane_LCD(0x10);
zap_rozkaz_LCD(0x24);
}



void clearLCDznak() //czysci
{
int i;
zap_dane_LCD(0x00);
zap_dane_LCD(0x10); //ust wskaz na 0
zap_rozkaz_LCD(0x24); //rozkaz ustawienia wskaznika
zap_rozkaz_LCD(0xB0); //tryb sekw on

for(i=0;i<240;i=i+1)
{
zap_dane_LCD(0x00); //kod znaku spacji
}
zap_rozkaz_LCD(0xB2); //tryb sekw off
zap_dane_LCD(0x00);
zap_dane_LCD(0x10);
zap_rozkaz_LCD(0x24); //rozkaz ustawienia wskaznika
pozycja=0x1000;
}

void wysw_znak_LCD(char x) //wyswietla znak konkretny (150 str)
{
    zap_dane_LCD(x); //kod znaku
    zap_rozkaz_LCD(0xC0);   
    pozycja++;
}
void ustaw_wskazn_LCD(int x) //ustawienie wskaznika
{
if (x<240)
    {
        int adres=0x1000;
        char adrLS; //najmniej wazny adres (00)
        char adrMS; //najwa|niejszy adres (10)
        adres=adres+x; 
        adrLS = adres&0x00FF; //maska by otrzymac najmloszy
        adrMS = adres>>8; //przesuniecie by otzymac najstarszy

        zap_dane_LCD(adrLS);
        zap_dane_LCD(adrMS);
        zap_rozkaz_LCD(0x24);
    }
}
void klaw_int0(void) interrupt 0
{
char kl; //bajt gdzie jest 1 lub 0

kl=klaw_dane; //przypisanie bitu do zmiennej 8smio bitowej (rejestru)
switch(licz_klaw)
    {
    case 0: // 00000000
        if(klaw_dane==0)
        {
        klaw=0;
        }
        licz_klaw++;
        break;
    case 1:// 0000000X
    case 2:// 000000X0
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
        klaw=klaw | (kl<<(licz_klaw-1)); //przypisanie do rejestru
        licz_klaw++;
        break;
    case 9: // 000000X0
        licz_klaw++;
        break;
    case 10: // 000000X0
        if(klaw_dane==1)
        {
        klaw_ok=1; //odebrano caly znak
        znak_odebr=klaw;
        licz_klaw=0;

        }
        break;
    }
}


void init_interrupts(void)
{
IE=IE | 0x81;
TCON=TCON | 0x01;
klaw_dane=1;
}

void init_T0(void)
{
   TMOD = TMOD | 0x31;
   TCON = TCON | 0x10;
   IE = IE | 0x82;
   TH0=0x3C;
   TL0=0xAF; //preload 15535
}
void init_T2(void) //t2con
{
    T2CON=T2CON|0X04;
       TH2=0x3C;
   TL2=0xAF; //preload 15535
   IE = IE | 0xA0;
RCAP2L=0xAF; //rejestry z ktorych T2 bierze wart. pocz. po przeladowaniu 
RCAP2H=0x3C;
}

void init_WD(void)
{
WDWR=1;
WDCON=0x72; 

}


void przerw_T0(void) interrupt 1
{

    licz_T0++; // musi liczyc do 20 by osiagnac 1s.
    TH0=0x3C;
    TL0=0xAF; //preload 15535
    if(licz_T0==0x14) //osiagnieto 20 
    {
    liczsek0++;
    licz_T0=0x00;
    }
}
void przerw_T2(void) interrupt 5 // 8*n +3= adres (0x2B) n=5
{
    licz_T2++; // musi liczyc do 20 by osiagnac 1s.
TF2=0; //zerowanie flagi przeladowania timera T2
    if(licz_T2==0x14) //osiagnieto 20 
    {
    liczsek2++;
    licz_T2=0x00;
    }
}
void LCD_liczba(int x) //wyswietla podana cyfre int na 5ciu znakach
{
   wysw_znak_LCD(0x10+(x/10000));
   wysw_znak_LCD(0x10+(x/1000)%10);
   wysw_znak_LCD(0x10+((x/100)%100)%10);
   wysw_znak_LCD(0x10+(((x/10)%1000)%100)%10);
   wysw_znak_LCD(0x10+((((x)%10000)%1000)%100)%10);
}


void backspace(void) //gumowanie
{
    zap_dane_LCD(0x00); //kod znaku
    zap_rozkaz_LCD(0xC2);  //zapis i dekrementacja wskaznika
    zap_dane_LCD(0x00); //kod znaku
    zap_rozkaz_LCD(0xC4);  //zapis bez zmiany wskaznika
    pozycja--;
}





void main(void)
{
P2=0xFF;
PLLCON=0; //dziala szybciej
initLCD();
clearLCDznak();
init_interrupts();
init_T0();
init_T2();
init_WD();


    while(1)
    {
    WDWR=1; //watchdog write enable
WDCON=0x72; //
    ustaw_wskazn_LCD(0);
    LCD_liczba(liczsek0);
    ustaw_wskazn_LCD(30);
    LCD_liczba(liczsek2);
while(KL1==0); //czekaie na watchdoga 
    if(KL2==0)
        {
        liczsek0++;
    while(KL2==0);
        }
    if(KL3==0)
        {
        liczsek2++;
    while(KL3==0);
        }
    }
}
0

Odnośnie początku (i adresów): zgaduję, że to jest LCD z kontrolerem HD44780 podpięty do magistral pamięciowych mikrokontrolera. W ten sposób można wysyłać tekst i komendy do wyświetlacza po prostu pisząc pod konkretny adres. Bez schematu elektrycznego trudno tu więcej powiedzieć. Ogólnie: http://www.analog.com/media/en/technical-documentation/data-sheets/ADUC834.pdf strona 63.

1 użytkowników online, w tym zalogowanych: 0, gości: 1