# pic uart not receiving

#### Andy206

Joined Nov 17, 2010
8
Hi everyone,

I'm trying to get my pic16f690 to talk rs232... using the usual max232 with 4 caps, really not worth posting a diagram i think.
It's actually working quite well, in that i can transmit from the pic just fine, going out to my hyperterminal without problems. Problem is on the receiving end, it just doesn't want to receive anything! I've checked with a logic probe on the actual pin of the pic (pin 12), i'm definitely getting data there. someone else seems to have had problems with logic levels before, checked that as well - my high is 4.2V which I'd think should more than do it... just in case i put a 2.2k to Vdd, no difference.
Code is attached below, it's the demo that came with mplab... I've modified it to use interrupts and spit out all sorts of debug info, all i find is that FERR is set but not OERR, and i'm not getting an interrupt - RCREG is always 0. I went back to the basic version below, same thing. I've tried using 2400 baud instead, no difference either. I'm really stuck... hoping for someone to spot some silly beginner's mistake...

Thanks heaps!
Cheers
Andy

usart.h
Rich (BB code):
#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

#define RX_PIN TRISB5
#define TX_PIN TRISB7
/* 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
usart.c
Rich (BB code):
#include <htc.h>
#include <stdio.h>
#include "usart.h"
/* Serial initialization */
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;
}
main.c
Rich (BB code):
#include <stdio.h>
#include <htc.h>
#include "usart.h"
/* A simple demonstration of serial communications which
* incorporates the on-board hardware USART of the Microchip
* PIC16Fxxx series of devices. */
__CONFIG(WDTDIS & PWRTEN & MCLRDIS & UNPROTECT & BORDIS & INTIO);
void main(void){
unsigned char input;
INTCON=0; // purpose of disabling the interrupts.
init_comms(); // set up the USART - settings defined in usart.h
// Output a message to prompt the user for a keypress
printf("\rPress a key and I will echo it back:\n");
while(1){
input = getch(); // read a response from the user
printf("\rI detected [%c]",input); // echo it back
}
}

#### Andy206

Joined Nov 17, 2010
8
After 8h+ of experimenting I finally found the problem: I have to initialise ANSEL/ANSELH to 0! d'oh! knew it'd be something simple... bit surprised though it's not in the demo software but hey, it's working now.
Hope it maybe saves someone else some time at some point.

#### Mosaic

Joined Aug 2, 2010
15
The Usart via the max232 shifts voltage levels. Is there a way to do this via serial usb without shifting levels?

I need some advice on serial via usb. I think i need a s'ware driver on the windows side and then do I use standard Usart protocols for comms?

#### Andy206

Joined Nov 17, 2010
8
The Usart via the max232 shifts voltage levels. Is there a way to do this via serial usb without shifting levels?

I need some advice on serial via usb. I think i need a s'ware driver on the windows side and then do I use standard Usart protocols for comms?
correct... that's why you need something like the max232. rs232 doesn't use ttl levels, that's just just how it works... officially you want +12 for H and -12 for L. However, the standard does require the receiver to understand everything down to +3/-3V, so sometimes you can trick it a bit by using +5/-5 or something like that. In any case, you'd still have to get -5V.

If you want to use usb instead you'd need a chip with a usb interface, different story.

Serial usb is the same as a "normal" serial port, you don't get any other benefits out of that (other than being able to use it on newer computers which don't generally have a serial port anymore). And yes, you need a driver, which will emulate the com port to windows (or whatever else you're using).

So really, there's no difference at all between using a "normal" serial port or a usb serial port.

And just a note on the side, you should probably open a new thread for a new topic... doesn't really have anything to do with the initial problem in this thread.