Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Starting Serial on MicroChip (16F1829)

Status
Not open for further replies.

woodrufj

New Member
I've been working on and off this first time microchip for a year, I should be considered a total novice on the chip and with C programming,

Ultimately I want these chips to send simple 8 character async strings RS232 to dumb receivers. For now, I'm trying to prove life of the serial transmit and receive on the 16F1829 Microchip here on my table top.

I'm using the Pickit3 programmer with a the low pin count demo board (03-01831). I've connected the chips pins RC4 and RC5 via jumper (should be serial TX and RX).

The idea is I configure the chip (async, 9600ish baud, TX enable, RX enable, etc), then write to the TX, which gets jumped to the RX, then read from teh RX and confirm the loop with a lit LED. But so far, no luck.

Again, I'm a beginner, so don't assume anything is not overlooked.



--------------------------
Code:
#include <xc.h>
long int x, count;
char serial_out, serial_in;

#pragma config FOSC=INTOSC

void main(void) {
   
  OSCCON = 0b01110000;  //Set internal Osc speed to 8 MHz 
   
   
  APFCON0bits.RXDTSEL = 0;  //Set RC5 as Serial RX
  APFCON0bits.TXCKSEL = 1;  //Set RC4 as Serial TX
  ANSELC=0;  //Set PortC to Digital
   
  TXEN = 1;  //Enable TX Circuit
  SYNC = 0;  //Asynchronous Operation (RX and TX)
  SPEN = 1;  //Configure RC4 as serial output
   
  CREN = 1;  //Enable RX Circuit
  TRISCbits.TRISC4 = 0;  //Set RC4 as output
  TRISCbits.TRISC5 = 1;  //Set RC5 as input
   
  //Baud rate setting for 9600
  SPBRGH=0;  //=0
  SPBRGL=0b00001100;  //=12
  BRGH=0;  //Low speed baud
  BRG16=0;  //Using 8bit baud generator
   
   
   
  TRISCbits.TRISC0 = 0;  //using pin as output (LEDs)
  TRISCbits.TRISC1 = 0;  //using pin as output (LEDs)
  TRISCbits.TRISC2 = 0;  //using pin as output (LEDs)
  TRISCbits.TRISC3 = 0;  //using pin as output (LEDs)


  LATC = 0;  //clear all LEDs

  serial_out = 'a';  //Char to transmit

  count=0;
   
  while(1){  //Forever loop
 
  //Transmit one character
  TXREG = serial_out;
   
  while (TXIF==0 || count<10) {  //Wait for Transmit Complete
  count++;
  }
  count=0;
   
  //Receive one character
  serial_in = RCREG;
   
  if ( serial_in == 'a' ){
  LATCbits.LATC2 = 1;  //Data Received
  }
  else {
  LATCbits.LATC2 = 0;
  }
   
  if ( TXREG == 'a' ){
  LATCbits.LATC3 = 1;  //Data Sending
  }
  else {
  LATCbits.LATC3 =0;
  }
   
  }
}
 
I don't use C so cannot help that much with the code, but if the recievers are RS232 you will need a MAX232 or similar IC,
For trouble shooting using a PC with a COM port the HEX232 program out there is very handy for this.
download.cnet.com/RS232-Hex-Com-Tool/3000-2383_4-10064973.html
Max.
 
You don't need to wait for TXIF unless you want to send the next character.

However, you need to wait for RCIF before reading RCREG.
 
I've got a hand full of 232 drivers in a bucket waiting for me to unblock this chip problem. Since you brought it up, anyone have recommendations on a 232 driver best for long distance? Low count in my plans, so no need to save pennies.

I'm thinking it isn't so much of a coding problem since it's a simple loop around, but something more inherent to the chip settings someone wiser will know.

Jay W
 
Here's the code I'm using on a 16F1827 running at 4MHz.

Code:
void Serinit()
   {
  TXCKSEL = 1;           // TXD on RB5
   RXDTSEL = 1;           // RXD on RB2
  TRISB5 = 0;  // TXD output
  TRISB2 = 1;  // RXD input
   SPBRG = 25;             // 4Mhz xtal 9600 BAUD
   TXSTA = 0x24;           // TXEN and BRGH
   RCSTA = 0x90;           // SPEN and CREN
   }

void Serout(unsigned char ch)
   {
   while(!TXIF);           // Wait for module to finish
   TXREG = ch;             // ready to send
   }
unsigned char Serin()
   {
   while(!RCIF);           // Wait for a character
   return RCREG;           // return character

   }
 
I've got a hand full of 232 drivers in a bucket waiting for me to unblock this chip problem. Since you brought it up, anyone have recommendations on a 232 driver best for long distance? Low count
What distance? As mentioned the Maxim MAX232
Max.
 
What distance? As mentioned the Maxim MAX232
Max.
Just as far as possible. Its for a remote display, and the longer I can wire it the more options I have. Thanks, I think I have some of those around somewhere.

I put in a "wait for RCIF" step, where it now appears to get stuck. Its perhaps not transmitting?

Code:
   :
   :
   :
  while(1){  //Forever loop

  LATCbits.LATC0 = CREN;  //Proof reciever on
   
  //Transmit one character
  TXREG = serial_out;
     
   
  while (!RCIF) {
  LATCbits.LATC1 = count/1000;  //Blink LED, waiting
  count++;
  }
  count = 0;

  //Receive one character
  serial_in = RCREG;

  LATCbits.LATC1 = 0;  //LED not waiting
   
  if ( serial_in == 'a' ){
  LATCbits.LATC2 = 1;  //Data Received
  }
  //else {
  //  LATCbits.LATC2 = 0;
  //}
   
  if ( TXREG == 'a' ){
  LATCbits.LATC3 = 1;  //Data Sending
  }
  else {
  LATCbits.LATC3 =0;
  }
   
  }
}
 
APFCON0bits.RXDTSEL = 0; //Set RC5 as Serial RX
APFCON0bits.TXCKSEL = 1; //Set RC4 as Serial TX
Both of these should be high ( default) 20 pin devices....

I use the pic16f1825 ( same footprint ) An I don't set these for portc operation as they are there anyway!!

As for an errata for Max's comments... If you need to go" looong" distance, ie over5 metres, use RS485 hardware..
 
Or not receiving. Shouldn't you set RXDTSEL to 1?
Hot damn, I think that was it.
God knows how many times I read that in the spec sheet and still got it wrong.

I'll follow up with more experiments tomorrow/next week, but the "alive" test seems to be working now.

Thanks for that, and thank others for some of the sample code I'll be using, as it's simpler than mine.

I'm sure I'll have future questions.

BTW, stuck with 232 because of existing hardware. :(. We once ran a test with something like a 150ft ethernet wire (ie, very small gauge) and the remote device took it (async).

Jay W
 
As for an errata for Max's comments... If you need to go" looong" distance, ie over5 metres, use RS485 hardware..

It all depends on the Baud rate, I have used RS232 at a distance over 100ft of in a highly noisy industrial environment.
I use the RS232 chart from some of the cable manuf.
which states:
19200 baud 50ft
9600 baud 500 ft
4800 baud 1000ft
2400 baud 3000
Max.
 
Last edited:
Status
Not open for further replies.
Back
Top