Transformators.lv


 
 
 
 
 
 
 
Transformators.lv » Atmega8 gaismasdiožu vadība + pārtraukumi | Beztēma | Forums
Jums jāielogojas lai rakstītu
Meklēt Forumus:


 






Wildcard Usage:
*    apzīmē jebkuru skaitli
%    apzīmē tieši vienu rakstzīmi

Atmega8 gaismasdiožu vadība + pārtraukumi

Aplūkot oriģinālo rakstu

Ieraksts
Member

KasparsL

09:13 24.08.2011

ieraksti23
Rakstu skaits 4

1

Sveicināti!
Vēlējos iemēģināt prasmes rakstīšanā un nolēmu izveidot šo rakstiņu. Pastāstīšu nedaudz par iespējām, kuras var noderēt, un, kuras var izmantot, rakstot "gaismas efektu" projektus iesācējiem. Rakstīsim C valodā. Es konkrēti izmantoju AVRStudio vidi.

Kas būs nepieciešams:
- ATMEGA8/8A mikrokontrolieris (ar nelielām programmas izmaiņām Atmega48/88/168/328)
- 8x gaismas diodes
- 8x rezistori (gaismas diožu strāvas ierobežošanai)
- kondensātors 100n jebkāds
- barošanas bloks vai baterijas, vai cits barošanas avots 3-5V
- spiedpoga ("tactswitch")
- maketplate (nelodējamā, bet protams, var arī uztaisīt iespiedplati)
- savienotājvadiņi
- AVR programmātors (piem. AVRISP vai cits, vai paštaisīts)
- nedaudz brīva laika ;)

Slēguma shēma: (klikšķiniet, lai palielinātu) Maketplate:

Pirms turpināt pārliecinieties, ka jūs protat programmu nokompilēt un rezultātu ielādēt mikrokontrolierī!

Tad nu ķersimies pie lietas!

Pirmais piemērs:
Šis veids, kā attēlot informāciju uz gaismas diodēm  ir vienkāršākais un visvairāk flash un ram atmiņas aizņemošais. Piemērā redzam, ka tiek daudzkārt atkārtoti ievietota viena un tā pati funkcija ('_delay_ms()'), tas aizņem vietu 'flash' atmiņā. Arī izvadāmo datu kopa (pattern) nav īpaši ērti pārskatāma.

// Piemers 1
#include <avr/io.h>  // ieejas-izejas biblioteka
#include <util/delay.h> // aiztures biblioteka

void ioinit(){
 DDRB = 0b11111111; // PORTB visas izejas (prieks diodem)
}

void showSequence1(){ // paradam pirmo sablonu un atgriezamies atpakal
 PORTB = 0b00000001;
 _delay_ms(300);
 PORTB = 0b00000011;
 _delay_ms(300);
 PORTB = 0b00000111;
 _delay_ms(300);
 PORTB = 0b00001111;
 _delay_ms(300);
 PORTB = 0b00011111;
 _delay_ms(300);
 PORTB = 0b00111111;
 _delay_ms(300);
 PORTB = 0b01111111;
 _delay_ms(300);
 PORTB = 0b11111111;
 _delay_ms(300);
}

int main(void){
 ioinit(); // sagatavojam mikroprocesoru
 while(1){ // izpildit vienmer (bezgaliga cilpa)
  showSequence1();
 }
return 0;
}

Otrs piemērs:
Otrajā piemērā redzam, ka attēlojamie dati ir sakārtoti "sequence2data[8]" kopā. Tas piešķir datiem pārskatāmību un ir ērti tos modificēt vai labot. Pati datu izvades funkcija "showSequence2()" ir izveidota kā 'for()' cikls, kas ļauj atbrīvoties no daudzkārtējajiem vienādajiem funkciju izsaukumiem. Rakstot garas gaismas efektu programmas ļauj ekonomēt ievērojamu daudzumu 'flash' atmiņas, bet joprojām aizņemam daudz 'RAM' atmiņas. Definējot mainīgo, tiek aizņemta vieta 'flash' atmiņā, un, ieslēdzot mikroprocesoru, mainīgais tiek ielādēts 'RAM' atmiņā! Piemēram – ja gribēsiet izveidot programmu ar 500 stāvokļiem (vai 10 programmas pa 50) priekš 8 gaismas diodēm (8 kanāliem) tiks aizņemti 500 baiti 'RAM'. Atmega8 satur tikai 1024 baitus RAM. Tātad šādā veidā arī neko īpaši garu nevar uzrakstīt.

// Piemers 2
#include <avr/io.h>      // ieejas-izejas biblioteka
#include <util/delay.h>     // aiztures biblioteka

uint8_t sequence2data[8] = {
 0b10000000,      //otra sablona dati
 0b01000000,
 0b00100000,
 0b00010000,
 0b00001000,
 0b00000100,
 0b00000010,
 0b00000001    };

void ioinit(){
 DDRB = 0b11111111;     // PORTB visas izejas (prieks diodem)
}

void showSequence1(){     // paradam pirmo sablonu un atgriezamies atpakal
 PORTB = 0b00000001;     // izvadam sablona datus uz diodem
 _delay_ms(300);        // pauze 300ms (neko nedaram / daram neko)
 PORTB = 0b00000011;     // utt.
 _delay_ms(300);
 PORTB = 0b00000111;
 _delay_ms(300);
 PORTB = 0b00001111;
 _delay_ms(300);
 PORTB = 0b00011111;
 _delay_ms(300);
 PORTB = 0b00111111;
 _delay_ms(300);
 PORTB = 0b01111111;
 _delay_ms(300);
 PORTB = 0b11111111;
 _delay_ms(300);
}
void showSequence2(){     // paradam otro sablonu un atgriezamies atpakal
 for(uint8_t i=0; i<8; i++){        // atkartojam ciklus, lidz i < 8, pec katra cikla beigam 'i' vertiba palielinas par 1
  PORTB = sequence2data[i];     // izvadam datus uz diodem, dati ar adresi 'i' no kopas squenceData2[]
  _delay_ms(300);       // pauze 300ms (neko nedaram / daram neko)
 }
}

int main(void){
 ioinit();     // sagatavojam mikroprocesoru
 while(1){     // izpildit vienmer (bezgaliga cilpa)
 showSequence1();
 showSequence2();
 }
 return 0;
}

Trešais piemērs:
Trešajā piemērā parādīts "pgmspace" bibliotēkas pielietojums, veidojot "mirgojošās" programmas. Mainīgo kopa "sequence3data[]" tiek novietota PROGMEM tas ir 'flash' atmiņā un netiek iekopēta RAM., līdz ar to ieekonomējam daudz RAM atmiņas. BET, lai nolasītu datus, kas atrodas šajā kopā, ir jāizmanto speciāla funkcija "pgm_read_byte()" (no pgmspace bibliotēkas). Šī funkcija nolasa 1 baitu sākot ar norādīto adresi (mūsu gadījumā no 'sequence3data', kas atrodas PROGMEM jeb 'flash' atmiņā).

// Piemers 3
#include <avr/io.h>      // ieejas-izejas biblioteka
#include <util/delay.h>     // aiztures biblioteka
#include <avr/pgmspace.h>  // biblioteka tiesai datu piekluve "program memory"

uint8_t sequence2data[8] = {
 0b10000000,      //otra sablona datu kopa RAM atmina
 0b01000000,
 0b00100000,
 0b00010000,
 0b00001000,
 0b00000100,
 0b00000010,
 0b00000001    };

uint8_t sequence3data[8] PROGMEM = {
 0b10000001,      //tresa sablona datu kopa PROGMEM atmina
 0b11000011,
 0b11100111,
 0b11111111,
 0b01111110,
 0b00111100,
 0b00011000,
 0b00000000    };

void ioinit(){
 DDRB = 0b11111111;     // PORTB visas izejas (prieks diodem)
}

void showSequence1(){     // paradam pirmo sablonu un atgriezamies atpakal
 PORTB = 0b00000001;     // izvadam sablona datus uz diodem
 _delay_ms(300);        // pauze 300ms (neko nedaram / daram neko)
 PORTB = 0b00000011;     // utt.
 _delay_ms(300);
 PORTB = 0b00000111;
 _delay_ms(300);
 PORTB = 0b00001111;
 _delay_ms(300);
 PORTB = 0b00011111;
 _delay_ms(300);
 PORTB = 0b00111111;
 _delay_ms(300);
 PORTB = 0b01111111;
 _delay_ms(300);
 PORTB = 0b11111111;
 _delay_ms(300);
}

void showSequence2(){     // paradam otro sablonu un atgriezamies atpakal
 for(uint8_t i=0; i<8; i++){        // atkartojam ciklus, lidz i < 8, pec katra cikla beigam 'i' vertiba palielinas par 1
  PORTB = sequence2data[i];     // izvadam datus uz diodem, dati ar adresi 'i' no kopas squenceData2[]
  _delay_ms(300);       // pauze 300ms (neko nedaram / daram neko)
 }
}

void showSequence3(){     // radam 3 sablonu
 for(uint8_t i=0; i<8; i++){
  PORTB = pgm_read_byte(sequence3data + i);    // nolsam datus, kura adrese ir datuKopa + ierakstaNumurs
  _delay_ms(500);
 }
}

int main(void){
 ioinit();     // sagatavojam mikroprocesoru
 while(1){     // izpildit vienmer (bezgaliga cilpa)
  showSequence1();
  showSequence2();
  showSequence3();
 }
 return 0;
}

Tagad esam sarakstījuši vairākus efektus (piemērā 3 tie ir 3 gabali). Piemērā 3 efekti tiek rādīti pēc kārtas un katrs vienu reizi. Bet kā lai pārslēdzas starp tiem, piemēram ar pogas palīdzību? Ja mēs pievienotu funkciju galvenajā cilpā, kas pārbauda pogas stāvokli,  pogas spiediens tiktu ignorēts efekta attēlošanas laikā, kas, protams, neder. Šeit mums var palīdzēt pārtraukumi.

Ceturtais piemērs:
Ceturtajā piemērā tiek demonstrēta mikroprocesora spēja 'pārtraukties', izmainoties loģiskajam līmenim uz kājiņas – mūsu gadījumā uz PORTD PD2 kājiņas. Konkrēti šim pārtraukumam ir piešķirts nosaukums "INT0".
Pārtraukums ir mikroprocesora spēja noreaģet uz kādu notikumu (piem. līmeņa izmaiņu uz kājiņas, iekšējā skaitītāja stāvokli, pabeigtu analogi-digitālo pārveidojumu utt.) kura rezultātā tiek pārtraukta programmas izpilde un tiek izpildīta pārtraukuma funkcija, un pēc tās izpildes, mikroprocesors atgriežas pie pārtrauktās programmas izpildes.
Mūsu gadījumā  – INT0 pārtraukums, šī pārtraukuma funkcijas nosaukums ir "INT0_vect".
Piemērā 4 demonstrēju šī pārtraukuma darbību. Pēc notikuša pārtraukuma tiek izslēgti pārtraukumi ("cli()", lai nekas šī pārtraukuma funkcijas laikā mūs nepārtrauktu), pēc tam gaidām līdz poga tiek atlaista, izmainām mainīgā "flag" vērtību, slēdzam atpakaļ pārtraukumus ('sei()') un atgriežamies kur pārtraucāmies.
Tajā pašā laikā galvenajā cilpā ('while(1)') visu laiku tiek pārbaudīta "flag" mainīgā vērtība, un balstoties uz to, tiek vai nu ieslēgtas visas gaismas diodes, vai nu izslēgtas.

// Piemers 4
#include <avr/io.h>      // ieejas-izejas biblioteka
#include <avr/interrupt.h>      // partraukumu biblioteka
#include <util/delay.h>     // aiztures biblioteka

uint8_t  flag = 0;

ISR(INT0_vect) {  //leksim seit, ja konstatets partraukums uz PD2 (INT0)
 cli();    // izsledzam partraukumus, lai seit mus neviens nepartrauktu
 while(!(PIND & _BV(PD2))){    // gaidam, kamer poga tiks atlaista
  _delay_ms(30);   // 'debounce' pauzite
 }
 flag++;        //palielinam mainigo par 1
 if(flag > 1){
  flag = 0;    // ja mainigais lielaks par 1 pieskiram tam veribu 0
 }    // mainiga veriba pec partraukumiem 1-0-1-0-utt.
 sei();    // iesledam partraukumus atpakal
} // pec izpildisanas lecam atpakal, kur partraucamies

void ioinit(){
 DDRB = 0b11111111;     // PORTB visas izejas (prieks diodem)
 DDRD = 0b11111011;    // PD2 ieeja (pogai)
 PORTD |= _BV(PD2);  // iesledzam "pullup" PD2 ieejai

 //  Ja lietojat Atmega8, tad INT0 partraukumu konfigurejam sadi
 MCUCR = 0;    // partraukums uz INT0 un INT1 kajam pie nulles limena, un mes negulam
 GICR |= _BV(INT0);    // aktivizejam INT0 partraukumu

 //  Ja lietojat Atmega48/88/168/328, tad INT0 partraukumu konfigurejam sadi
 //    EICRA = 0;    // partraukums uz INT0 un INT1 kajam pie nulles limena
 //    EIMSK |= _BV(INT0);    // aktivizejam INT0 partraukumu
 sei();    // iesledzam partraukumus
}

int main(void){
 ioinit();     // sagatavojam mikroprocesoru
 while(1){     // izpildit vienmer (bezgaliga cilpa)
  if(flag == 1){
   PORTB = 0b11111111;    // ja mainigais ir '1' iesledam visas diodes
  }else{
   PORTB - 0b00000000; // ja mainigais ir '0' izsledam visas diodes
  }
 }
 return 0;
}

Tad kā mēs varētu izmantot šo "pārtraukšanos", lai pārslēgtos starp efektiem? Līdzīgi kā Piemērā 4 – pārtraukuma rezultātā mainīt kādu mainīgā (piem 'flag') vērtību, vēl piešķirt citam mainīgajam (piem 'buttonInterruptFlag') vertibu, kuru galvenajā cilpā to nemitīgi pārbaudīt, un balstoties uz mainiga ('flag') vertību  – pārslēgt efektu.

Piektais piemērs:
Piektajā piemērā tas viss ir izdarīts =] .

Nozpiežot pogu notiek pārtraukums, kura laikā izslēdzam visas diodes (lai  nepaliktu iepriekšējie dati), mainīgajam 'buttonInterruptFlag' piešķiram '1' un pārslēdazm par 1 mainīgā 'flag' vērtību (0-1-2-3-0-1-…).

Galvenajā cilpā izmantoju "switch()" funkciju, kas atkarībā no mainīgā 'flag', izpilda savu apakšfunkciju. Savu kārt apakšfunkcijas showSquence1(); (2,3 un4 arī) ir izveidotas 'while()' ciklā. Tas nepieciešams, lai varētu pārbaudīt, vai nav noticis pārtraukums ( vai 'buttonInterruptFlag' nav palicis par '1'). Ja tas ir noticis, cikls tiek pārtraukts, un mēs atgriežamies galvenajā cilpā – pie 'switch()' funkcijas, un balstoties uz jau izmainijušos 'flag' vērtību, ejam uz citu apakšfunkciju.

Vēl viena lieta – ja mēs izsaucam aiztures funkciju piem: '_delay_ms(1000)', veselu sekundi mums būs jāgaida, līdz varēsim 'izlekt' ārā no apakšfunkcijas 'showSequence1()' 'while()' cikla. Tādēļ izveidoju speciālu aiztures funkciju 'special_delay()', kura var tikt pārtraukta reizi milisekundē.

// Piemers 5
#include <avr/io.h>      // ieejas-izejas biblioteka
#include <avr/interrupt.h>      // partraukumu biblioteka
#include <util/delay.h>     // aiztures biblioteka
#include <avr/pgmspace.h>  // biblioteka tiesai datu piekluve "program memory"

volatile uint8_t  flag = 0;
volatile uint8_t  buttonInterruptFlag = 0;
volatile uint8_t  _index = 0;

uint8_t sequence1data[8] PROGMEM = {
 0b10000000,      //pirma sablona datu kopa PROGMEM atmina
 0b01000000,
 0b00100000,
 0b00010000,
 0b00001000,
 0b00000100,
 0b00000010,
 0b00000001    };

uint8_t sequence2data[2] PROGMEM = {
 0b11110000,      //otra sablona datu kopa PROGMEM atmina
 0b00001111    };

uint8_t sequence3data[16] PROGMEM = {
 0b00000001,      //tresa sablona datu kopa PROGMEM atmina
 0b00000011,
 0b00000111,
 0b00001111,
 0b00011111,
 0b00111111,
 0b01111111,
 0b11111111,
 0b11111110,
 0b11111100,
 0b11111000,
 0b11110000,
 0b11100000,
 0b11000000,
 0b10000000,
 0b00000000    };

uint8_t sequence4data[8] PROGMEM = {
 0b00011000,      //ceturta sablona datu kopa PROGMEM atmina
 0b00111100,
 0b01111110,
 0b11111111,
 0b11100111,
 0b11000011,
 0b10000001,
 0b00000000    };

ISR(INT0_vect) {  //leksim seit, ja konstatets partraukums uz PD2 (INT0)
 cli();    // izsledzam partraukumus, lai seit mus neviens nepartrauktu
 PORTB = 0b00000000;   // nodzesam visas diodes, pogas spiediena laika
 while(!(PIND & _BV(PD2))){    // gaidam, kamer poga tiks atlaista
  _delay_ms(30);   // 'debounce' pauzite
 }
 buttonInterruptFlag = 1;  // atzimejam, ka ir noticis partraukums, un ir japarsledz rezims
 flag++;        //palielinam mainigo par 1
 if(flag > 3){
  flag = 0;    // ja mainigais lielaks par 3 pieskiram tam veribu 0
 }    // mainiga veriba pec partraukumiem 1-0-1-0-utt.
 sei();    // iesledam partraukumus atpakal
} // pec izpildisanas lecam atpakal, kur partraucamies

void special_delay(uint16_t time_ms){// speciala pauze, kura tiek partraukta, ja noticis partraukums
 while((time_ms > 0) && (buttonInterruptFlag == 0)){  // kamer nav noticis partraukums un nav veikts 'time_ms'
  _delay_ms(1);                                    // rezes partraukums, turpinam 'cilpot' !
  time_ms--;   // pec katras cilpas samazinam cilpu skaititaju par 1
 }
}

void showSequence1(){
 _index = 8;  // cik efektam ir ierakstu
 while((_index > 0) && (buttonInterruptFlag == 0)){ // ja nav paradits viss efekts un nav partraukums, turpinam cilpot
  PORTB = pgm_read_byte(sequence1data + (8-_index));    // nolsam datus, kura adrese ir datuKopa + ierakstaNumurs
  special_delay(200);  // speciala pauze, kura tiek partraukta, ja mainiga noticis partraukums
  _index--;
 }
}

void showSequence2(){
 _index = 2;  // cik efektam ir ierakstu
 while((_index > 0) && (buttonInterruptFlag == 0)){ // ja nav paradits viss efekts un nav partraukums, turpinam cilpot
  PORTB = pgm_read_byte(sequence2data + (2-_index));    // nolsam datus, kura adrese ir datuKopa + ierakstaNumurs
  special_delay(700);  // speciala pauze, kura tiek partraukta, ja mainiga noticis partraukums
  _index--;
 }
}

void showSequence3(){
 _index = 16;  // cik efektam ir ierakstu
 while((_index > 0) && (buttonInterruptFlag == 0)){ // ja nav paradits viss efekts un nav partraukums, turpinam cilpot
  PORTB = pgm_read_byte(sequence3data + (16-_index));    // nolsam datus, kura adrese ir datuKopa + ierakstaNumurs
  special_delay(100);  // speciala pauze, kura tiek partraukta, ja mainiga noticis partraukums
  _index--;
 }
}

void showSequence4(){
 _index = 8;  // cik efektam ir ierakstu
 while((_index > 0) && (buttonInterruptFlag == 0)){ // ja nav paradits viss efekts un nav partraukums, turpinam cilpot
  PORTB = pgm_read_byte(sequence4data + (8-_index));    // nolsam datus, kura adrese ir datuKopa + ierakstaNumurs
  special_delay(500);  // speciala pauze, kura tiek partraukta, ja mainiga noticis partraukums
  _index--;
 }
}

void ioinit(){
 DDRB = 0b11111111;     // PORTB visas izejas (prieks diodem)
 DDRD = 0b11111011;    // PD2 ieeja (pogai)
 PORTD |= _BV(PD2);  // iesledzam "pullup" PD2 ieejai

//  Ja lietojat Atmega8, tad INT0 partraukumu konfigurejam sadi
  MCUCR = 0;    // partraukums uz INT0 un INT1 kajam pie nulles limena, un mes negulam
  GICR |= _BV(INT0);    // aktivizejam INT0 partraukumu

//  Ja lietojat Atmega48/88/168/328, tad INT0 partraukumu konfigurejam sadi
//  EICRA = 0;    // partraukums uz INT0 un INT1 kajam pie nulles limena
//  EIMSK |= _BV(INT0);    // aktivizejam INT0 partraukumu
 sei();    // iesledzam partraukumus
}

int main(void){
 ioinit();     // sagatavojam mikroprocesoru
 while(1){     // izpildit vienmer (bezgaliga cilpa)
  buttonInterruptFlag = 0;  // atzimejam, ka esam jau 'izlekusi' ara no efekta, lai tagad tur paliktu
  switch(flag){
   case 0: showSequence1(); break;
   case 1: showSequence2(); break;
   case 2: showSequence3(); break;
   case 3: showSequence4(); break;
   default: break;
  }
 }
 return 0;
}
Piemēra1 VIDEO
Piemēra2 VIDEO
Piemēra3 VIDEO
Piemēra4 VIDEO
Piemēra5 VIDEO

LEJUPIELĀDE:
Atmega-Blink-Int.zip – arhīvs ar visiem piemēriem (sākumkodu un '.hex' datnēm)
ATMEGA8 Datasheet – šeit var pasmelties, ko tad īsti mikrokontrolieris prot
Atmega168 Datasheet – un šeit

P.S.
Ja rodas jautājumi vai ierosinājumi – laipni lūgti! Tikai nesodiet bargi – pirmais raksts ;)


Aplūkot oriģinālo rakstu

Member

Maarchels

08:31 25.08.2011

ieraksti21
Rakstu skaits 3

2

Paldies par orgjinaalo rakstu un, ka PATS domaaji

Member

Anonymous

23:15 24.09.2011

ieraksti8
Rakstu skaits 0

3

Man izdevas gan salikt breadbordu gan ieprogrammet atmega8 MC  un  viss strada (  nemu piekto paraugu) 
un laikam 5 piemera C koda nav noradita procesora frekvence t.i. - #define F_CPU 1000000UL   :) 
Bet man rodas jautajums:

Ka iespejams izmainit to piemeram  " showSequence1 "  rindkopu ta lai var lietot nevis tikai portB kajinas diodem bet ari porC un portD

 

Sadi man izskatitos tas kajinu taka registrs kur iznemot PORTD 2  parejas ir izejas prieks diodem. 

DDRC = 0b0011111;
DDRB = 0b11111111;     // PORTB visas izejas (prieks diodem)
DDRD = 0b11111011;    // PD2 ieeja (pogai)
 
Uzrakstiet kaut vai piemeru lai  "showSequence1"  tagadeja vieta  iedektos vispirms visas portc diodes, piectam nodzistu tas un iedegtos portB un pectam nodzistu portB un iedegtos portD iznemot kajinu PORTD 2 jo tas ir sledzis. Cerku ka kads izpalidzes
 
 
Member

Mercury

19:54 26.09.2011

ieraksti4
Rakstu skaits 0

4

Lielisks raksts! Tieši šadus izskaidrotus piemerus meklēju, lai pats varetu iemacīties kodu rakstīt.

Member

KasparsL

10:45 27.09.2011

ieraksti23
Rakstu skaits 4

5

Ieraksts labots 10:47 – 27.09.2011 Labotājs – KasparsL


Anonymous teica:

Man izdevas gan salikt breadbordu gan ieprogrammet atmega8 MC  un  viss strada (  nemu piekto paraugu) 

un laikam 5 piemera C koda nav noradita procesora frekvence t.i. - #define F_CPU 1000000UL   :) 

Bet man rodas jautajums:

Ka iespejams izmainit to piemeram  " showSequence1 "  rindkopu ta lai var lietot nevis tikai portB kajinas diodem bet ari porC un portD

 

Sadi man izskatitos tas kajinu taka registrs kur iznemot PORTD 2  parejas ir izejas prieks diodem. 

DDRC = 0b0011111;
DDRB = 0b11111111;     // PORTB visas izejas (prieks diodem)
DDRD = 0b11111011;    // PD2 ieeja (pogai)
 

Uzrakstiet kaut vai piemeru lai  "showSequence1"  tagadeja vieta  iedektos vispirms visas portc diodes, piectam nodzistu tas un iedegtos portB un pectam nodzistu portB un iedegtos portD iznemot kajinu PORTD 2 jo tas ir sledzis. Cerku ka kads izpalidzes

 
 

 

#define F_CPU nav nekur definēts, jo nezinu kāds konkrētā gadījumā būs (internal 1Mhz vai 8Mhz, vai kāds cits external), katrs AVRstudio projakta parametros var ierakstīt kādu vajag =]

 

20 diodes – tāds neērts skaits 8bit mikrokontrolierim. Būtu ērti 8 – 16 – 24 – utt. Tad varētu veselu baitu pa tiešo sūtīt uz PORTx.

Bet izdarīt var.

Vienkāršākais – garākais:

  – karā solī piešķir katram portam vajadzīģās vērtības (PORTC = 0b0010000; PORTB = 0b01000000; PORTD = 0b00100000;),

  – uzraksti funkciju (piem void setOutputs(uint32_t outputData); ), kura vajadzīgos bitus 'sabīdīs' vajadzīgjās PORTx vietās Piem:

void setOutputs(uint32_t outputData){
	PORTC = (outputData & 0b0011111);
	PORTB = ((outputData >> 6) & 0xFF);
	PORTD = (((outputData >> 16) & 0x03) | ((outputData >> 15) & 0xF8));
}

 

  – var salikt vajadzīgās izejas vienā masīvā, un tad rakstīt datus tur (nevarēšu uzreiz paskaidrot, varbūt kāds cits var=] ).

Member

gipijs

23:05 16.12.2011

ieraksti3
Rakstu skaits 0

6

Raksts lielisks, bet ko darīt , ja es gribu pieslēgt vairāk LED'us un katru kontrolēt atsevišķi nekā mikrokontrolierim ir izejas?

Member

KasparsL

21:17 15.01.2012

ieraksti23
Rakstu skaits 4

7

gipijs teica:

Raksts lielisks, bet ko darīt , ja es gribu pieslēgt vairāk LED'us un katru kontrolēt atsevišķi nekā mikrokontrolierim ir izejas?


 

Tad jāņem palīgā serial uz parallel nobīdes reģistrus piemēram 74HC595 . Mikrokontrolierim izmantosies 3 kājas, un ar vienu 74HC595 dabūsi 8 izejas, ar divām 16, ar četrām 32, ar astoņām 64 utt. Tas viss joprojām izmantojot 3 mikrokontroliera izvadus. ierobežojošais faktors  – nepieciešamais izmaiņas ātrums ud izejām pret mikrokontroliera takts frekvenci.



Sākums | Visi Raksti | DIY Raksti | Pasākumi | Noteikumi | Forums
© 2010 Argus Radiodetaļu Tirdzniecība SIA | Web izstrāde Kārlis Baumanis