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