7 Segmentų Ekranas (pamokėlė Nr.1)

Vos ne pats pirmas darbelis su AVR kontroleriais buvo su tokiais ekraniukais 🙂 Aišku pats pagrindas buvo su pora LED. Kad suprasi kaip veikia pats paprasčiausias pagrindas. Tai neilgai pažaidus su LED’ais greit paaiškėja kur ten šuo pakastas:) tik tiek, kad tiek isiaiškinus jau gali padaryti minimalius darbelius ir sužinoti vis daugiau kas ten slypi 🙂 Taigi radęs CD grotuvą, jame radau dvigubą 7 segmentų ekraniuką. Jo sąndara šeip nėra labai sudėtinga. Tiesiog yra sudėti šviesos diodai (LED’ai) ir iš jų yra suformuota aštuoniukė ir taškelis. Pagal modelį gali būti kad pagrindinis yra Anodas arba Katodas. Tai reiškia kad visų LED’ų po vieną koją yra sujungta į krūvą:

ledsch

bet nebūtinai turi būti sujungta taip kaip parodyta šioje schemoje, gali būti ir atvirkščiai. Taigi  susiradus betkokį septynių segmentų ekraniuką, galima susirasti kaip diodai sujunginėti ir susirašyti kur kokia koja:) Kadangi CD Player’iuose  dažniausiai būna dviejų skaitmenų ekraniukas, tai jų viduje segmentai būna sujungti lygiagrečiai ir yra atskiri bendri katodai arba anodai. Aš naudosiu du atskirus skaitmenukus.

pinout

todėl man teko sujunginėti kojas lygiagrečiai išskyrus bendrus katodus palikti atskirus 🙂 Taigi schema atrodo maždaug taip:

schema

Šiaip jei daugiau nieko nereikia jungti prie procesoriaus  tai galima ir nesujunginėti segmentų, bet tada reikės dvigubai daugiau procesoriaus išvadų. Viename skaitmenyje yra 8 segmentai .. 7 segmentai skaitmeniui ir vienas segmentas taškeliui:)  taigi taip iškarto užimtų 16 išvadų ir vieną išvada bendriems katodams .. kas tikrai daugoka. Tam ir yra geriau sujungi lygiagrečiai segmenus, o palikti atskirus bendrus katodus.. taip sutaupoma išvadų.. bereikia 8 išvadų segmentams ir dviejų išvadų bendriems katodams. Tai vietoj 17 išvadų bereikia 10 🙂 Beto kaip aš sujungiau segmentus prie AVR kontrolerio nėra butinybė jungti būtent taip.. dėl pajungimo skirsis tik skaitmenų kombinacijos, o skaitmenų deriniai atrodo taip:

0 – a,b,c,d,e,f
1 – b,c
2 – a,b,g,e,d
3 – a,b,g,c,d
4 – f,g,b,c
5 – a,f,g,c,d
6 – a,f,e,d,c,g
7 – a,b,c
8 – a,b,c,d,e,f,g
9 – d,c,b,a,f,g

taigi kiekviena raidė turi savo koją todėl gautusi skirtingos kombinacijos.

Aš susidariau tokia lentelę, pagal kurią lengvai galima išsireikšti jas.

numbers

Viršuje susirašiau kur kokia raidė(koja) pajungta prie AVR kontrolerio kojos, o stulpeliu surašytos reikšmės, pagal anksčiau pateiktas kombinacijas prie raidžiu bereiki tik surašyti vienetukus. Na ir viską turint pasiruošus galima pradėt programavimą. Aišku programavimui reikės ir programatoriaus 🙂 Iš pradžių gali būti sunku sugalvoti kaip padaryti, kad vienu metu turėtume du skirtingus skaičius  abiejuose skaitmenyse 🙂 Nes juk segmentai sujungti lygiagrečiai.. tai ijungus abu bendrus katodus matysime du vienodus skaitčius.. taigi kaip tai padaryti, kad jie butu skirtingi.. man pirmą karta paaiškino vienas žmogus (jauler) pacituosiu ji:

<jauler>paduodi skaitmeni ant porto
<jauler>ijungi pirma LED`a
<jauler> palauki
<jauler>išjungi pirma LED`a
<jauler>pakeiti skaitmeni ant porto
<jauler>ijungi antra LED`a
<jauler>palauki
<jauler>išjungi antra LED`a

aišku šitai vyksta labai greitai, todėl mes nematome kaip mirga skaičiai 🙂

pradinis programos kodas atrodytų taip:

#include <avr/io.h>
#include <util/delay.h>
 
unsigned char a[11]= {0x77,0x14,0xB3,0xB6,0xD4,0xE6,0xE7,0x34,0xF7,0xF6,0x08}; //0,1,2,3,4,5,6,7,8,9,.
unsigned char x,i; //kintamieji skaitmenims ir ciklui 
 
char vienetai(char x) //funkcija gauti vienetams
{
return x%10; //ieškoma liekana
}
 
char desimtys(char x) //funkcija gauti dešimtims
{
return x/10; //dalinama iš dešimties kad gauti pirmajį skaitmenį
}
 
int main(void)
{
DDRD=255; //visi PD0-PD7 bus kaip išėjimai (Segmentai)
DDRB=3 //PB0 ir PB1 bus kaip išėjimai (Katodai)
while(1) //Amžinas ciklas
{
  for (x=0;x<100;x++) //Skaičiuosime nuo 0 iki 100
    {
    for (i=0;i<100;i++) <em>// vieną kombinaciją rodisimę 100 kartų</em>
      {
      PORTB=0b00 //išjungiame abu bendrus katodus
      PORTD=a[desimtys(x)]; //paduodame skaitmenį iš masyvo į funkciją, kuri grąžina dešmčių skaitmenį
      PORTB=0b01 //įjungiam pirmajį skaitmenį įjungdami bendrą katodą pirmojo skaitmens
      _delay_ms(1); //palaukiam
      PORTB=0b00;  //išjungiam bendrus katodus
      PORTD=a[vienetai(x)]; //paduodame skaitmenį iš masyvo į funkciją, kuri grąžina vienetų skaitmenį
      PORTB=0b10; //įjungiam antrajį skaitmenį įjungdami bendrą katodą antrojo skaitmens
      _delay_ms(1); //palaukiam
      }
    }
}
}

tokia progamėlė jau rodytu didejantį skaičių, nuo 00 iki 99 ir vėl iš pradžių 🙂

bet tokia programa nėra labai gera, nes procesoriuis ištysai naudojamas rodyti skaičims. Kad to išvengti reikia panaudoti TIMER. Kuris užsiims skaičių vaizdavimu ir atnaujinimu nemaišydamas procesoriaus darbo 🙂 Tam reikės panaudoti pertrauktis (Interrupts) ir kodas atrodys taip:

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
 
unsigned char a[11]= {0x77,0x14,0xB3,0xB6,0xD4,0xE6,0xE7,0x34,0xF7,0xF6,0x08}; //0,1,2,3,4,5,6,7,8,9,.
volatile unsigned char sk; //kintamieji
unsigned char s,x,i;
 
char vienetai(char x) //funkcija gauti vienetams
{
return x%10; //ieškoma liekana
}
 
char desimtys(char x) //funkcija gauti dešimtims
{
return x/10; //dalinama iš dešimties kad gauti pirmajį skaitmenį
}
 
int main(void)
{
DDRD=255; //visi PD0-PD7 bus kaip isejimai (Segmentai)
DDRB=3; //PB0 ir PB1 bus kaip isejimai (Katodai) 
 
TIMSK |= (1 << TOIE0) //Ijungiame persipildymo (Overflow) interrupt'a
TCCR0 |= (1 << CS02); //Ijungiame dalikli (prescaler) is 256 ir kai tik isijungia clock'as timer'iui  jis tuoj ir pradeda veikti
sei(); //ijungiame globalias pertrauktis
sk=0;
while(1) //Amžinas ciklas
{
if (sk<99) //patikriname ar skaičius neviršijo 99
  {
  sk++; //jei neviršijo tai didiname skaičiu
  }
else //priešingu atveju
  {
  sk=0; //nustatome iš pradžių
  }
_delay_ms(150); //parodome ilgiau vieną skaitmenį
}
}
 
ISR(TIMER0_OVF_vect) //Overflow interuptas
{
s++; //padidiname reikšmę vienetu kad pakeistu bendrą katodą
if (s == 1) //Tikriname koks skaičius dabar yra
  {
  PORTB=0; //Išjungiam visus ekranus
  PORTD=a[desimtys(sk)]; //Parenkamas skaičius ir nustatomos reikalingos PD kojos
  PORTB=s; //Įjungiamas pirmas ekranas
  }
else if (s == 2) //Tikriname koks skaičius dabar yra
  {
  PORTB=0; //Išjungiami visi ekranai
  PORTD=a[vienetai(sk)]; //Parenkamas skaičius ir nustatomos  reikalingos PD kojos
  PORTB=s; //Įjungiamas antras ekranas
  s=0; //atstatomas skaitmuo, kad vėl pradėtu iš pradžių
  }
}

breadboard

Toks kodas žymei patogesnis 🙂 nes jau galima main() funkcijoje tiesiog parašyti sk=25; ir ekraniukas jau rodys tuos skaitmenis 🙂 Taigi tam kartui tiek..:) ir taip turbūt pabos skaityt 🙂

Tags: , , ,

8 Responses to “7 Segmentų Ekranas (pamokėlė Nr.1)”

  1. Armandas says:

    Sveikas. Turiu tokią pastabėlę dėl kodo. Dabar labai nepatogu jį skaityti. Geriau būtų, jei įdėtum atskirą failą, naudotum žymes, ar kokį spalvinimo plugin’ą.

    O šiaip tai gera pamokėlė 😉

  2. admin says:

    Sveikas, toks plugin’as būtų tikrai gerai 🙂 pamėginisiu paieškot:) nu ir dar įdėsiu visą projekto supakuotą direktoriją

  3. zhulikas says:

    Yra toks WP Syntax, susimesk ;]

  4. admin says:

    Dėkui zhulikas 🙂 pamačijo 🙂

  5. garsisc says:

    mldc! nebloga pamokele 😉

  6. Arturas says:

    O ar imanoma butu gauti koda 7segmentu ekraneliui su bendru + ?

  7. ateiciai says:

    ateiciai jei dar kam toks klausymas kiltu : Jei bendras + tai ant segmentu portu dek tranzus, o anodus junk tiesiogiai ir nk keist kode nereikia.

  8. Admin says:

    Taip, galimas ir toks variantas 🙂

Leave a Reply

You can add images to your comment by clicking here.

Spam Protection by WP-SpamFree