Difference between revisions of "U23 2008/Gruppe1"
(→Taster) |
|||
(29 intermediate revisions by 5 users not shown) | |||
Line 9: | Line 9: | ||
Für C verwendet man "c" und für assembler "asm".<br> | Für C verwendet man "c" und für assembler "asm".<br> | ||
== '''Mitglieder:''' == | == '''Mitglieder:''' == | ||
− | + | -shn<br/> | |
− | - | ||
-Maike<br/> | -Maike<br/> | ||
-skullbocks<br/> | -skullbocks<br/> | ||
Line 17: | Line 16: | ||
-Smasher (Brille und anthrazit-farbenes dell notebook ;) )<br/> | -Smasher (Brille und anthrazit-farbenes dell notebook ;) )<br/> | ||
+ | == '''Projekte:''' == | ||
− | ===Taster=== | + | |
+ | ===Sourcecode,Assembler LCD HD44780 kompatibel, 2x16 Zeichen @ 16Mhz (20Mhz funktioniert auch): === | ||
+ | <source lang="asm"> | ||
+ | |||
+ | ;*************************************************************************** | ||
+ | ;* W I C H T I G ! | ||
+ | ;* | ||
+ | ;* Das Programm wurde in AVR Studio unter Windows geschrieben. | ||
+ | ;* Es sind kleine Anpassungen notwendig um unter AVRGCC kompiliert zu werden | ||
+ | ;* Dies umfasst z.b. den Stackpointer ( lo8(RAMEND), hi8(RAMEND) ) | ||
+ | ;* sowie der tausch von .def in #define . #define ersetzt .equ ! | ||
+ | ;* Von Smasher | ||
+ | ;*************************************************************************** | ||
+ | |||
+ | .include "m168def.inc" | ||
+ | ;****************************** | ||
+ | ;LCD Pin Belegung | ||
+ | ;DB4-7 = PORT D. 0-3 | ||
+ | ;ENABLE=PORT D Pin 5 | ||
+ | ;RS= PORTD Pin 4 | ||
+ | |||
+ | .def temp = r16 | ||
+ | .def temp1=r20 | ||
+ | .equ enable=5 | ||
+ | .equ rs=4 | ||
+ | .equ LCD_PORT = PORTD | ||
+ | .equ LCD_DDR = DDRD | ||
+ | |||
+ | .org 0x0000 | ||
+ | rjmp main | ||
+ | |||
+ | main: | ||
+ | |||
+ | ldi temp, LOW(RAMEND) ; Stackpointer initialisieren | ||
+ | out SPL, temp | ||
+ | ldi temp, HIGH(RAMEND) | ||
+ | out SPH, temp | ||
+ | |||
+ | ldi temp,0xFF ; Port D als Ausgang | ||
+ | out LCD_DDR, temp | ||
+ | |||
+ | |||
+ | lcdinit: ldi temp, 0x00 | ||
+ | out LCD_PORT, temp | ||
+ | ;****************************************** | ||
+ | ; LCD mitteilen, dass im 4 Bit Modus gearbeitet wird | ||
+ | rcall delay15ms ;Hier mindestens 15ms warten! | ||
+ | rcall delay15ms ;Zur sicherheit! z.b. nach Stromeinschalten! | ||
+ | |||
+ | |||
+ | ldi temp, 0b00000011 | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | |||
+ | rcall delay4ms ;Mindestens 4,1ms warten! | ||
+ | |||
+ | ldi temp, 0b00000011 | ||
+ | out LCD_PORT,temp | ||
+ | rcall enable_routine | ||
+ | |||
+ | |||
+ | |||
+ | rcall short_delay ;Mindestens 100us warten! | ||
+ | rcall short_delay | ||
+ | |||
+ | ldi temp, 0b00000011 | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | |||
+ | |||
+ | ldi temp, 0b00000010 ;Hier wird letztendlich 4-Bit Modus eingeschaltet | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | rcall short_delay ;Hier zur sicherheit 60us zum abarbeiten | ||
+ | ;4 Bit Modus Mitteilung abgeschlossen | ||
+ | ; ******************************************* | ||
+ | |||
+ | |||
+ | ldi temp, 0b00000010 ;2 Zeilig 5x8 matrix | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | ldi temp,0b00001000 | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | |||
+ | rcall short_delay ;Kurze Wartezeit zum abarbeiten | ||
+ | rcall display_off | ||
+ | rcall clear_display | ||
+ | |||
+ | ldi temp, 0b00000000; Kursor nach rechts wandernd, kein display shift | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | ldi temp, 0b00000010 | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | rcall delay2ms | ||
+ | |||
+ | rcall display_on | ||
+ | ldi temp, 0b00000000 ; display ein, Cursor ein, Cursor Blinkend | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | ldi temp, 0b00001111 | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine ; ferig | ||
+ | |||
+ | ldi temp, 'H' | ||
+ | rcall lcd_print | ||
+ | ldi temp, 'a' | ||
+ | rcall lcd_print | ||
+ | |||
+ | ldi temp, 'l' | ||
+ | rcall lcd_print | ||
+ | ldi temp, 'l' | ||
+ | rcall lcd_print | ||
+ | |||
+ | ldi temp, 'o' | ||
+ | rcall lcd_print | ||
+ | ldi temp, ' ' | ||
+ | rcall lcd_print | ||
+ | |||
+ | ldi temp, 'W' | ||
+ | rcall lcd_print | ||
+ | ldi temp, 'e' | ||
+ | rcall lcd_print | ||
+ | |||
+ | ldi temp, 'l' | ||
+ | rcall lcd_print | ||
+ | ldi temp, 't' | ||
+ | rcall lcd_print | ||
+ | |||
+ | |||
+ | |||
+ | loop: | ||
+ | rjmp loop | ||
+ | lcd_print: mov temp1, temp | ||
+ | swap temp | ||
+ | andi temp, 0b00001111 | ||
+ | sbr temp, 1<<rs | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | |||
+ | andi temp1, 0b00001111 | ||
+ | sbr temp1, 1<<rs | ||
+ | out LCD_PORT, temp1 | ||
+ | rcall enable_routine | ||
+ | rcall short_delay | ||
+ | ret | ||
+ | |||
+ | display_on: | ||
+ | ldi temp, 0b00000000 | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | |||
+ | ldi temp,0b00001100 | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | rcall delay2ms | ||
+ | |||
+ | ret | ||
+ | |||
+ | display_off: | ||
+ | ldi temp, 0b00000000 | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | |||
+ | ldi temp, 0b00001000 | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | rcall delay2ms | ||
+ | |||
+ | ret | ||
+ | |||
+ | clear_display: | ||
+ | ldi temp, 0b00000000 | ||
+ | out LCD_PORT, temp | ||
+ | rcall enable_routine | ||
+ | |||
+ | ldi temp, 0b00000001 | ||
+ | out LCD_PORT,temp | ||
+ | rcall enable_routine | ||
+ | rcall delay2ms | ||
+ | |||
+ | ret | ||
+ | |||
+ | |||
+ | enable_routine: | ||
+ | |||
+ | |||
+ | |||
+ | rcall short_delay | ||
+ | sbi LCD_PORT,enable | ||
+ | rcall short_delay | ||
+ | cbi LCD_PORT, enable | ||
+ | rcall short_delay | ||
+ | |||
+ | ret | ||
+ | |||
+ | delay15ms: | ||
+ | |||
+ | ; ============================= | ||
+ | ; Warteschleifen-Generator | ||
+ | ; 340000 Zyklen: | ||
+ | ; ----------------------------- | ||
+ | ; warte 339999 Zyklen: | ||
+ | ldi R17, $0B | ||
+ | WGLOOP0: ldi R18, $33 | ||
+ | WGLOOP1: ldi R19, $C9 | ||
+ | WGLOOP2: dec R19 | ||
+ | brne WGLOOP2 | ||
+ | dec R18 | ||
+ | brne WGLOOP1 | ||
+ | dec R17 | ||
+ | brne WGLOOP0 | ||
+ | ; ----------------------------- | ||
+ | ; warte 1 Zyklus: | ||
+ | nop | ||
+ | ; ============================= | ||
+ | |||
+ | ret | ||
+ | |||
+ | delay4ms: | ||
+ | ; ============================= | ||
+ | ; Warteschleifen-Generator | ||
+ | ; 90000 Zyklen: ~4,7ms | ||
+ | ; ----------------------------- | ||
+ | ; warte 89997 Zyklen: | ||
+ | ldi R17, $83 | ||
+ | WALOOP0: ldi R18, $E4 | ||
+ | WALOOP1: dec R18 | ||
+ | brne WALOOP1 | ||
+ | dec R17 | ||
+ | brne WALOOP0 | ||
+ | ; ----------------------------- | ||
+ | ; warte 3 Zyklen: | ||
+ | ldi R17, $01 | ||
+ | WALOOP2: dec R17 | ||
+ | brne WALOOP2 | ||
+ | ; ============================= | ||
+ | ret | ||
+ | |||
+ | |||
+ | delay2ms: | ||
+ | ; ============================= | ||
+ | ; Warteschleifen-Generator | ||
+ | ; 48000 Zyklen: | ||
+ | ; ----------------------------- | ||
+ | ; warte 47988 Zyklen: | ||
+ | ldi R17, $56 | ||
+ | WCLOOP0: ldi R18, $B9 | ||
+ | WCLOOP1: dec R18 | ||
+ | brne WCLOOP1 | ||
+ | dec R17 | ||
+ | brne WCLOOP0 | ||
+ | ; ----------------------------- | ||
+ | ; warte 12 Zyklen: | ||
+ | ldi R17, $04 | ||
+ | WCLOOP2: dec R17 | ||
+ | brne WCLOOP2 | ||
+ | ; ============================= | ||
+ | |||
+ | ret | ||
+ | |||
+ | short_delay: | ||
+ | ; ============================= | ||
+ | ; Warteschleifen-Generator | ||
+ | ; 1000 Zyklen: ca. 60us laut oszi | ||
+ | ; | ||
+ | ; ----------------------------- | ||
+ | ; warte 999 Zyklen: | ||
+ | ldi R17, $03 | ||
+ | WDLOOP0: ldi R18, $6E | ||
+ | WDLOOP1: dec R18 | ||
+ | brne WDLOOP1 | ||
+ | dec R17 | ||
+ | brne WDLOOP0 | ||
+ | ; ----------------------------- | ||
+ | ; warte 1 Zyklus: | ||
+ | nop | ||
+ | ; ============================= | ||
+ | ret | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | </source> | ||
+ | |||
+ | ---- | ||
+ | ===Sourcecode, Taster 1 entprellen und Port D inkrementieren, funktioniert gut!: === | ||
+ | <source lang="c"> | ||
+ | //*********************************************************************************************************** | ||
+ | // * | ||
+ | // * Von smasher | ||
+ | // * | ||
+ | //*********************************************************************************************************** | ||
+ | |||
+ | // An das komplette PORTD habe ich LEDs aktiv High geschaltet (Also mit Anode an den Portpin), über | ||
+ | // Widerstand nach Masse. An Port C, Pin0 habe ich einen Taster, der aktiv low ist. | ||
+ | // Pullups werden an PortC Pin 0 aktiviert und im DDR auf Eingang gesetzt. | ||
+ | //Das Port D wird komplett als Ausgang gesetzt. | ||
+ | //Bei jedem Tastendruck wird nun status inkrementiert und auf den Leds kann man gut verfolgen, das jeweils //nur um eins erhöht wird. | ||
+ | //Bei weglassen von entprell(); und direktem aufrufen von lcd(); (in main) sieht man sofort, dass es zum | ||
+ | //prellen kommt und "wild" inkrementiert wird. Sprünge von 0 auf über 200 sind keine seltenheit! | ||
+ | //*********************************************************************************************************** | ||
+ | //* PAUSENZEITEN durch _delay_ms(x); | ||
+ | //* Ich würde sagen, dass man es damit nicht allzu genau nehmen darf. | ||
+ | //* Ich habe zwar noch kein Toggeln damit erzeugt und dann die frequenz mit einem oszi gemessen | ||
+ | //* (wodurch man //* dann auf die Pausenzeit kommt) | ||
+ | //* Aber ich denke dass die Funktion sehr ungenau arbeitet... | ||
+ | //* Darum funktionieren Pausenzeiten von 1ms nach aufruf von entprell genauso, wie 10ms. | ||
+ | //* Ebensogut kann es sein, dass mein Taster nur seeehr leicht Prellt und sich schnell "beruhigt"... | ||
+ | //* Also nur ein hypothetischer Ansatz... | ||
+ | //*********************************************************************************************************** | ||
+ | |||
+ | #include <avr/io.h> | ||
+ | #include <util/delay.h> | ||
+ | |||
+ | uint8_t status=0; | ||
+ | |||
+ | void led (void){ | ||
+ | status ++; | ||
+ | PORTD = status; | ||
+ | } | ||
+ | |||
+ | void entprell (void) { | ||
+ | _delay_ms(1); | ||
+ | if ( (PINC & _BV(PC0)) == 1 ) { | ||
+ | _delay_ms(5); | ||
+ | |||
+ | if ( (PINC & _BV(PC0)) == 1){ | ||
+ | led(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | int main(void) | ||
+ | { | ||
+ | DDRC &= ~( _BV(PC0) ); /* PIN PB0 auf Eingang (Taster) */ | ||
+ | PORTC |= _BV(PC0); /* Pullup-Widerstand aktivieren */ | ||
+ | DDRD =0xFF; | ||
+ | |||
+ | while(1) | ||
+ | { | ||
+ | if ( (PINC & _BV(PC0)) == 0 ) | ||
+ | { | ||
+ | entprell(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | == '''Projektabend 2:''' == | ||
+ | ===Sourcecode: === | ||
<source lang="c"> | <source lang="c"> | ||
+ | #include <avr/io.h> | ||
+ | #include <util/delay.h> | ||
+ | |||
+ | /* Funktionsweise: | ||
+ | * das Array 'reihe' gibt die Folge der Lampen an. | ||
+ | * Jede uint8_t Variable enthaelt in den letzten beiden Bits die Lampe (0==1. Lampe, 1==2. Lampe, usw.) | ||
+ | * und in den ersten sechs Bits die Zeit in Zehntelsekunden. Die Lampen werden hierbei nicht automatisch ausgeschaltet, | ||
+ | * jeder Aufruf der Funktion 'schritt' toggelt den Status der Lampe und wartet um die angegebene Zeit. | ||
+ | * | ||
+ | * Die drei Makros werden benutzt um das Array zu erzeugen und auf die Daten zuzugreifen. | ||
+ | */ | ||
+ | |||
+ | |||
+ | #define GET_LAMPE(tl) ( (tl) & 0b11 ) | ||
+ | #define GET_ZEIT(tl) ( (tl) >> 2 ) | ||
+ | #define GET_TL(l,t) ( ((t)<<2) | ((l)&0b11) ) | ||
+ | |||
+ | #define ENDE 0xFF | ||
+ | |||
+ | |||
+ | uint8_t reihe[] = { GET_TL(0,10), ENDE }; | ||
+ | |||
+ | void lampe(uint8_t); | ||
+ | void zehntelsekunde(uint8_t); | ||
+ | |||
+ | void main(void) { | ||
+ | //Lampenports als Ausgaenge konfigurieren | ||
+ | DDRC = _BV(PC4); | ||
+ | DDRD = _BV(PD3) | _BV(PD6) | _BV(PD7); | ||
+ | |||
+ | uint8_t l=1; //Laenge der Reihe | ||
+ | while (reihe[l] != ENDE) l++; | ||
+ | |||
+ | uint8_t i; | ||
+ | for (i = 0 ;i < l;i++) | ||
+ | { | ||
+ | lampe(GET_LAMPE(reihe[i])); | ||
+ | zehntelsekunde(GET_ZEIT(reihe[i])); | ||
+ | } | ||
+ | |||
+ | |||
+ | for ( ;; ) ; //Endlos... | ||
+ | |||
+ | } | ||
+ | |||
+ | //Lampe #l toggeln | ||
+ | void lampe(uint8_t l) | ||
+ | { | ||
+ | switch (l) | ||
+ | { | ||
+ | case 0: PORTC ^= _BV(PC4); | ||
+ | break; | ||
+ | case 1: PORTD ^= _BV(PD3); | ||
+ | break; | ||
+ | case 2: PORTD ^= _BV(PD6); | ||
+ | break; | ||
+ | case 3: PORTD ^= _BV(PD7); | ||
+ | break; | ||
+ | default: break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | //ca. 'f' Zehnelsekunden warten | ||
+ | void zehntelsekunde(uint8_t f) | ||
+ | { | ||
+ | uint8_t i; | ||
+ | for (i = 0; i < 8*f; i++) | ||
+ | _delay_loop_2(0); | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | ---- | ||
+ | ===Taster (entprell versuch)=== | ||
+ | <source lang="c"> | ||
+ | |||
+ | //CODE ANFANG | ||
+ | |||
#include <avr/io.h> | #include <avr/io.h> | ||
#include <util/delay.h> | #include <util/delay.h> | ||
Line 79: | Line 507: | ||
} | } | ||
}*/ | }*/ | ||
+ | |||
+ | //CODE ENDE! | ||
+ | |||
</source> | </source> | ||
− | === | + | == '''Projektabend 1:''' == |
− | + | ===Sourcecode: === | |
− | + | <source lang="c"> | |
− | + | //VERALTET! NEUE VERSION: WEITER OBEN, ABEND 2 | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
/*Dieses Programm lässt ein bestimmtes Muster auf unserem Testboard ablaufen*/ | /*Dieses Programm lässt ein bestimmtes Muster auf unserem Testboard ablaufen*/ | ||
Line 167: | Line 559: | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</source> | </source> |
Latest revision as of 19:24, 30 August 2008
Gruppe1
Hier eine Neuerung zum Einfügen von Sourcecode:
Bisher wurde der Code zerpflückt, wenn nicht vor jeder Zeile eine "Leertaste" stand.
Nun kann man per <source lang ="language"> HIER KOMMT DER CODE REIN!</source>
wunderbar der Code eingefügt werden und er wird, wie formatiert eingefügt, dargestellt!
Für C verwendet man "c" und für assembler "asm".
Mitglieder:
-shn
-Maike
-skullbocks
-Gesche
-Trella
-Smasher (Brille und anthrazit-farbenes dell notebook ;) )
Projekte:
Sourcecode,Assembler LCD HD44780 kompatibel, 2x16 Zeichen @ 16Mhz (20Mhz funktioniert auch):
<source lang="asm">
- W I C H T I G !
- Das Programm wurde in AVR Studio unter Windows geschrieben.
- Es sind kleine Anpassungen notwendig um unter AVRGCC kompiliert zu werden
- Dies umfasst z.b. den Stackpointer ( lo8(RAMEND), hi8(RAMEND) )
- sowie der tausch von .def in #define . #define ersetzt .equ !
- Von Smasher
.include "m168def.inc"
- LCD Pin Belegung
- DB4-7 = PORT D. 0-3
- ENABLE=PORT D Pin 5
- RS= PORTD Pin 4
.def temp = r16 .def temp1=r20 .equ enable=5 .equ rs=4 .equ LCD_PORT = PORTD .equ LCD_DDR = DDRD
.org 0x0000
rjmp main
main:
ldi temp, LOW(RAMEND) ; Stackpointer initialisieren out SPL, temp ldi temp, HIGH(RAMEND) out SPH, temp
ldi temp,0xFF ; Port D als Ausgang out LCD_DDR, temp
lcdinit: ldi temp, 0x00
out LCD_PORT, temp
- LCD mitteilen, dass im 4 Bit Modus gearbeitet wird
rcall delay15ms ;Hier mindestens 15ms warten! rcall delay15ms ;Zur sicherheit! z.b. nach Stromeinschalten!
ldi temp, 0b00000011
out LCD_PORT, temp rcall enable_routine
rcall delay4ms ;Mindestens 4,1ms warten!
ldi temp, 0b00000011 out LCD_PORT,temp rcall enable_routine
rcall short_delay ;Mindestens 100us warten! rcall short_delay
ldi temp, 0b00000011 out LCD_PORT, temp rcall enable_routine
ldi temp, 0b00000010 ;Hier wird letztendlich 4-Bit Modus eingeschaltet
out LCD_PORT, temp
rcall enable_routine
rcall short_delay ;Hier zur sicherheit 60us zum abarbeiten
- 4 Bit Modus Mitteilung abgeschlossen
- *******************************************
ldi temp, 0b00000010 ;2 Zeilig 5x8 matrix
out LCD_PORT, temp
rcall enable_routine
ldi temp,0b00001000
out LCD_PORT, temp
rcall enable_routine
rcall short_delay ;Kurze Wartezeit zum abarbeiten rcall display_off rcall clear_display
ldi temp, 0b00000000; Kursor nach rechts wandernd, kein display shift
out LCD_PORT, temp rcall enable_routine ldi temp, 0b00000010 out LCD_PORT, temp rcall enable_routine rcall delay2ms
rcall display_on
ldi temp, 0b00000000 ; display ein, Cursor ein, Cursor Blinkend
out LCD_PORT, temp rcall enable_routine ldi temp, 0b00001111 out LCD_PORT, temp rcall enable_routine ; ferig
ldi temp, 'H' rcall lcd_print ldi temp, 'a' rcall lcd_print
ldi temp, 'l' rcall lcd_print ldi temp, 'l' rcall lcd_print
ldi temp, 'o' rcall lcd_print ldi temp, ' ' rcall lcd_print
ldi temp, 'W' rcall lcd_print ldi temp, 'e' rcall lcd_print
ldi temp, 'l' rcall lcd_print ldi temp, 't' rcall lcd_print
loop: rjmp loop lcd_print: mov temp1, temp swap temp andi temp, 0b00001111 sbr temp, 1<<rs out LCD_PORT, temp rcall enable_routine
andi temp1, 0b00001111 sbr temp1, 1<<rs out LCD_PORT, temp1 rcall enable_routine rcall short_delay ret
display_on: ldi temp, 0b00000000 out LCD_PORT, temp rcall enable_routine
ldi temp,0b00001100 out LCD_PORT, temp rcall enable_routine rcall delay2ms
ret
display_off: ldi temp, 0b00000000 out LCD_PORT, temp rcall enable_routine
ldi temp, 0b00001000
out LCD_PORT, temp rcall enable_routine rcall delay2ms
ret
clear_display: ldi temp, 0b00000000 out LCD_PORT, temp rcall enable_routine
ldi temp, 0b00000001 out LCD_PORT,temp rcall enable_routine rcall delay2ms
ret
enable_routine:
rcall short_delay sbi LCD_PORT,enable rcall short_delay cbi LCD_PORT, enable rcall short_delay
ret
delay15ms:
- =============================
- Warteschleifen-Generator
- 340000 Zyklen
- -----------------------------
- warte 339999 Zyklen
ldi R17, $0B
WGLOOP0: ldi R18, $33 WGLOOP1: ldi R19, $C9 WGLOOP2: dec R19
brne WGLOOP2 dec R18 brne WGLOOP1 dec R17 brne WGLOOP0
- -----------------------------
- warte 1 Zyklus
nop
- =============================
ret
delay4ms:
- =============================
- Warteschleifen-Generator
- 90000 Zyklen
- ~4,7ms
- -----------------------------
- warte 89997 Zyklen
ldi R17, $83
WALOOP0: ldi R18, $E4 WALOOP1: dec R18
brne WALOOP1 dec R17 brne WALOOP0
- -----------------------------
- warte 3 Zyklen
ldi R17, $01
WALOOP2: dec R17
brne WALOOP2
- =============================
ret
delay2ms:
- =============================
- Warteschleifen-Generator
- 48000 Zyklen
- -----------------------------
- warte 47988 Zyklen
ldi R17, $56
WCLOOP0: ldi R18, $B9 WCLOOP1: dec R18
brne WCLOOP1 dec R17 brne WCLOOP0
- -----------------------------
- warte 12 Zyklen
ldi R17, $04
WCLOOP2: dec R17
brne WCLOOP2
- =============================
ret
short_delay:
- =============================
- Warteschleifen-Generator
- 1000 Zyklen
- ca. 60us laut oszi
- -----------------------------
- warte 999 Zyklen
ldi R17, $03
WDLOOP0: ldi R18, $6E WDLOOP1: dec R18
brne WDLOOP1 dec R17 brne WDLOOP0
- -----------------------------
- warte 1 Zyklus
nop
- =============================
ret
</source>
Sourcecode, Taster 1 entprellen und Port D inkrementieren, funktioniert gut!:
<source lang="c"> //*********************************************************************************************************** // * // * Von smasher // * //***********************************************************************************************************
// An das komplette PORTD habe ich LEDs aktiv High geschaltet (Also mit Anode an den Portpin), über // Widerstand nach Masse. An Port C, Pin0 habe ich einen Taster, der aktiv low ist. // Pullups werden an PortC Pin 0 aktiviert und im DDR auf Eingang gesetzt. //Das Port D wird komplett als Ausgang gesetzt. //Bei jedem Tastendruck wird nun status inkrementiert und auf den Leds kann man gut verfolgen, das jeweils //nur um eins erhöht wird. //Bei weglassen von entprell(); und direktem aufrufen von lcd(); (in main) sieht man sofort, dass es zum //prellen kommt und "wild" inkrementiert wird. Sprünge von 0 auf über 200 sind keine seltenheit! //*********************************************************************************************************** //* PAUSENZEITEN durch _delay_ms(x); //* Ich würde sagen, dass man es damit nicht allzu genau nehmen darf. //* Ich habe zwar noch kein Toggeln damit erzeugt und dann die frequenz mit einem oszi gemessen //* (wodurch man //* dann auf die Pausenzeit kommt) //* Aber ich denke dass die Funktion sehr ungenau arbeitet... //* Darum funktionieren Pausenzeiten von 1ms nach aufruf von entprell genauso, wie 10ms. //* Ebensogut kann es sein, dass mein Taster nur seeehr leicht Prellt und sich schnell "beruhigt"... //* Also nur ein hypothetischer Ansatz... //***********************************************************************************************************
- include <avr/io.h>
- include <util/delay.h>
uint8_t status=0;
void led (void){ status ++; PORTD = status; }
void entprell (void) {
_delay_ms(1);
if ( (PINC & _BV(PC0)) == 1 ) { _delay_ms(5);
if ( (PINC & _BV(PC0)) == 1){ led(); }
}
}
int main(void) {
DDRC &= ~( _BV(PC0) ); /* PIN PB0 auf Eingang (Taster) */ PORTC |= _BV(PC0); /* Pullup-Widerstand aktivieren */ DDRD =0xFF;
while(1) { if ( (PINC & _BV(PC0)) == 0 )
{
entprell(); } }
} </source>
Projektabend 2:
Sourcecode:
<source lang="c">
#include <avr/io.h>
- include <util/delay.h>
/* Funktionsweise:
* das Array 'reihe' gibt die Folge der Lampen an. * Jede uint8_t Variable enthaelt in den letzten beiden Bits die Lampe (0==1. Lampe, 1==2. Lampe, usw.) * und in den ersten sechs Bits die Zeit in Zehntelsekunden. Die Lampen werden hierbei nicht automatisch ausgeschaltet, * jeder Aufruf der Funktion 'schritt' toggelt den Status der Lampe und wartet um die angegebene Zeit. * * Die drei Makros werden benutzt um das Array zu erzeugen und auf die Daten zuzugreifen. */
- define GET_LAMPE(tl) ( (tl) & 0b11 )
- define GET_ZEIT(tl) ( (tl) >> 2 )
- define GET_TL(l,t) ( ((t)<<2) | ((l)&0b11) )
- define ENDE 0xFF
uint8_t reihe[] = { GET_TL(0,10), ENDE };
void lampe(uint8_t); void zehntelsekunde(uint8_t);
void main(void) { //Lampenports als Ausgaenge konfigurieren DDRC = _BV(PC4); DDRD = _BV(PD3) | _BV(PD6) | _BV(PD7);
uint8_t l=1; //Laenge der Reihe while (reihe[l] != ENDE) l++;
uint8_t i; for (i = 0 ;i < l;i++) { lampe(GET_LAMPE(reihe[i])); zehntelsekunde(GET_ZEIT(reihe[i])); }
for ( ;; ) ; //Endlos...
}
//Lampe #l toggeln void lampe(uint8_t l) { switch (l) { case 0: PORTC ^= _BV(PC4); break; case 1: PORTD ^= _BV(PD3); break; case 2: PORTD ^= _BV(PD6); break; case 3: PORTD ^= _BV(PD7); break; default: break; } }
//ca. 'f' Zehnelsekunden warten void zehntelsekunde(uint8_t f) { uint8_t i; for (i = 0; i < 8*f; i++) _delay_loop_2(0); } </source>
Taster (entprell versuch)
<source lang="c">
//CODE ANFANG
#include <avr/io.h> #include <util/delay.h> uint8_t zeit; uint8_t richtung; uint8_t anaus; uint8_t t0, temp0; /*void lauflicht(void) { }*/ void main(void) { DDRC &= ~(_BV(PC0)|_BV(PC1)|_BV(PC2)|_BV(PC3)); //Schalter DDRC &= _BV(PC4); //Lampe4 DDRD &= _BV(PD3) | _BV(PD6) | _BV(PD7); //Lampe 1-3 PORTC = _BV(PC0)|_BV(PC1)|_BV(PC2)|_BV(PC3); //Pullups t0= 0; anaus = 0x00; //0x00 = aus; 0xff = an _delay_loop_2(0); //Kurz warten, bis pullups ready while(1){ temp0 = PINC & _BV(PC0); _delay_loop_2(0); if((PINC & _BV(PC0)) == temp0){
t0 = temp0;
} if (t0 == 0)
PORTD = 128; else PORTD = 0;
}
}
/*if( (PINC & _BV(PC0)) == 0){
_delay_loop_2(0);
if( (PINC & _BV(PC0)) == 0 ){
//anaus != anaus;
PORTD = 0xff;
}
}*/
//CODE ENDE!
</source>
Projektabend 1:
Sourcecode:
<source lang="c"> //VERALTET! NEUE VERSION: WEITER OBEN, ABEND 2
/*Dieses Programm lässt ein bestimmtes Muster auf unserem Testboard ablaufen*/
#include <avr/io.h> #include <util/delay.h> void lampe(uint8_t l) { switch (l) { case 0: PORTC ^= _BV(PC4); break; case 1: PORTD ^= _BV(PD3); break; case 2: PORTD ^= _BV(PD6); break; case 3: PORTD ^= _BV(PD7); break; default: break; } } void main(void) { /* config PD7 as output */ DDRC = _BV(PC4); DDRD = _BV(PD3) | _BV(PD6) | _BV(PD7); uint8_t ls[] = {0, 1, 0, 2, 1, 3, 2, 1, 3}; uint8_t p=0; while(1) { //PORTD ^= _BV(PD7); uint8_t i; lampe(ls[p]); p++; for (i = 0; i < 76; i++) { /* wait 4 * 65536 cycles */ _delay_loop_2(0); } } for ( ;; ) ; }
</source>