Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| pic_12f629_led_blinken [2014/07/16 18:22] – [PIC12F629 LED blinken] dokuwikiadmin | pic_12f629_led_blinken [2015/01/12 08:24] (aktuell) – [relocatable code] dokuwikiadmin | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| - | Zum erstellen | + | Zum Erstellen |
| - | Mit der MPLAB X IDE installiert sich auch die MPLAB X IPE Applikation, | + | Mit der **MPLAB X IDE** installiert sich auch die **MPLAB X IPE** Applikation, |
| ====== PIC12F629 LED blinken ====== | ====== PIC12F629 LED blinken ====== | ||
| - | Im folgenden ein ganz einfaches Beispiel für die Verwendung eines PIC12F629. | + | |
| + | Im folgenden ein ganz einfaches Beispiel für die Verwendung eines PIC12F629. | ||
| + | Am PIN 7 (GP0) wird eine LED angehängt. | ||
| + | PIN 8 (GND) wird mit Masse (= minuspol des Netzgerätes) | ||
| {{: | {{: | ||
| - | Hier nun das C-Programm: | + | ===== Programmierung in C ===== |
| <code c> | <code c> | ||
| Zeile 23: | Zeile 26: | ||
| #pragma config WDTE = OFF, PWRTE = ON, CP = OFF, BOREN = OFF, MCLRE = OFF, CPD = OFF, FOSC = INTRCCLK | #pragma config WDTE = OFF, PWRTE = ON, CP = OFF, BOREN = OFF, MCLRE = OFF, CPD = OFF, FOSC = INTRCCLK | ||
| - | |||
| - | /* | ||
| - | * | ||
| - | */ | ||
| void main() | void main() | ||
| Zeile 46: | Zeile 45: | ||
| </ | </ | ||
| + | |||
| + | ===== Programmierung in Assembler ===== | ||
| + | |||
| + | Bei der Programmierung in Assembler gibt es zwei Möglichkeiten: | ||
| + | |||
| + | ==== absolute code ==== | ||
| + | |||
| + | Dies bedeutet, dass man beim Codieren die Speicheraddressen selber festlegt. Dies sieht etwa so aus: | ||
| + | |||
| + | <code asm> | ||
| + | myVar equ 0x20 ; myVar zeigt auf Speicheraddresse 0x20 | ||
| + | |||
| + | org 0x0000 ; ab hier code | ||
| + | |||
| + | main | ||
| + | ; machwas | ||
| + | end | ||
| + | </ | ||
| + | |||
| + | |||
| + | Bei Verwendung der MPLAB X IDE allerdings sieht man im Debug-Modus diese Variablen nicht, | ||
| + | das dürfte auch daran liegen, dass MLINK für die Erstellung des Maschinencodes verwendet wird. | ||
| + | |||
| + | ==== relocatable code ==== | ||
| + | |||
| + | In diesem Fall übernimmt die Arbeit der Speicherzuordnung von Variablen etc. der Linker. | ||
| + | |||
| + | <code asm> | ||
| + | | ||
| + | myVar res 1 ; reserviere 1 Byte für myVar | ||
| + | |||
| + | RESET CODE 0x000 ; ab hier code | ||
| + | |||
| + | main | ||
| + | ;machwas | ||
| + | end | ||
| + | </ | ||
| + | |||
| + | Vorteil dieser Methode ist, dass sich dieser Code dann besser in der MPLAB X IDE debuggen lässt, da man jetzt alle Variablen sieht. | ||
| + | |||
| + | === LED blinken, interner Timer === | ||
| + | |||
| + | Einer der Vorteile des C Programmiersprache sind die vielen fertigen Libraries die Funktionen wie zb. _delay_ms() zur Verfügung stellen. Für das Abwarten des Zeitraumes X in Assembler muss man selber geeignete Routinen implementieren. Dies kann im einfachsten Fall eine Schleife sein, die x-mal NOP (= no operation) ausführt. | ||
| + | |||
| + | Im folgenden Beispiel wird der TIMER0 des PIC Prozessors verwendet. Der PIC12F629 läuft mit 4 MHz. Der Timer wird über den Prescaler an den internen Takt angeschlossen. Der TIMER0 ist limitiert auf 8 bit und zählt daher nur bis max. 255. Eine weitere Einschränkung ist, dass der Timer auf 1/4 der Taktfrequenz limitiert ist d.h. dieser läuft nur mit 1 MHz. Wenn man den Prescaler auf das Verhältnis 1:32 setzt, bedeutet dies dass der Timer0 alle 32 µs einen Impuls/Tick erhält und um eins hochgezählt wird. Ein Wert von 250 im TIMER0 entspricht dann etwa 8 ms. | ||
| + | |||
| + | <code asm> | ||
| + | ; | ||
| + | ;22.07.2014 Stelzl Marius | ||
| + | ;translate from C to ASM | ||
| + | list P=12F629 | ||
| + | include " | ||
| + | |||
| + | ;#pragma config WDTE = OFF, PWRTE = ON, CP = OFF, BOREN = OFF, | ||
| + | ; MCLRE = OFF, CPD = OFF, FOSC = INTRCCLK | ||
| + | __config _WDTE_OFF & _PWRTE_ON & _CP_OFF & _BOREN_OFF & | ||
| + | | ||
| + | |||
| + | ;variable definition | ||
| + | ; | ||
| + | UDATA_SHR | ||
| + | counter1 res 1 ;reserve one byte for counter1 variable | ||
| + | counter2 res 1 ;wait counter | ||
| + | |||
| + | ; | ||
| + | ;code starts here | ||
| + | RESET CODE 0x000 | ||
| + | |||
| + | goto main | ||
| + | |||
| + | ; | ||
| + | ;init subroutine | ||
| + | init | ||
| + | bcf STATUS, | ||
| + | clrf GPIO ;GPIO = 0; | ||
| + | |||
| + | movlw 0xFF ; | ||
| + | movwf CMCON ;set all GPIO to digital IO | ||
| + | |||
| + | bsf STATUS, | ||
| + | |||
| + | ;setting TRISIO bit | ||
| + | ; 1 ... PIN is input | ||
| + | ; 0 ... PIN is output | ||
| + | movlw 0xFE ;0xFE = 254 = 0b11111110 | ||
| + | movwf TRISIO | ||
| + | |||
| + | ; OPTION register is also on bank1 | ||
| + | ; setup for usage of Timer0 with prescale 1:32 | ||
| + | movlw b' | ||
| + | movwf OPTION_REG | ||
| + | |||
| + | return | ||
| + | | ||
| + | ; | ||
| + | ;wait routine | ||
| + | wait_500 | ||
| + | clrf counter2 | ||
| + | waitls | ||
| + | | ||
| + | w_tmr0 | ||
| + | xorlw .250 ;250 ticks x 32 us/tick = 8ms | ||
| + | btfss STATUS,Z | ||
| + | goto w_tmr0 | ||
| + | |||
| + | incf counter2,1 | ||
| + | movlw .63 ;passed 62 * 8 ms = 500 ms ? | ||
| + | xorwf counter2,0 | ||
| + | btfss STATUS,Z | ||
| + | goto waitls | ||
| + | |||
| + | return | ||
| + | |||
| + | ; | ||
| + | ;our processing starts here | ||
| + | main | ||
| + | clrf counter1 | ||
| + | movlw 0x2 | ||
| + | movwf counter1 | ||
| + | loop | ||
| + | decfsz counter1,1 ;we call the init subproc only once | ||
| + | call init | ||
| + | |||
| + | bcf STATUS, | ||
| + | bsf GPIO, | ||
| + | |||
| + | ;wait 500 ms | ||
| + | call wait_500 | ||
| + | ;now switch off LED | ||
| + | bcf GPIO, | ||
| + | call wait_500 | ||
| + | |||
| + | goto loop ;endless loop, run forever | ||
| + | |||
| + | end | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | |||