Author Topic: PIC USART communication problem  (Read 17019 times)

0 Members and 1 Guest are viewing this topic.

Offline wicket

  • Contributor
  • Posts: 35
PIC USART communication problem
« on: March 17, 2014, 09:59:04 am »
Hi,

I'm using a PIC16F628A USART to communicate with my SE T610 GSM. MikroC compiler.

Circuit:


How program works - when RB0 goes high, uC transmits "at" command to my GSM and it responds "OK". I've included a char compare routine to see if the response is indeed "OK". And it works - if it receives chars O, K, \n or \r the LED turns on.

My problem - I'm trying to use the exact same program and circuit (with appropriate pin adjustments, of course) with my PIC18F4520 and PIC16F887 but it doesn't work.

Transmittion works fine, I've tried "atd" command instead of "at", and GSM makes a call, which means transmission is ok. And uC also receives something back, because interrupt does occur (i've tested it), but when I compare incoming chars, none of them are what they are supposed to be ("OK\n\r").

I've also connected the GSM to my PC directly and tested it using putty to make sure it's not GSMs fault. It works perfectly.
Voltage levels of Tx and Rx pins are correct, I've also tried different Fosc's and baudrates, but couldn't make it work. Unfortunatley I don't have an access to any oscilloscope to check what am I actually receiving.

I don't understand why it works on 16F628A, but not on other two PICs. I suspect it has something to do with USART configuration. I've read all 3 datasheets but it seems to me nothing should change regarding USART init.

I would really appreciate any help.

Code from PIC16F887, where I'm using PORD intead of PORTB I/O:
Code: [Select]
volatile unsigned char uart_rd = 0; // serial input byte (RCREG)
unsigned int b = 0;

// UART Initialization
void uartinit()
{
UART1_Init(9600); // initialize UART module at 9600 bps
Delay_ms(100); // let it stabilize
PIE1.B5 = 1; // turn on USART interrupt bit RCIE
}

// UART Interrupt: Receive character
void interrupt()
{
if (PIR1.B5) // if interrupt occurs - if RCIF = 1(RCREG full)
{
uart_rd = RCREG; // read incoming byte (character)
if (uart_rd == 79) PORTD.B1 = 1; //if incoming byte is "O", turn on LED
PIR1.B5 = 0; // reset RCIF flag bit to 0
}
}

// Main program
void main()
{
uartinit();

INTCON = 0b11000000; // enable PEIE and GIE interrupts
ADCON1 = 0b0111; // configure all pins as digital
TRISD = 0b01;
PORTD = 0b00;

while (1)
{
if ((PORTD.B0 == 1) && (b == 0)) // if input goes high
{
b = 1; // set flag, so this if loop is disabled in future
UART1_Write_Text("at"); // phones response should be "OK"
UART1_Write(13); // \r
}
}
}
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: PIC USART communication problem
« Reply #1 on: March 17, 2014, 11:17:26 am »
The usart portion of the code looks ok. Issue is likely somewhere else, like pin setup - analog and comparator off....
================================
https://dannyelectronics.wordpress.com/
 

Offline wicket

  • Contributor
  • Posts: 35
Re: PIC USART communication problem
« Reply #2 on: March 17, 2014, 12:06:54 pm »
16F887 datasheet

Possible, yes. I've set all analog pins to digital using ADCON1 = 0b0111; as described in datasheet, but I can't seem to find comparators module with this PIC.
 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1425
  • Country: us
Re: PIC USART communication problem
« Reply #3 on: March 17, 2014, 12:25:53 pm »
Page 87 & 109
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 

Offline wicket

  • Contributor
  • Posts: 35
Re: PIC USART communication problem
« Reply #4 on: March 17, 2014, 01:03:54 pm »
Whoops, I downloaded 877 datasheet instead of 887.

I've corrected the code, but it still doesn't work:
Code: [Select]
volatile unsigned char uart_rd = 0; // serial input byte (RCREG)
unsigned int b = 0;

// UART Initialization
void uartinit()
{
UART1_Init(9600); // initialize UART module at 9600 bps
Delay_ms(100); // let it stabilize
PIE1.B5 = 1; // turn on USART interrupt bit RCIE
}

// UART Interrupt: Receive character
void interrupt()
{
if (PIR1.B5) // if interrupt occurs - if RCIF = 1(RCREG full)
{
uart_rd = RCREG; // read incoming byte (character)
if (uart_rd == 79) PORTD.B1 = 1; //if incoming byte is "O", turn on LED
PIR1.B5 = 0; // reset RCIF flag bit to 0
}
}

// Main program
void main()
{
uartinit();

INTCON = 0b11000000; // enable PEIE and GIE interrupts
ANSEL = 0b00000000; // configure all pins as digital
CM1CON0.B7 = 0; // comparators off
CM2CON0.B7 = 0;
TRISD = 0b01;
PORTD = 0b00;

while (1)
{
if ((PORTD.B0 == 1) && (b == 0)) // if input goes high
{
b = 1; // set flag, so this if loop is disabled in future
UART1_Write_Text("at"); // phones response should be "OK"
UART1_Write(13); // \r
}
}
}

I get into interrupt routine, but received byte is still not O, K, \n or \r.
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7438
  • Country: nz
Re: PIC USART communication problem
« Reply #5 on: March 17, 2014, 01:41:36 pm »
As a test you could loop mcu tx and rx and see if what you send is what you get back. Might gives some clues to help understand where the problem is

Save up and buy a scope, so useful for this sort of stuff.
« Last Edit: March 17, 2014, 01:44:43 pm by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline wicket

  • Contributor
  • Posts: 35
Re: PIC USART communication problem
« Reply #6 on: March 17, 2014, 05:38:45 pm »
Yeah, I tried using intergrated UART tool and it worked all right. I received what i sent.
I'm simply lost, duplicating the exact same routine on different PIC... Strange.

And yes, I'll definitely get myself a scope.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: PIC USART communication problem
« Reply #7 on: March 17, 2014, 09:39:55 pm »
Aside from actual differences between peripherals, you want ckeck analog, comparator, and fuse.

================================
https://dannyelectronics.wordpress.com/
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: PIC USART communication problem
« Reply #8 on: March 17, 2014, 10:31:47 pm »
Have you tried using your micro unit with some PC terminal software to see if the baud rate is correct?

A loopback will succeed with the wrong baud rate because the micro tx and rx are at the same (incorrect) rate.
 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1425
  • Country: us
Re: PIC USART communication problem
« Reply #9 on: March 17, 2014, 11:08:50 pm »
I think it's time to throw a blinky on all three chips, using the same code base, and making sure blinky does it's blinking at the correct rate.
I'm betting you'll find one of them is 4x off.
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 

Offline wicket

  • Contributor
  • Posts: 35
Re: PIC USART communication problem
« Reply #10 on: March 18, 2014, 09:08:44 am »
Have you tried using your micro unit with some PC terminal software to see if the baud rate is correct?

A loopback will succeed with the wrong baud rate because the micro tx and rx are at the same (incorrect) rate.

I connected my PIC to TTL - USB converter and tried to used putty, but I cannot type anything into terminal window and I also don't receive anything. But if I use MikroCs integrated UART terminal, it works.

What if I insert a parity bit check into my interrupt routine (FERR)? Would that signalize incorrect baudrate or xtal? I've read that UART is extremely sensitive regarding oscillator.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: PIC USART communication problem
« Reply #11 on: March 18, 2014, 09:13:56 am »
Checking that the oscillator is running at the correct speed should be at the top of your list.
 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1425
  • Country: us
Re: PIC USART communication problem
« Reply #12 on: March 18, 2014, 09:15:40 am »
Would that signalize incorrect baudrate or xtal? I've read that UART is extremely sensitive regarding oscillator.
....hence the earlier suggestion to hook up an LED and write a quick blinky program...
...(sigh)...
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 

Offline wicket

  • Contributor
  • Posts: 35
Re: PIC USART communication problem
« Reply #13 on: March 18, 2014, 12:10:11 pm »
....hence the earlier suggestion to hook up an LED and write a quick blinky program...
...(sigh)...

Gonna try it then. :)
 

Offline granz

  • Regular Contributor
  • *
  • Posts: 136
  • Country: us
  • 6.62606957
Re: PIC USART communication problem
« Reply #14 on: March 18, 2014, 03:12:52 pm »
I connected my PIC to TTL - USB converter and tried to used putty, but I cannot type anything into terminal window and I also don't receive anything. But if I use MikroCs integrated UART terminal, it works.

Putty won't display characters you type, but they are still sent.  Normally, when you see what you are typing, it's because the receiver is echoing the characters back.

From what you've said so far, it certainly sounds like the baud rate is set incorrectly.  I would double check the CONFIG bits, and the OSCCON register.  You can also set OSCCON manually at the top of your main() routine to be sure it is what you expect.  I don't use MikroC, but the UART1_Init() library routine will be setting up the UART registers based on what it believes the clock rate is.

You could also not use UART1_Init() and just setup the USART registers yourself, it's really only a few lines of code.

« Last Edit: March 18, 2014, 07:57:59 pm by granz »
 

Offline wicket

  • Contributor
  • Posts: 35
Re: PIC USART communication problem
« Reply #15 on: March 18, 2014, 03:29:15 pm »
I understand. Instead of calibrating  INTOSC, I'm gonna test it using 3.6864 MHz in 11.0592 MHz crystals, which are supposably the best fit for UART (theoretical 0% baud error).

I'm gonna set UART registers myself and also try to duplicate the same program in MPLAB instead of MikroC. I'll let you know how it goes.
 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1425
  • Country: us
Re: PIC USART communication problem
« Reply #16 on: March 18, 2014, 05:13:09 pm »
The point isn't really that your crystal, internal oscillator, etc. is off by 1% or 2% or whatever...  The point is figuring out if you've got your oscillator configuration set correctly and therefore your baud rate division is being done correctly.
Example...If you do a one second blinky, and actually get a 4 second blinky, might be trying to use the 4xPLL, but it's not actually on, or something along those lines.
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: PIC USART communication problem
« Reply #17 on: March 18, 2014, 11:40:33 pm »
Quote
might be trying to use the 4xPLL

The chip is unlikely to have a pll.

9600bps is usually the upper limit for internal rc oscillator. If you suspect that the internal oscillator isn't that accurate, you can try to tune it or lower the baud rate to a point where oscillator errors are sufficiently insignificant.

It is generally a good idea to use crystal when high speed uart is used, however.
================================
https://dannyelectronics.wordpress.com/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: PIC USART communication problem
« Reply #18 on: March 19, 2014, 12:18:44 am »
I tried the framework of your code and it worked: in my case, I was looping back RX to TX and flipping PORTD.1 on '\n'. So your issues are anything other than the portion of the code posted.

One suggestion:

Code: [Select]
INTCON = 0b11000000; // enable PEIE and GIE interrupts
I would rewrite that code using bits, if your compiler supports it:

Code: [Select]

 PEIE = 1;  //enable peripheral interrupts
 GIE = 1;  //enable global interrupts

In case the positions of PEIE and GIE are different from chip to chip.
================================
https://dannyelectronics.wordpress.com/
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: PIC USART communication problem
« Reply #19 on: March 19, 2014, 12:40:08 am »
Clarify a little bit further: as I don't have your compiler, I had to set CREN and others bits to get my code to work, in the spirit of your code. Your usart initialization may or may not have done similar things. but the isr is identical (functionally).
================================
https://dannyelectronics.wordpress.com/
 

Offline wicket

  • Contributor
  • Posts: 35
Re: PIC USART communication problem
« Reply #20 on: March 19, 2014, 08:23:03 am »
Ok, I decided to leave behind my PIC 887 (I only used it to compare to my 628A and 4520) and only focus on 18F4520, which I'll be using in my final product. I also found 7.3728 MHz oscillator, which gives me 0% baud error using BRGH = 1, BRG16 = 0 and desired baud of 9600 bps.

Tried a simple 1 second blinky, works fine.

To avoid any potencial mess, I also initialized UART myself, instead of inbuilt UART1_Init() library.
Also tried PORTD instead of PORTB. Everything is the same, I do get into the interrupt routine, but an led doesn't turn on when comparing incoming chars.

I've measured voltage levels of the circuit (I'm powering it from 7805 reg.):

Vdd - 5,02 V
PIC Tx pin (GSM Rx) - 5,02 V
PIC Rx pin (GSM Tx) - 2,78 V

Since I don't own a scope, I was measuring PIC Rx voltage during reception and a slight voltage drop does occur (I know multimeter isn't fast enough, but it seems there definitely is something going into the PIC).
« Last Edit: April 12, 2014, 12:44:54 pm by wicket »
 

Offline SL4P

  • Super Contributor
  • ***
  • Posts: 2117
  • Country: au
  • There's more value if you figure it out yourself!
Re: PIC USART communication problem
« Reply #21 on: March 19, 2014, 08:50:56 am »
/* ---
Here's the exact code I used on PIC16F887  (  887 !!)
Worked fine with internal 8MHz oscillator (INTOSC) - both PIC to PIC and with many serial terminals - FTDI and RS422 links

It may be worth looking at the FERR flag, as I found that closes the UART until it is cleared and re-initialised as shown below.
--- */

// =================================================================
   :
   :
   :
// ---- serial port --------------------------------------
#define SER_19200
   
   #ifdef SER_9600
   TRISC6 = 0;
   SPBRG = 12;            // 9600 bps @ 8MHz CLOCK
   BRGH = 0;               // high speed flag
   BRG16 = 0;
   #endif
   #ifdef SER_19200
   TRISC6 = 0;
   SPBRG = 25;            // 19200bps @ 8MHz CLOCK
   BRGH = 1;               // high speed flag
   BRG16 = 0;
   #endif
   #ifdef SER_57600
   TRISC6 = 0;
   SPBRG = 34;            // 57600bps @ 8MHz CLOCK
   BRGH = 1;               // high speed flag
   BRG16 = 1;
   #endif
   
   // ------------------
   SYNC    = 0;            // asynchronous
   RX9       = 0;            // 8 bit
   CREN    = 1;            // receiver enabled
   TX9       = 0;            // 8 bit
   TXEN    = 1;            // enabled
   SPEN    = 1;
   :
   :
   :
// =================================================================
   
void sendChar(char c) {
   while ( (TXIF == 0 ) );
   TXREG = c;   // push char to tx register
   DelayUs(100);   // allow the receiver to digest the char - no handshake
}

// =================================================================

static void interrupt isr(void) {

   while (RCIF) {   // serial character(s) have been received into FIFO
      CLRWDT();
      if (OERR) { // over run
         CREN = 0;   CREN = 1;   OERR = 0;
         rptr = rxBuf;  wptr = rxBuf;   // reset the rx Buffer
         break;
      }
      if (FERR) { // framing err
         rptr = rxBuf;   wptr = rxBuf;   // reset the rx Buffer
         dummy = RCREG;   // grab the dud character
         break;
      }
      mychar = RCREG;      // put char from rx register into buffer
   :
   :
   :
   }
// =================================================================

Don't ask a question if you aren't willing to listen to the answer.
 

Offline David_AVD

  • Super Contributor
  • ***
  • Posts: 2607
  • Country: au
Re: PIC USART communication problem
« Reply #22 on: March 19, 2014, 09:49:54 am »
Yes, checking for overruns and frame errors (and reacting to them) is essential.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8229
  • Country: 00
Re: PIC USART communication problem
« Reply #23 on: March 19, 2014, 10:38:47 am »
Code: [Select]
if (uart_rd == 10) PORTB.B1 = 1; //if incoming byte is "\n", turn on LED
Use

Code: [Select]
if (uart_rd == 'a') PORTB.B1 ^= 1; //if incoming byte is "\n", turn on LED
and tie RX to TX. Insert a long delay like 500ms in the main loop - don't set b in the main loop.

If you observe B1 blinking, your code is working.
================================
https://dannyelectronics.wordpress.com/
 

Offline wicket

  • Contributor
  • Posts: 35
Re: PIC USART communication problem
« Reply #24 on: March 19, 2014, 01:18:40 pm »
Using your advices, I programmed the chip in MPLAB (first time using this program, maybe something is way off).

First I only tried looping Tx and Rx through UART terminal and it worked fine, I received what I sent, also the LED was turning on/off on defined chars/strings.

When I hooked up my GSM, I got the same result as always till now...  Transmission works and i get into the interrupt itself, but that's it.

Now I'm trying to do FERR and OERR check. I'm reading the 18F4520 datasheet and it says, that this chip doesn't support hardware parity, but it is possible via software. I simply don't know how to handle this, it probably has to do something with 9-bit reception, whereas the 9th bit is a parity bit?

Oh, and I tried to use delays instead of "flag" b in mikroC, but it didn't help. And I don't know how to use a delay in MPLAB, so I couldn't test it there.
« Last Edit: April 12, 2014, 12:45:26 pm by wicket »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf