AUSART problem med PIC 16F88

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

AUSART problem med PIC 16F88

Inlägg av jfri »

Har problem att få utskrift till PC serieporten att fungera om en 16F88 används. Har ett program (listat nedan) som använder AUSART för att skriva till serieporten på min PC.
Använder där terminalprogrammet Realterm. RX och TX pinnarna på 16F88 är kopplade till en nivåanpassare som sedan ansluter till PC serieporten. På denna nivåanpassare
finns LED för sändning och mottagning. Därför ser jag att signaler kommer in till den när PIC programmet skriver. Men i Realterm ser jag bra 'null' skrivas och dessutom en röd indikering på BREAK som ska innebära 'Break is when the RXD line is broken'. Men jag har kontrollerat med summer att RX och TX sladdarna är rätt anslutna vilket också framgår av nivåanpassarens LED (både sändning och mottagning indikeras). Om nedanstående program implementeras på en PIC16F690 så fungerar utskriften. Så jag förstår inte varför inte detta fungerar på en PIC16F88.

Kod: Markera allt

#include <htc.h>
#include <stdio.h>
#include "usart.h"

#define	_XTAL_FREQ	4000000L

#define	TRUE	1
#define	FALSE	0

__CONFIG(INTIO & WDTDIS & PWRTDIS & BORDIS & UNPROTECT);

void	Init_PIC()
{
	init_comms();
}
	
void	main()
{
	unsigned char	c;						//Lagra mottaget tecken här

	Init_PIC();

	do {printf("Hej 88:an\n\r");} while (TRUE); // ger nul nul nul osv med 16F88 men korrekt utskrift på en 16F690	
}

usart.c
#include <htc.h>
#include <stdio.h>
#include "usart.h"

void 			putch(unsigned char byte) 
{
	/* output one byte */
	while(!TXIF)	/* set when register is empty */
		continue;
	TXREG = byte;
}

unsigned char 	getch() 
{
	/* retrieve one byte */
	while(!RCIF)	/* set when register is not empty */
		continue;
	return RCREG;	
}

unsigned char	getche(void)
{
	unsigned char c;
	putch(c = getch());
	return c;
}

usart.h
#ifndef _SERIAL_H_
#define _SERIAL_H_

#define BAUD 9600      
#define FOSC 4000000L
#define NINE 0     /* Use 9bit communication? FALSE=8bit */

#define DIVIDER ((int)(FOSC/(16UL * BAUD) -1))
#define HIGH_SPEED 1

#if NINE == 1
#define NINE_BITS 0x40
#else
#define NINE_BITS 0
#endif

#if HIGH_SPEED == 1
#define SPEED 0x4
#else
#define SPEED 0
#endif

#if defined(_16F87) || defined(_16F88)
	#define RX_PIN TRISB2
	#define TX_PIN TRISB5
#else
	#define RX_PIN TRISB5
	#define TX_PIN TRISB7
#endif

/* Serial initialization */
#define init_comms()\
	RX_PIN = 1;	\
	TX_PIN = 1;		  \
	SPBRG = DIVIDER;     	\
	RCSTA = (NINE_BITS|0x90);	\
	TXSTA = (SPEED|NINE_BITS|0x20)

void putch(unsigned char);
unsigned char getch(void);
unsigned char getche(void);

#endif

sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: AUSART problem med PIC 16F88

Inlägg av sodjan »

> Om nedanstående program implementeras på en PIC16F690 så fungerar utskriften.
> Så jag förstår inte varför inte detta fungerar på en PIC16F88.

Tja, kanske för att det är två olika PIC modeller ?
De har USART moduler av olika "generation" (AUSART resp EUSART).
Är du *säker* på att koden ska fungera på båda rakt av ??
Användarvisningsbild
Icecap
Inlägg: 26658
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: AUSART problem med PIC 16F88

Inlägg av Icecap »

Om det indikeras break är det för att RS232-signalen är '0' för lång tid (ett tecken eller mer). Jag skulle gissa att din "nivåanpassning" är fel.

RS232 '0' = +3-12V
RS232 '1' = -3-12V
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: AUSART problem med PIC 16F88

Inlägg av jfri »

sodjan skrev:> Om nedanstående program implementeras på en PIC16F690 så fungerar utskriften.
> Så jag förstår inte varför inte detta fungerar på en PIC16F88.

Tja, kanske för att det är två olika PIC modeller ?
De har USART moduler av olika "generation" (AUSART resp EUSART).
Är du *säker* på att koden ska fungera på båda rakt av ??
Vad jag vet är att nedanstående kod finns i usart.h

Kod: Markera allt

#if defined(_16F87) || defined(_16F88)
	#define RX_PIN TRISB2
	#define TX_PIN TRISB5
#else
	#define RX_PIN TRISB5
	#define TX_PIN TRISB7
#endif
Så nog verkar det som om den ska fungera i 16F88. Annars har jag märkt i andra programexempel att dessa rader inte verkar spela någon roll. Editeras de till att definiera fel pinnar så har programexemplet ändå fungerat. Förstår inte det heller.
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: AUSART problem med PIC 16F88

Inlägg av jfri »

Icecap skrev:Om det indikeras break är det för att RS232-signalen är '0' för lång tid (ett tecken eller mer). Jag skulle gissa att din "nivåanpassning" är fel.

RS232 '0' = +3-12V
RS232 '1' = -3-12V
Borde det inte snarare vara någon form av timing fel i så fall. Precis samma krets för nivåanpassning fungerar med andra kodexempel där annan PIC än 16F88 används så
uppenbart matas rätt nivåer fram till PC porten.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: AUSART problem med PIC 16F88

Inlägg av sodjan »

Vad gör "Init_PIC()" ?
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: AUSART problem med PIC 16F88

Inlägg av jfri »

Init_PIC intierar PICen genom att köra init_comms() som ska initiera AUSARTen och den listas i usart.h. I mitt första inlägg är hela exempelkoden listad

Kod: Markera allt

/* Serial initialization */
#define init_comms()\
	RX_PIN = 1;	\
	TX_PIN = 1;		  \
	SPBRG = DIVIDER;     	\
	RCSTA = (NINE_BITS|0x90);	\
	TXSTA = (SPEED|NINE_BITS|0x20)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: AUSART problem med PIC 16F88

Inlägg av sodjan »

Aha, så hängde det ihop ja, ser det nu... :-)

En undran bara, du har inget för hantering av alla andra konfigureringar
av processorn ? Analoga pinnar o.s.v ? Jag är inte helt säker på att det
räcker med TRIS botarna för att få TX/RX att fungera. Det kan vara så,
men jag är inte helt säker...
Användarvisningsbild
Icecap
Inlägg: 26658
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: AUSART problem med PIC 16F88

Inlägg av Icecap »

Om pinnen har en analog funktion måste den stängas av, att bara slå på UART gör inte susen.

Men då lamporna tydligen blinkar är det ju värd att fundera på timing men jag saknar lita gammaldags felsökning!

Skit i UART'en men skicka en '0' hhv. '1' till TX-pinnen och mät resultatet efter nivåskiftet. Det är alltid bra att utesluta vissa fel, att anta att det nog är bra ger alldeles för många osäkerhetsfaktorer.
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: AUSART problem med PIC 16F88

Inlägg av jfri »

Det finns ingen analog funktion på RX (RB2) och TX(RB5) för 16F88. Endast RB7 och RB6 (för PORTB) har analog ingång som ett konfigureringsalternativ.
Försökte toggla TX manuellt med

Kod: Markera allt

	TRISB5=0;        //förblev hög
	TRISB5=1;
och i debuggning i hårdvaran men detta fungerade inte. Spänningen på TX förblev 4.9 V. Går inte detta pga att den är konfigurerad som AUART sändare?
Användarvisningsbild
Icecap
Inlägg: 26658
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: AUSART problem med PIC 16F88

Inlägg av Icecap »

Du måste ju låta bli att aktivera UART'en för att köra den test!

Och sedan är det ganska ointressant vad den är på µC-sidan, det är på RS232-delen det roliga sker men självklart kan det vara kul att se om '0'/'1' får rätt nivåer.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: AUSART problem med PIC 16F88

Inlägg av sodjan »

> ...är kopplade till en nivåanpassare...

Vad mer exakt är det för något ?
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: AUSART problem med PIC 16F88

Inlägg av jfri »

Jag använder den här nivå anpassaren från electrokit
http://www.electrokit.se/download/RS232-Shifter-SMD.pdf
Och om den får rätt insignaler från uC så fungerar den ju då andra exempelprogram fungerar
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: AUSART problem med PIC 16F88

Inlägg av sodjan »

OK, med den ska ju fungera helt OK.

Tja, har du (som Icecap förelog) funderat på lite gammal hederlig/traditionell felsökning ?
(Det betyder i princip att man funderar lite själv och inte bara kastar sig över närmaste forum... :-) )

> så fungerar den ju då andra exempelprogram fungerar

Och varför fungerar dom ? Vad är det som skiljer ?

Är du 100% säker på att allt det där med SPEED och NINE_BITS o.s.v fungerar ?

En del i en vanlig felsökning är att "kortsluta" alla specialhantering och se till
att man skriver hårdkodade värden (som är lättare att verifiera) direkt till registren.
Och/eller kolla assembler-listan från kompilatorn och verifiera att koden som den
genererar verkligen fungerar. Har du gjort det ?

Gör ett kort test-program och få *det* att fungera. Hoppa helt över allt vad
"printf" och annat C-tjafs heter och kör rakt på registren istället.

Börja med ett skicka ett enstaka tecken/byte och få *det* att fungera först.

Generellt sätt, backa ett par steg, minska ner koden tills det hoppar igång.
jfri
Inlägg: 180
Blev medlem: 1 februari 2010, 21:41:20

Re: AUSART problem med PIC 16F88

Inlägg av jfri »

Kom på vad problemet var. Denna uC kördes med 31.25 kHz som klockfrekvens som default om intern osc användes. Att få den att gå i 4 MHz (som jag tänkte) krävde att man konfigurerade detta i OSCCON registret.
I PIC16F690 blev klockfrekvensen 4 MHz utan att jag behövde göra något därför fungerade exemplet där och därför missade jag detta. 31.25 kHz var en klart oväntad låg klockfrekvens för mig. Tack för hjälpen i alla fall.
Skriv svar