Sida 1 av 3

PIC, Sätta TXREG med char

Postat: 8 juni 2011, 11:56:10
av Abets
Nybörjar med PIC behöver lite hjälp.

Sitter på en EasyPic6 med PIC18f4520 och använder kompilatorn CC8.

Jag försöker göra en funktion som skickar en byte data till PCns serieport.

Kod: Markera allt

void SendChar(uns8 c)
{
	while( ! TXIF ) ;
	TXREG = c;
}
Denna anropar jag med

Kod: Markera allt

SendChar('a');
Detta fungerar inte. På TX-pinnen skickar den endast en nolla - oavsett argument. TXREG får alltså ett värde(men någonstans blir det galet).
Om jag däremot sätter TXREG direkt med en konstant så fungerar det:

Kod: Markera allt

TXREG =  'a';
Vad är det som jag missar?

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 12:04:40
av Icecap
Blir lite osäker på vad du menar.

Kod: Markera allt

void SendChar(uns8 c)
  {
  while(!TXIF);
  TXREG = c;
  }
Fungerar inte skriver du men det som fungerar, ser det ut som följer?

Kod: Markera allt

void SendChar(uns8 c)
  {
  while(!TXIF);
  TXREG = 'a';
  }
Om det är så kan det vara för att den uppfattar c på fel sätt (har aldrig använd CC8) och du kan testa:

Kod: Markera allt

void SendChar(char c)
  {
  while(!TXIF);
  TXREG = c;
  }

Eller kanske:
void SendChar(unsigned short c)
  {
  while(!TXIF);
  TXREG = c;
  }
Det sista sättet deklarerar c till samma typ som TXREG. Jag skulle tro att compilern "tror" att värdeskillnaden gör att det är ett 16-bit värde som ska skrivas ut och då skickar den bara inledande 0x00.

EDIT: kom på ett mer tydligt sätt kanske:

Kod: Markera allt

void SendChar(char c)
  {
  while(!TXIF);
  TXREG = (unsigned short)c;
  }
Detta cast'ar c till att vara rätt typ när den skickas till TXREG men "utåt" är det en char.

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 13:06:58
av swesysmgr
Du måste sätta upp TX/RX-pinnarnas TRIS register först så att din PIC vet om att de skall användas som ut/ingångar.

Du behöver även konfigurera din serieports baudrate och sätta (fritt ur minnet) TXEN och SPEN för att aktivera sändning och serieportsfunktionen.

PIC har även en miljard olika analoga funktioner multiplexade på pinnarna, stäng av komparatorer och annat som delar port med de du skall använda först.

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 13:31:45
av sodjan
> Jag försöker göra en funktion som skickar en byte data till PCns serieport.....

Visa inte enbart lösryckta delar, visa *HELA* ditt testprogram.
Det finns (som swesysmgr påpekar) en hel del annat som kan störa,
och det finns ingen anledning att vi ska fråga om varje detalj.
Visa hela ditt testprogram så framgår det troligtsvis...

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 14:32:52
av Icecap
När TXREG = 'a'; fungerar är resten ganska säkert ställd upp korrekt!

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 14:50:24
av Abets
Det fungerar att sätta TXREG='a'. Så jag antog att det var rätt inställt.

Skalade av lite. Problemet är det samma:

Kod: Markera allt

#include "18F4520.h"
#include "INT18XXX.H"

void main() 
{
	OSCCON = 0b01000011; //1MHz
	
	TRISC = 0b11000000; 	//RX & TX =  inputs for serial communication
	PORTC = 0x00;

	TRISB = 0x00;
	PORTB = 0x00;
	
	SPBRG = 25; //---9600 Baud rate---
	SPBRGH = 0;
	BRGH = 1;	//High baudrate select bit (Asynch: 1= High speed, 0 = Low Speed)    
	BRG16 = 1;	//16-bit baud rate register enable bit (1= 16-bit, 0 = 8-bit)
	SYNC = 0;	//EUSART Mode Select bit (1 = Synchronous, 0 = Async)
	SPEN = 1;	//Serial port enable bit
	
	TXEN = 1;  //Transmit enable bit
	
	clearRAM();
	
	char a = 'a';
	TXREG = a;
	
	while(1) ;
	
}

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 14:54:08
av bearing
Hur ser genererade assemblerkoden ut kring raden TXREG = a; ?

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 15:16:42
av Abets

Kod: Markera allt

00002E 0E61		00076 		MOVLW 97
000030 6E00		00077 		MOVWF a,0
				00078 		;	TXREG = a;
000032 C000 FFAD  	00079 		MOVFF a,TXREG

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 15:24:43
av bearing
Ser ju inte ut att vara något fel i koden. Mätfel?

EDIT: vad gör clearram, och vad menar du med att det "funkar" att sätta TXREG = 'a'?

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 15:27:12
av JustNeed
Har du testat det som Icecap skrev?

Fungerar nedanstående?

Kod: Markera allt

void SendChar(uns8 c)
  {
  while(!TXIF);
  TXREG = 'a';
  }
Edit: Vet du om den kör igenom SendChar överhuvudtaget?

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 15:55:52
av sodjan
Prova med ett annan (bättre) variabelnamn än "a".
T.ex :

char char_to_send = 'a';
TXREG = char_to_send;

Om *det* fungerar så får du frågan om varför som hemläxa...

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 16:37:22
av Abets
bearing,
Hur menar du med mätfel?

clearRAM förjer med kompilatorn.
The internal function clearRAM() will set all RAM locations to zero. The generated code uses the FSR0 register.
När det funkar att sätta TXREG = 'a', så menar jag att jag får ut ett "a" i hyperteminalen.

JustNeed,
Ja. Det fungerar. SendChar anropas, men det har egentligen inte någonting med problemet att göra. Problemet ligger någonstans i att ange ett variabelt värde till TXREG.

sodjan,
Jag har kört runt med de flesta variabler. Det slutade med a, av ren lathet (bara för att det är kort). Jag tar det ändå som hemläxa att ta reda på varför.

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 16:42:08
av sodjan
Från din ASM kod :

MOVWF a,0
MOVFF a,TXREG

Har du någon assembler lista som visar vad symbolen "a" har för värde ?
Finns "a" definierat i någon av de två .h filerna ?

(Ledtråd: Detta *kan* vara ett problem just för att det är en PIC18, det
*borde* inte vara ett problem på en PIC16...)

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 16:47:33
av sodjan
> Problemet ligger någonstans i att ange ett variabelt värde till TXREG.

Jaha, och vad är skillnaden då ?
D.v.s i den genererad ASM koden ?
Felsökning kurs 1A... :-)

> Jag har kört runt med de flesta variabler.

Varför det ? Hur skulle *det* kunna hjälpa ?

> av ren lathet

Right, just *det* kan jag garantera är något som aldrig hjälper.

Re: PIC, Sätta TXREG med char

Postat: 8 juni 2011, 17:22:01
av Abets
00002E 0E61 00076 MOVLW 97
000030 6E00 00077 MOVWF a,0
00078 ; TXREG = a;
000032 C000 FFAD 00079 MOVFF a,TXREG
Denna kod genereras ju.
Sätter 97 som värde på a. Det finns inte någon symbol "a" i någon av .h filerna.

a får värdet som jag anger.
Testade med koden nedan
if(a == 'a') TXREG = 'a';