Pic från början

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
frejo
Inlägg: 496
Blev medlem: 21 april 2004, 21:43:01
Ort: Linköping

Pic från början

Inlägg av frejo »

Tja
Jag har tidigare bara jobbat med AVR och lite Motorola. Men nu när vi ska använda oss av PIC18 i kursen Mikrodatorer tänkte jag att det var lika bra att få igång lite hemma också som man kan sitta och "leka" med ;-)

Precis innan helgen fick jag mitt "startpaket" från Sodjan, ägnade sedan lördagen åt att löda och svära över att min kod inte fungerade direkt, men det gick bra tillslut.

Jag tänkte att man kanske skulle ta och skriva om allting här, från allra första början så andra kan lära av mina misstag ;) eller kanske bara få lite hjälp att komma igång.
Kommer posta kod här vartefter jag lär mig nya grejer.

Tänkte börja med lite bilder:

Först innehållet i paketet:
Bild
Större bild

Wisp628-kit:
Bild
Större bild

Jaha, det var det. Sen var det bara att värma upp lödkolven:
Bild
Större bild

Bild
Större bild

Lödningen gick rätt smärtfritt och ivrig som man är valde jag att ta ett befintligt nättagg istället för labbplattenätagget som följde med som kit, verkar dock väldigt smidigt med den så jag löder ihop den nån annan dag.

Uppkoppling:
Bild
Större bild

Nästa steg var att ladda ner XWisp2, i mitt fall installerade jag det under d:\Xwisp2 då jag inte gillar att lägga allt som behöver finnas i "path" i windowskatalogen. Gick istället in under kontrolpanelen/system/ och letade mig fram till "miljövariabler" och i "path" la jag till "d:\XWisp2", på detta sätt kan jag anropa det direkt från den katalog jag har koden i.

Då var det dags för det första programmet, jag valde det färdiga blink-a-led-programmet som går att hitta här:
http://www.voti.nl/blink/index.html
Det fungerade alldeles utmärkt. Den vänstra dioden på bilden ovan blinkade så fint 8)

Sen var det dags att skriva egen kod, det gick mindre bra. Kom efter några timmars svordomar fram till att kristallen svängde med blink-a-led men inte med min egen kod så felet måste ligga i konfigurationsbitarna, inge problem tänkte jag, bara att gå in under "configuration bits" i mplab... men icke sa nicke, det fungerade inte alls.

Fick sen veta att det gick att ställa in dessa från själva koden och vips så fungerade allting =)

Mitt första program:

Kod: Markera allt

;=========================================================
; 2005-09-10
; Fredrik Johansson
; Simple led-blinker
;=========================================================

	list p=18f452
	include "p18f452.inc"

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;     CONFIG settings (copied from P18F452.INC)
	config OSC = HS
	config OSCS = OFF
	config PWRT = ON
	config BOR = OFF
	config WDT = OFF
	config CCP2MUX = OFF
	config STVR = OFF
	config LVP = OFF
	config DEBUG = OFF
	config CP0 = OFF
	config CP1 = OFF
	config CP2 = OFF
	config CP3 = OFF
	config CPB = OFF
	config CPD = OFF
	config WRT0 = OFF
	config WRT1 = OFF
	config WRT2 = OFF
	config WRT3 = OFF
	config WRTB = OFF
	config WRTC = OFF
	config WRTD = OFF
	config EBTR0 = OFF
	config EBTR1 = OFF
	config EBTR2 = OFF
	config EBTR3 = OFF
	config EBTRB = OFF
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;    Variables. We put them in the access bank...
vars		UDATA_ACS
delayH		RES   1
delayL		RES   1
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	
Boot	CODE	h'0000'
	goto	Start

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                   

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Main	CODE     

Start
	bcf		TRISC,RC0		; PORTC, PIN 0 as output
	bcf		PORTC,RC0		; initiate output value to 0

main
	call	Delay
	comf 	PORTC,F		; invert all signals on PORTC
	goto 	main

Delay
	movlw	d'255'			; initiate delay values
	movwf	delayL			
	movlw	d'255'
	movwf	delayH			
count
	decfsz	delayL
	goto 	count			; continue counting until delayL = 0
	movlw	d'255'
	movwf	delayL			; reset value of delayL
	decfsz	delayH			; decrease delayH one step and go back 
	goto	count			; to decrease delayL once again
	return					; we have counted delayL*delayH times
	end
Observera att programmet är skrivet i relocate-mode, för att det ska kunna kompileras måste 18f452.lkr läggas till under linker-scrips i projektet i mplab, filen går att hitta i mplab-katalogen. Det använder dessutom PORTC, därav den högra dioden på uppkopplingen. PORTA ville inte fungera, vet inte om jag missat något register :oops:

Tack till Sodjan som hjälpte mig komma igång och visade på hur man kodar på ett "snyggt" sätt ;-)

Nästa grej blir att koda blink-programmet med en timer och interrupts.
Senast redigerad av frejo 14 mars 2006, 07:29:18, redigerad totalt 1 gång.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43205
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

Hm, jag hoppas att det är OK att kommentera lite... :-)

Som alternativ till att lägga in pathen till XWisp2 i PATH, så brukar jag skapa en BAT fil i projektkatalogen (FLASH.BAT), där jag lägger XWisp2 kommandot, och då är det lika enkelt att lägga pathen direkt i kommandot. Sedan brukar jag lägga en "shortcut" på skrivbordet, så att jag kan dubbelklicka direkt på den, eller ha ett öppen CMD fönster där jag kan göra "upp-pil" och ENTER (tyvärr saknar MPLAB möjlighet att definiera egna "knappar" som kör t.ex DOS kommandon, annars skulle man naurligtsvis lägga det där...).


Angående koden, CONFIG prylarna kan skrivas lite mer kompakt :

config OSC = HS, OSCS = OFF, PWRT = ON, BOR = OFF
config WDT = OFF, CCP2MUX = OFF, STVR = OFF

o.s.v.

Om man ofta kör med vissa standard inställningar, så kan de ju även läggas i en separat fil och läggas in med #include, för lite "renare" kod.


Delayen kan göras lite mer kompakt :

Kod: Markera allt

Delay
   decfsz   delayL
   goto    delay         ; continue counting until delayL = 0
   decfsz   delayH         ; decrease delayH one step and go back
   goto   delay         ; to decrease delayL once again
   return               ; we have counted delayL*delayH times
Detta fungerar eftersom du i alla fall räknar båda räknarna 255->0.
Notera att både delayL och delayH kommer att vara = 0 vid return.

Första blinket kan bli vad som helst (beroende på vad delayL och delayH råkar få för värden vid reset), men du kan lägga in "CRLF delayL" och "CLRF delayH" direkt efter start labeln, om du vill undvika det.

Som vanligt, helt otestad kod... :-)

> "PORTA ville inte fungera..."

Därför att du inte har läst på ordentligt om PORTA i databladet... :-)

> "vet inte om jag missat något register"

Se den lilla grå rutan och kodexemplet i kapitlet om PORTA !

Överkurs : *Varför* är dessa pinnar konfigurerade som analoga inputs vid reset ?

> "Tack till Sodjan som hjälpte mig komma igång och visade på hur man kodar på ett "snyggt" sätt ".

Jag låvade aldrig något "snyggt", bara något som fungerade... :-)

EDIT : Glömde en sak.
Jag skulle sätta kristallen mer "rak", och sedan sätta de två kondingarna
direkt mellan PIC benen och GND bussen nedanför. Alltså utan de två extra kablarna. Kristall delen är den störningskänsligaste delen av kopplingen, så den bör vara så enkel som möjligt...
frejo
Inlägg: 496
Blev medlem: 21 april 2004, 21:43:01
Ort: Linköping

Inlägg av frejo »

Självklart. Både synpunkter och frågor är välkomna.

men, hm, satt och fundera på den där loopen länge och trodde jag hade det klart för mig.

Fast nu ser jag att det går ju utmärkt att korta ner den så där förutsatt att man jobbar mot ett 8-bitars register. Är van vid AVR:n där man också har några 16-bitars ;)
Det man tappar är finjusteringen av fördröjningen men det beror ju helt på vad man ska ha den till.

En annan variant skulle kunna vara:

Kod: Markera allt

Delay
   decfsz   delayL
   goto    delay         ; continue counting until delayL = 0
   movwf	delayL
   decfsz   delayH         ; decrease delayH one step and go back
   goto   delay         ; to decrease delayL once again
   return               ; we have counted delayL*delayH times 
Då w har rätt värde sen tidigare, förutsatt att inget interrupt ändrat där.

Ang, XWisp2, jag gjorde även en pic.bat som jag la i samma katalog som XWisp2 med innehållet:
@xwisp2w go %1

Finns säkert 100 sätt att lösa det på, tycker det är smidigt med en cmd-prompt där jag bara skriver "pic filnamnet" och sedan använder pil-upp som du beskriver.

Ang. PORTA
Det enda jag hitta i databladet var:
Note: On a Power-on Reset, RA5 and RA3:RA0
are configured as analog inputs and read
as 0. RA6 and RA4 are configured as
digital inputs.
Kan tillägga att jag redan hade satt TRISA=0x00, då borde den väl ändå vara output?
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43205
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

> "Då w har rätt värde sen tidigare, förutsatt att inget interrupt ändrat där. "

En korrekt kodad ISR (Interrupt Service Routine) skall inte ändra W (i main koden) !

På PIC18 sparas dessutom W, STATUS och något mer register *automatiskt* när interruptet inträffar, och "RETFIE, 1" återställer dom automatiskt. O.b.s, fungerar bara om man köra en interrupt nivå, men det är nog det vanligaste. Med "riktigt" skrivna ISR, så brukar man inte behöva köra med två interrupt prioriteter i alla fall...

Angående PORTA så har du missat följande i kodexemplet (i databladet) :

Kod: Markera allt

...
MOVLW 0x07   ; Configure A/D
MOVWF ADCON1 ; for digital inputs
...
I texten står det även :

> The other PORTA pins are multiplexed with analog
> inputs and the analog VREF+ and VREF- inputs. The
> operation of each pin is selected by clearing/setting the
> control bits in the ADCON1 register (A/D Control
> Register1).

och även (i en egen liten grå ruta) :

> Note: On a Power-on Reset, RA5 and RA3:RA0
> are configured as analog inputs and read
> as 0. RA6 and RA4 are configured as
> digital inputs.

Det spelar ingen roll vad du gör med TRISA om inte pinnarna sätts om till digital I/O via ADCON1 !
frejo
Inlägg: 496
Blev medlem: 21 april 2004, 21:43:01
Ort: Linköping

Inlägg av frejo »

ok, läste kodexemplet lite snabbt och såg väl bara vad jag ville se ;)

Nu har jag i alla fall fått ordning på en timer med interrupt:

Kod: Markera allt

	list p=18f452
	include "p18f452.inc"

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;     CONFIG settings (copied from P18F452.INC)
	config OSC = HS
	config OSCS = OFF
	config PWRT = ON
	config BOR = OFF
	config WDT = OFF
	config CCP2MUX = OFF
	config STVR = OFF
	config LVP = OFF
	config DEBUG = OFF
	config CP0 = OFF
	config CP1 = OFF
	config CP2 = OFF
	config CP3 = OFF
	config CPB = OFF
	config CPD = OFF
	config WRT0 = OFF
	config WRT1 = OFF
	config WRT2 = OFF
	config WRT3 = OFF
	config WRTB = OFF
	config WRTC = OFF
	config WRTD = OFF
	config EBTR0 = OFF
	config EBTR1 = OFF
	config EBTR2 = OFF
	config EBTR3 = OFF
	config EBTRB = OFF
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;    Variables. We put them in the access bank...
vars		UDATA_ACS
tmrCount	RES   1
tmrVal		RES   1
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
	
Boot	CODE	h'0000'
	goto	start
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

Int	CODE    h'0008'         ;This is where our interrupt routine will start 


	decfsz	tmrCount		; decrement
	goto end_of_isr			; not zero yet, continue counting
	movff	tmrVal,tmrCount ; reset value
	comf	PORTC, F		;Invert PORTC

end_of_isr
	bcf	    INTCON, TMR0IF 	; clear interrupt flag.
	retfie                      

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Main	CODE     

start
	movlw	d'195'	; 50Hz m. TOSC = 20Mhz
	movwf	tmrVal
	movwf	tmrCount
	
	bsf     INTCON,GIE
	bsf     INTCON,TMR0IE

	movlw	0x00
	movwf	TRISC		  	;  PORTC as output
	movwf	PORTC			; initiate state of PORTC
	movlw   b'11001111'		; enable timer0,8-bit, prescale = 256 
	movwf	T0CON
	
loop
	goto loop
	
	end
Kan tilläga att koden är en del av en lab där val av timer osv var styrt enligt följande:
Fyrkantpulser med frekvensen 50 Hz och timer0 module. Använd minst signifikanta byte till timer0 module med lämpligt valt värde på prescalern. Utnyttja dessutom en minnescell i RAM vars innehåll minskas med ett varje gång timer0 module räknat runt så att flaggan har satts för overflow. Glöm inte återställa flaggan i koden. Innehållet i minnescellen laddas med det innehåll som läses av från port D som är ansluten till en DIP-switch. Undersök mellan vilka frekvenser fyrkantpulserna kan ställas in med hjälp av DIP-switchen.
Rätt bra att få jobba utifrån en "kravspec" nån gång ibland också.

Nu tror jag iofs inte det var menat att det skulle vara interruptbaserat men det blir väldigt smidigt så samtidigt som man lär sig något nytt.

Nu till ett annat problem. Vad jag läst mig till ska man ju kunna välja en multiplier på kristallens frekvens mha av en PLL.
Har tittat i include filen och där finns ju OSC = HS samt OSC=HSPLL, tittar man sen i databladet står det att om PLL är aktiverad får man Fkristall * 4 som intern klocka.
Har provat med både HS och HSPLL men frekvensen vid lysdioden blir exakt samma, borde inte den ändras?


Till sist en liten kul grej, råkade av misstag köra in en gammal hex-fil från ovanstående kod, tog lite tid innan jag insåg att jag hade fel hex-fil, det var nästan magiskt (så fort jag gick nära fungerade den, men när jag backade slutade den att fungera)
Film
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43205
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

PLL : kristal max 10 Mhz (står naturligtsvis i databladet i oscillator delen :-) ).
40 Mhz är max för PIC18 serien (med ett par undantag).

Notera att "RETFIE" inte återställer WREG, STATUS och BSR.
Ta gärna för vana att göra "RETFIE, 1". Se databladet för detaljer.

Sedan är ju detta en ganska rudimentär ISR. Normalt har men två eller flera olika interrupt källor, och då måste man börja med att testa xxxxIF flaggorna för att se vilket interrupt som man skall "serva".

Det hela skulle också bli lite mer realistiskt om inte ISR'en ändrade PORTC, utan bara sätter en "flagga" som main loopen sedan kollar, och ändrar PORTC om det behövs. Det är oftast så man strukturerar upp det, ISR'en är så kort som möjligt, kollar av något och sätter en flagga (t.ex läser ett tecken från USARTen, sparar det, och sätter en flagga som talar om att ett tecken har kommit in). Main rutinen pollar dessa flaggor och gör sedan själva grovjobbet (t.ex kollar vad det var som kom in på USARTen).

Kolla gärna MAP filen så ser du en del intressanta saker om hur MPLINK har snott ihop det hela. Bl.a vilka fysiska minnes adresser som dina variabler har hamnat på (även om det inte spelar något roll vilka adresser det blev, och att man inte heller behöver veta det, men det kan vara bra att veta var informationen finns).

Jag skulle ha skickat med en DIP-switch... :-) Men det kan ju även fixas med några trådar på labbplattan...

> "så fort jag gick nära fungerade den, men när jag backade slutade den att fungera"

Brukar tyda på att man har någon eller några "öppna" ingångar som plockar upp brum (oftast 50 Hz nätbrum) från omgivningen (t.ex dig). Oanvända pinnar skall antingen läggas till 5V eller GND, eller (enklare) sättas som utgångar (se bara till att inte ansluta något till dom!).
frejo
Inlägg: 496
Blev medlem: 21 april 2004, 21:43:01
Ort: Linköping

Inlägg av frejo »

Ja och på min platta sitter det en 10Mhz kristall.
Har plöjt oscillator delen i databladet ett antal gånger, det jag kan få ut är:
For an input clock frequency of 10 MHz, the internal
clock frequency will be multiplied to 40 MHz. This is
useful for customers who are concerned with EMI due
to high frequency crystals.
The PLL can only be enabled when the oscillator configuration
bits are programmed for HS mode. If they are
programmed for any other mode, the PLL is not
enabled and the system clock will come directly from
OSC1.
The PLL is one of the modes of the FOSC<2:0> configuration
bits. The Oscillator mode is specified during
device programming.
Kollar man sen i include-filen precis som jag beskrev ovan finns det OSC=HS och OSC=HSPLL, följdaktligen borde HSPLL stå för att PLL är aktiverad och min pic borde snurra i 40Mhz, men det gör den inte...
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43205
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

En liten detalj som jag tror *inte* står...

När man har ändrat till/från PLL, *måste* man slå av spänningen och på igen, för att ändringen ska "ta". Jag har själv missat det flera gånger...
jensa
Inlägg: 149
Blev medlem: 28 oktober 2003, 18:16:49
Ort: Umeå

Inlägg av jensa »

Intressant "startkit" du hittat där. Antar att det är sojan som säljer (via forumet?).
Synd bara att några av mina minneskretsar som jag skulle vilja leka med är SMC å därför lite jobbiga att få på testbord utan lödning :(
frejo
Inlägg: 496
Blev medlem: 21 april 2004, 21:43:01
Ort: Linköping

Inlägg av frejo »

ja, det är han som säljer, inte nödvändigtvis via forumet:
http://www.jescab.se/wisp628.html
finns även att beställa från Holland men det känns lite knöligt.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43205
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

Angående "start-kitet"...

Det är något som jag har tänkt att sammanställa i lite mer ordnade former. Jag har hållit på och räknat på olika "innehåll", och det är lite svårt att hitta rätt "nivå". Vad skall vara med ? Vad har de flesta sedan tidigare ? Skall det vara med 2-3 "nybörjar-PICar", eller vill de flesta välja själva ? Sannolikt kommer jag att sammaställa *något* i alla fall (jag fick hem 50 labbplattor för någon vecka sedan, och jag kan ju inte ha dom liggandes...). Hur som helst, det blir en ny sida på www.jescab.se när det är dags, och antagligen en notis här (i rätt forum ! :-) ).

> "Synd bara att några av mina minneskretsar som jag skulle vilja leka med är SMC..."

Du säger inte vilken kapsel det är, med dels finns det väll (DYRA) socklar för de flesta kapseltyper, eller om det SOIC kan man ju alltid köra med något liknande dessa : http://www.jescab.se/SOIC_DIP.html :-) :-)
jensa
Inlägg: 149
Blev medlem: 28 oktober 2003, 18:16:49
Ort: Umeå

Inlägg av jensa »

Woops, kollade fel var inte minneskretsarna, blandade ihop dom med mina 2 12f675f rfpic som har ssop socket.men dom behöver fortfarande konverteras så :)

Personligen för mig så skulle det ju inte vara helt fel med ett startkit med:
EN valfri PIC
Kristall
kondingar till ovan
Wisp628
(ev. RS-Link)
(ev. strömförsörjning, dvs sp.reg + 2 kondingar)
(ev. veroboard)
(ev. tryckknappar, LED, LCD ...)

Förövrigt så verkade sakerna på din sida väldans trevliga :)
frejo
Inlägg: 496
Blev medlem: 21 april 2004, 21:43:01
Ort: Linköping

Inlägg av frejo »

syftar du på RS232-link så finns den möjligheten att få genom wisp628 om jag förstått allting rätt, bara att löda dit två sladdar till (rx/tx).
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43205
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Inlägg av sodjan »

Nja, jag är inte helt säker på vad du syftar på med "två sladdar till" på Wisp628...
frejo
Inlägg: 496
Blev medlem: 21 april 2004, 21:43:01
Ort: Linköping

Inlägg av frejo »

http://www.voti.nl/wisp628/index.html skrev:Wisp628 provides a serial passthrough which is usefull when you want to communicate with your target system. The same serial line that is connected to the Wisp628 programmer can be passed on to the target PICmicro's pins RB6 + RB7 (the ones that are already used for programming), or - using additional wires from Wisp628 to the target PICmicro - any pair of pins (most likely: the pins that are connected to the targets build-in UART). The passthrough is implemented in software, so it is best used with baudrates of 19k2 and lower. The passthrough can handle both inverted and non-inverted signal levels at the target PICmicro side.
Och så står det ju längst ner här också
http://www.jescab.se/ICSP.html skrev:Pin 7 och 8 används bara om men vill använda möjligheten att köra seriedeta genom Wisp628 till PC:n. Används normalt inte och behöver då inte heller anslutas.
För mig låter det som att jag kan använda max-kretsen på wisp628:an för att konvertera signalnivåerna så att pic:n jag programmerat kan snacka med datorn.
Skriv svar