Zum Erstellen von Programmen für den PIC12F629 (und auch diverse andere Mikroprozessoren) verwendet man am besten die MPLAB X IDE (http://www.microchip.com/). Für die C Programmiersprache muss man noch den XC8 (für 8 bit prozessoren) Compiler installieren. Mit der **MPLAB X IDE** installiert sich auch die **MPLAB X IPE** Applikation, mit der man fertige HEX Dateien auch ohne IDE auf den Mikroprozessor brennen kann. ====== PIC12F629 LED blinken ====== 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) verbunden und an PIN 1 (VDD) werden die 3V Gleichspannung angelegt. {{:img_20140716_133105_nopm_.jpg?200|}} ===== Programmierung in C ===== #include #include #include #define _XTAL_FREQ 4000000 // Oscillator frequency for _delay() #define __delay_ms(x) _delay((unsigned long) ((x)*(_XTAL_FREQ/4000.0))) //Config: int reset, no code protect, no brownout detect, no watchdog, // power-up timer enabled, 4MHz internal clock #pragma config WDTE = OFF, PWRTE = ON, CP = OFF, BOREN = OFF, MCLRE = OFF, CPD = OFF, FOSC = INTRCCLK void main() { GPIO = 0; CMCON = 0b11111111; TRISIO = 0b11111110; //output to GP0 GPIObits.GP0 = 1; for(;;) { GPIObits.GP0 = 1; __delay_ms(200); GPIObits.GP0 = 0; __delay_ms(200); } } ===== 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: 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. UDATA_SHR ; UDATA alleine führt zu einem Linker error 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. ;--------------------------------------------------------- ;22.07.2014 Stelzl Marius ;translate from C to ASM list P=12F629 ; Prozessor definieren include "P12F629.inc" ; entsprechende .inc Datei für MPASM ;#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 & _MCLRE_OFF & _CPD_OFF & _FOSC_INTRCCLK ;variable definition ;relocatable, use udata_shr 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,RP0 ;select bank 0 clrf GPIO ;GPIO = 0; movlw 0xFF ;CMCON = 0b1111111; movwf CMCON ;set all GPIO to digital IO bsf STATUS,RP0 ;select bank1 ;setting TRISIO bit ; 1 ... PIN is input ; 0 ... PIN is output movlw 0xFE ;0xFE = 254 = 0b11111110 movwf TRISIO ;TRISIO = 0b1111110; //output to GP0 ; OPTION register is also on bank1 ; setup for usage of Timer0 with prescale 1:32 movlw b'11010100' movwf OPTION_REG return ;-------------------------------------------- ;wait routine wait_500 clrf counter2 waitls clrf TMR0 w_tmr0 movf TMR0,w 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,RP0 ;select bank 0 for writing to GPIO bsf GPIO,0 ;set bit 0 of GPIO register to 1 => GPIObits.GP0 = 1; ;wait 500 ms call wait_500 ;now switch off LED bcf GPIO,0 ;clear bit 0 of GPIO register call wait_500 goto loop ;endless loop, run forever end