Egyik barátomat, most őrjítem be éppen az AVR-ekre. Nagyon tetszik neki, a kezdethez képest, már határozott a javulás, és pozitív a tendencia is.
Mikor úgy gondoltam, hogy ideje komolyabb feladatot is "adni", rábíztam, hogy elkészítse a következő áramkört. Ezen az oldalon, az Ő leírását, és szoftverét találod.
Beköszöntött a tél. Íme, egy kapcsolás, ami segítségével megnézhetjük, hogy hány fok van a műhelyünkben:
A hőmérsékletmérést egy NTC végzi, mely karakterisztikája a mi mérési tartományunkban szinte lineáris, így egy feszültségosztóba építve már mérhetjük is a rajta eső feszültséget, mikrokontrollerünk A/D konverterének segítségével. Fontos, hogy a potmétert első használat esetén úgy állítsuk be, hogy az adott hőmérsékletnél a kijelzőn is ennek megfelelő érték jelenjen meg. A potméter egyik lábát egy ellenálláson keresztül kötöm a földre biztonsági okokból. A kijelzésről 2db 10-es LED BAR gondoskodik, ami a két soros latch kimenetére van kötve. A latcheket szoftveres "SPI" buszon tápláljuk adattal.
A kapcsoláson látható, hogy az output enable (/OE) a földön van. Nem szükséges processzorral kapcsolgatni, hisz soha nincs Tri-state-ben a latch, a kimenet mindig össze van kötve a LED-ekkel. A két latch sorba van kötve, tehát tetszés szerint bővíthetjük kapcsolásunkat további latchel (kaszkádolás). Ez hasznos lehet, ha spórolnunk kell processzorunk lábaival.
Következzék a forráskód, amiben használjuk a már korábbról jól ismert A/D konvertert. Letöltés: homero.zip
#include <avr/io.h>
#include "m_delay_10ms.h"
#include "spiout.h"
#include "admeasure.h"
//-------------------------------------
void Init() {
//-------------------------------------
DDRB = 0b11111011; //ADC PB2 bemenet, tobbi kimenet!
DIDR0 |= (1<<ADC1D); // ADC1D enable
}
//-------------------------------------
unsigned short CreateBar(unsigned char v) {
//-------------------------------------
unsigned char i;
unsigned short val;
val = 0;
for(i=0;i<v;i++) {
val |= 1;
val <<= 1;
}
return val;
}
//-------------------------------------
int main(void) {
//-------------------------------------
unsigned long adc = 0;
unsigned short tmp = 0;
Init();
ADInit();
for(;;) { //végtelen ciklus
SPIReset();
adc = MeasureADC(1); //mérés ADC1-en
if(adc>=512) {
adc -= 512;
}
else {
adc = 0;
}
tmp = CreateBar(adc/32); // 512/32 => 16 szegmens
SPIOut(tmp>>8);
SPIOut(tmp);
LatchOut();
m_delay_10ms(2);
}
}
A forráskódban 3 saját headert használtam, ezzel is átláthatóbbá téve a kódot.
A program az initek után 3 folyamatból áll:
1. Az analóg digitál mérésnél értékkel töltünk fel egy 2 bájtos változót.
Ha jobban megvizsgáljuk az ADCInitet láthatjuk, hogy a tápfeszültséget vesszük referencia feszültségként, ezáltal is szabaddá téve egy lábat. Látható még, hogy teljes tápfeszültség esetén a változónk 1024-es értéket fog felvenni, fél tápfeszültség esetén 512-t.
2. A kapott változó tartalma még nem elégséges, hiszen ezt kiírva a latch-ekre, csak bináris számokat látnánk, ezért ezt még át kell alakítanunk olyan értékké amit kiküldve sorba tölti fel a LED BAR-unkat. Erre hivatott a CreateBar függvény, ami egyszerű shift műveletekből áll, és ennek visszatérési értéke már az amit kapni szeretnénk.
3. Ezt az adatot küldjük ki a software-s SPI buszunkon két részletbe, ugye a két latch miatt (először a felső 8, majd az alsó 8 bit).
Az spiout.h több függvényt is tartalmaz, ajánlom használatát mindenkinek, hiszen csak a #define-okban a megfelelő lábra kell állítani, és máris használható rengeteg AVR esetén.
Fontos, hogy mielőtt új adatot küldenénk a regiszterünknek reseteljük a regiszterét.
Miután kiküldtük SPIOut()-unk segítségével a változónk értékét még nem jelenik meg a latch kimenetén, hisz még csak a regisztereinkben várakozik az adat. Ezért szükséges meghívnunk az LatchOut() függvényünket.
Remélem, elnyeri tetszésedet a kapcsolás! Sikeres utánépítést kívánok! Ha bármi kérdés van, nyugodtan keress meg, igyekszem segíteni.
ZsírosDani
A cikk még nem ért véget, lapozz!
Értékeléshez bejelentkezés szükséges!