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 | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||