Uživatel:Vicarpet
Z MAM wiki
m (kategorie) |
|||
(Není zobrazeno 45 mezilehlých verzí.) | |||
Řádka 3: | Řádka 3: | ||
== vybrana semestralni prace: == | == vybrana semestralni prace: == | ||
- | |||
- | |||
'''Ovládání ventilátoru teplovzdušného rozvodu''' | '''Ovládání ventilátoru teplovzdušného rozvodu''' | ||
- | Myslenka: k mikroprocesoru pripojen dvojmistny sedmisegmentovy displey - zobrazuje stridave nastavenou teplotu vs. teplotu skutecnou pomoci dvou tlacitek regulace nastavene teploty vetrak spinan tranzistorem mereni teploty | + | Myslenka: k mikroprocesoru pripojen dvojmistny sedmisegmentovy displey - zobrazuje stridave nastavenou teplotu vs. teplotu skutecnou pomoci dvou tlacitek regulace nastavene teploty vetrak spinan tranzistorem mereni teploty LM35. |
- | + | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | -- | + | [http://xsimi.cz/kadibudka/mam-paty_nastrel.png schema] |
+ | [http://xsimi.cz/kadibudka/mam.sch zdrojak do Eagle] | ||
+ | [http://xsimi.cz/kadibudka/mam.pdf prezentace PDF] | ||
+ | [http://xsimi.cz/kadibudka/mam.odp prezentace ODP] - má to být na pár minut, tak myslím že to takhle stačí | ||
- | == | + | == Zakmity == |
- | + | Proste tlačítko neudelá normální prechod 0-1, ale párkrát zakmitá, takze se objevi cca neco takovýdleho ..01000110010001111111... | |
- | + | Vyresíme jednoduse, pokud prijde interup pockame cca 20ms a pak teprve prectem hodnotu, jde to resit i hw, ale tohle je jednodussí. | |
- | + | ||
- | + | --[[Uživatel:Zikmuji1|Jiří Zikmund]] 9. 5. 2010, 14:48 (UTC) | |
- | + | ||
- | + | ||
- | + | Obávám se, že nikdo nezaručí, že za 20ms tam bude určitě tutová 0. Co takhle to řešit prvním přečtením, pak 20ms počkat a znova přečíst, porovnat a když to bude stejný, tak je to OK a pokračujem dál? Ale to je jen takovej nápad. Jestliže bude vstupem třeba PD.2 viz schéma, zkusil bych jít třeba tudy: | |
- | + | ||
- | + | no zaruci, tak spatny tlacitka aby to kmitalo dele nez 20ms sem snad mit nebudeme :) | |
- | + | ||
- | + | ||
- | + | '''První nástřely tlačítek v C''' | |
- | + | ||
- | + | ||
- | + | - jsou to dvě tlačítka, jedno má teplotu o stupeň snížit a druhé zvýšit, | |
+ | porty jsou podle schématu | ||
+ | |||
+ | == Měření teploty == | ||
+ | |||
+ | Tady bych se přikláněl k měření přes A/D převodník s teploměrem [http://www.national.com/mpf/LM/LM35.html#Overview LM35] | ||
+ | |||
+ | Řeší problém kalibrace (vnitřní kompenzací teploty) sám o sobě (dokonce je kalibrován na °C, má velmi malou spotřebu, rozlišení 10mV/°C), tak uvidíme, jak se k tomu vyjádří případně vedoucí cvičení. Pouzdro asi ještě doladíme, zatím LM35DZ v [http://www.gme.cz/cz/lm35dz-p313-909.html TO-92] (pakliže nebude třeba měřit záporné teploty), vychází nejlevněji. | ||
+ | |||
+ | [[Uživatel:Zikmuji1|Jiří Zikmund]] 19. 4. 2010, 17:16 (UTC) | ||
+ | |||
+ | --[[Uživatel:Zikmuji1|Jiří Zikmund]] 9. 5. 2010, 14:48 (UTC) | ||
+ | |||
+ | Takže měření teploty... použijeme vnitřní 10-bitový A/D převodník s vnitřním referenčním napětím 1,1V, vstup ADC2, výstup PB2 | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | + | == Kód == | |
- | |||
<pre> | <pre> | ||
- | + | //------------------------------------------------------------------------------ | |
- | + | #include <avr/io.h> | |
- | + | #include <avr/interrupt.h> | |
- | + | #include <avr/pgmspace.h> | |
- | + | #include <avr/eeprom.h> | |
+ | #include <util/delay.h> | ||
- | + | #define xtal 1000000 //kmitocet krystalu 1MHz | |
- | + | #define TMR_CNT 65536 - 97 // cas / 1024 / 1000000, cas v sec, pro 0.1 sec | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | |||
- | + | //------------------------------------------------------------------------------ | |
- | + | unsigned char kteryudaj = 0;//stara se o vyber udaje co bude zobrazen (0..teplota) | |
+ | volatile int teplota = 20; // Zmerena teplota | ||
+ | volatile int Tnastavena = 20; //Nastavena teplota | ||
- | |||
- | - | + | void UpdateOutput(); |
- | + | //------------------------------------------------------------------------------ | |
+ | //zpusobi usnuti mikroprocesoru | ||
+ | void usni(void) | ||
+ | { | ||
+ | SMCR = 1; | ||
+ | } | ||
+ | //------------------------------------------------------------------------------ | ||
+ | //je zavolano pri stisku libovolneho tlacitka | ||
+ | void preruseni (void) | ||
+ | { | ||
+ | unsigned char portVal = PINC; | ||
- | + | do { | |
- | + | portVal = PINC & 0x30; | |
- | + | _delay_ms(20); | |
- | + | } while(portVal != (PINC & 0x30)); | |
+ | |||
+ | if((portVal & 0x30) == 0x20) | ||
+ | { | ||
+ | //prvni | ||
+ | Tnastavena++; | ||
+ | kteryudaj = 10; | ||
+ | } | ||
+ | if((portVal & 0x30) == 0x10) | ||
+ | { | ||
+ | //druhy | ||
+ | Tnastavena--; | ||
+ | kteryudaj = 10; | ||
+ | } | ||
+ | } | ||
- | |||
- | void | + | //------------------------------------------------------------------------------ |
+ | //hlavni cast, nastavy procesor a uspi ho | ||
+ | void ShowDisplay(unsigned char num) | ||
+ | { | ||
+ | PORTD = (PORTD & 0xF0) | (num / 10); | ||
+ | PORTC = PORTC | 0x02; | ||
+ | _delay_ms(1); | ||
+ | PORTC = PORTC & 0xFD; | ||
- | + | PORTD = (PORTD & 0xF0) | (num % 10); | |
+ | PORTC = PORTC | 0x08; | ||
+ | _delay_ms(1); | ||
+ | PORTC = PORTC & 0xF7; | ||
- | + | } | |
- | + | ||
- | + | //------------------------------------------------------------------------------ | |
+ | int PrectiAdc() | ||
+ | { | ||
+ | while((ADCSRA & (1 << ADIF)) == 0); | ||
+ | int iAdcValue = ADCW; | ||
+ | return((iAdcValue * 28) >> 8); | ||
+ | } | ||
- | + | //------------------------------------------------------------------------------ | |
+ | SIGNAL(PCINT1_vect) | ||
+ | { | ||
+ | preruseni(); | ||
+ | } | ||
- | + | //------------------------------------------------------------------------------ | |
- | + | SIGNAL(TIMER1_OVF_vect) | |
- | + | { | |
- | + | teplota = PrectiAdc(); | |
- | + | if(kteryudaj > 0) | |
- | + | { | |
- | + | ShowDisplay(Tnastavena); | |
- | + | kteryudaj--; | |
- | + | } | |
- | + | else | |
+ | ShowDisplay(teplota); | ||
+ | |||
+ | UpdateOutput(); | ||
- | + | TCNT1 = TMR_CNT; | |
+ | |||
+ | // uspani | ||
+ | usni(); | ||
+ | } | ||
- | == | + | //------------------------------------------------------------------------------ |
+ | void InitAdc() | ||
+ | { | ||
+ | ADMUX = (1 << REFS1) | (1 << REFS0) | 2; // Reference 1.1V, kanal ADC2 | ||
+ | ADCSRA = (1 << ADEN) | (1 << ADATE) | 7; // Povoleni ADC, preddelicka 128 | ||
+ | ADCSRB = 6; // start pri preteceni T1 | ||
+ | } | ||
- | |||
- | + | //------------------------------------------------------------------------------ | |
+ | void UpdateOutput() | ||
+ | { | ||
+ | if(teplota > Tnastavena) | ||
+ | PORTD = (PORTD & 0x7F) | 0x80; | ||
+ | if(teplota < Tnastavena - 10) | ||
+ | PORTD = PORTD & 0x7f; | ||
+ | } | ||
- | [[ | + | |
+ | |||
+ | //------------------------------------------------------------------------------ | ||
+ | //zakladni nastaveni portu | ||
+ | void InitPorts() | ||
+ | { | ||
+ | DDRD = 0x8F; | ||
+ | DDRC = 0x0A; | ||
+ | |||
+ | PCICR = 0x02; | ||
+ | PCMSK1 = 0x30; | ||
+ | } | ||
+ | //------------------------------------------------------------------------------ | ||
+ | |||
+ | void InitTimer1() | ||
+ | { | ||
+ | TCCR1A = 0; | ||
+ | TCCR1B = 5; // delicka 1024 | ||
+ | TCCR1C = 0; | ||
+ | TCNT1 = TMR_CNT; | ||
+ | TIMSK1 = 1; // povoleni preruseni od preteceni | ||
+ | } | ||
+ | |||
+ | //------------------------------------------------------------------------------ | ||
+ | int main() | ||
+ | { | ||
+ | InitPorts(); | ||
+ | InitAdc(); | ||
+ | InitTimer1(); | ||
+ | sei(); | ||
+ | |||
+ | |||
+ | while(1); //nekonecna smycka, aby neskoncil main | ||
+ | return (0); | ||
+ | } | ||
+ | //------------------------------------------------------------------------------ | ||
+ | </pre> | ||
+ | |||
+ | == Datasheets == | ||
+ | |||
+ | Teploměr LM-35 | ||
+ | BCD převodník HCF4056BE | ||
+ | Sedmisegmentovky HDSP-F203 | ||
+ | |||
+ | == Realizace == | ||
+ | [[Soubor:nastav_teplomer.jpg|600px]] | ||
== Tým == | == Tým == | ||
Řádka 150: | Řádka 222: | ||
Jachym Simak - simakjac@fel.cvut.cz | Jachym Simak - simakjac@fel.cvut.cz | ||
'''[[Uživatel:zikmuji1|Jiří Zikmund]]''' | '''[[Uživatel:zikmuji1|Jiří Zikmund]]''' | ||
+ | |||
+ | [[Category:Kód v C]] |
Aktuální verze z 21. 2. 2011, 09:33
petr vičar
Obsah |
[editovat] vybrana semestralni prace:
Ovládání ventilátoru teplovzdušného rozvodu
Myslenka: k mikroprocesoru pripojen dvojmistny sedmisegmentovy displey - zobrazuje stridave nastavenou teplotu vs. teplotu skutecnou pomoci dvou tlacitek regulace nastavene teploty vetrak spinan tranzistorem mereni teploty LM35.
schema zdrojak do Eagle prezentace PDF prezentace ODP - má to být na pár minut, tak myslím že to takhle stačí
[editovat] Zakmity
Proste tlačítko neudelá normální prechod 0-1, ale párkrát zakmitá, takze se objevi cca neco takovýdleho ..01000110010001111111... Vyresíme jednoduse, pokud prijde interup pockame cca 20ms a pak teprve prectem hodnotu, jde to resit i hw, ale tohle je jednodussí.
--Jiří Zikmund 9. 5. 2010, 14:48 (UTC)
Obávám se, že nikdo nezaručí, že za 20ms tam bude určitě tutová 0. Co takhle to řešit prvním přečtením, pak 20ms počkat a znova přečíst, porovnat a když to bude stejný, tak je to OK a pokračujem dál? Ale to je jen takovej nápad. Jestliže bude vstupem třeba PD.2 viz schéma, zkusil bych jít třeba tudy:
no zaruci, tak spatny tlacitka aby to kmitalo dele nez 20ms sem snad mit nebudeme :)
První nástřely tlačítek v C
- jsou to dvě tlačítka, jedno má teplotu o stupeň snížit a druhé zvýšit, porty jsou podle schématu
[editovat] Měření teploty
Tady bych se přikláněl k měření přes A/D převodník s teploměrem LM35
Řeší problém kalibrace (vnitřní kompenzací teploty) sám o sobě (dokonce je kalibrován na °C, má velmi malou spotřebu, rozlišení 10mV/°C), tak uvidíme, jak se k tomu vyjádří případně vedoucí cvičení. Pouzdro asi ještě doladíme, zatím LM35DZ v TO-92 (pakliže nebude třeba měřit záporné teploty), vychází nejlevněji.
Jiří Zikmund 19. 4. 2010, 17:16 (UTC)
--Jiří Zikmund 9. 5. 2010, 14:48 (UTC)
Takže měření teploty... použijeme vnitřní 10-bitový A/D převodník s vnitřním referenčním napětím 1,1V, vstup ADC2, výstup PB2
[editovat] Kód
//------------------------------------------------------------------------------ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/pgmspace.h> #include <avr/eeprom.h> #include <util/delay.h> #define xtal 1000000 //kmitocet krystalu 1MHz #define TMR_CNT 65536 - 97 // cas / 1024 / 1000000, cas v sec, pro 0.1 sec //------------------------------------------------------------------------------ unsigned char kteryudaj = 0;//stara se o vyber udaje co bude zobrazen (0..teplota) volatile int teplota = 20; // Zmerena teplota volatile int Tnastavena = 20; //Nastavena teplota void UpdateOutput(); //------------------------------------------------------------------------------ //zpusobi usnuti mikroprocesoru void usni(void) { SMCR = 1; } //------------------------------------------------------------------------------ //je zavolano pri stisku libovolneho tlacitka void preruseni (void) { unsigned char portVal = PINC; do { portVal = PINC & 0x30; _delay_ms(20); } while(portVal != (PINC & 0x30)); if((portVal & 0x30) == 0x20) { //prvni Tnastavena++; kteryudaj = 10; } if((portVal & 0x30) == 0x10) { //druhy Tnastavena--; kteryudaj = 10; } } //------------------------------------------------------------------------------ //hlavni cast, nastavy procesor a uspi ho void ShowDisplay(unsigned char num) { PORTD = (PORTD & 0xF0) | (num / 10); PORTC = PORTC | 0x02; _delay_ms(1); PORTC = PORTC & 0xFD; PORTD = (PORTD & 0xF0) | (num % 10); PORTC = PORTC | 0x08; _delay_ms(1); PORTC = PORTC & 0xF7; } //------------------------------------------------------------------------------ int PrectiAdc() { while((ADCSRA & (1 << ADIF)) == 0); int iAdcValue = ADCW; return((iAdcValue * 28) >> 8); } //------------------------------------------------------------------------------ SIGNAL(PCINT1_vect) { preruseni(); } //------------------------------------------------------------------------------ SIGNAL(TIMER1_OVF_vect) { teplota = PrectiAdc(); if(kteryudaj > 0) { ShowDisplay(Tnastavena); kteryudaj--; } else ShowDisplay(teplota); UpdateOutput(); TCNT1 = TMR_CNT; // uspani usni(); } //------------------------------------------------------------------------------ void InitAdc() { ADMUX = (1 << REFS1) | (1 << REFS0) | 2; // Reference 1.1V, kanal ADC2 ADCSRA = (1 << ADEN) | (1 << ADATE) | 7; // Povoleni ADC, preddelicka 128 ADCSRB = 6; // start pri preteceni T1 } //------------------------------------------------------------------------------ void UpdateOutput() { if(teplota > Tnastavena) PORTD = (PORTD & 0x7F) | 0x80; if(teplota < Tnastavena - 10) PORTD = PORTD & 0x7f; } //------------------------------------------------------------------------------ //zakladni nastaveni portu void InitPorts() { DDRD = 0x8F; DDRC = 0x0A; PCICR = 0x02; PCMSK1 = 0x30; } //------------------------------------------------------------------------------ void InitTimer1() { TCCR1A = 0; TCCR1B = 5; // delicka 1024 TCCR1C = 0; TCNT1 = TMR_CNT; TIMSK1 = 1; // povoleni preruseni od preteceni } //------------------------------------------------------------------------------ int main() { InitPorts(); InitAdc(); InitTimer1(); sei(); while(1); //nekonecna smycka, aby neskoncil main return (0); } //------------------------------------------------------------------------------
[editovat] Datasheets
Teploměr LM-35 BCD převodník HCF4056BE Sedmisegmentovky HDSP-F203
[editovat] Realizace
[editovat] Tým
Petr Vičar Jachym Simak - simakjac@fel.cvut.cz Jiří Zikmund