5

I am struggling with the following code:

#include <xc.h>
#include "config.h"

void Init(void);
void uart_send(char*);

void main(void)
{
    char arr[2]= {'a','b'};
    char i=0;
    Init();       
    uart_send(arr+i);
    i++;
    uart_send(arr+i);
    while(1);    
}

void uart_send(char* c)
{
    while(PIR1bits.TXIF < 1);
    TXREG= *c;
}

void Init(void)
{
    OSCCON = 0xef;    
    TRISBbits.RB7 = 0;  
    ANSELHbits.ANS11 = 0;
    PORTBbits.RB5 = 0;
    TRISBbits.RB5 = 1;  
    BAUDCON = 0x00;
    BAUDCONbits.BRG16= 1;
    SPBRGH  = 0x03;
    SPBRG  = 0x40;
    TXSTA= 0x24;          
    RCSTA= 0x90;       
    PIE1 = 0x00;
    INTCON = 0x00;    
    RCSTAbits.CREN = 1;
}

In the first case, I call the function uart_send and I receive 'a'. In the second case, when I call the function again, I also receive 'a' instead of 'b'. I can't figure it out Why. If I modify the code, to use value instead of address:

void uart_send(char);

void main(void)
{
    char arr[2]= {'a','b'};
    char i=0;
    Init();       
    uart_send(*(arr+i));
    i++;
    uart_send(*(arr+i));
    while(1);    
}

void uart_send(char c)
{
    while(PIR1bits.TXIF < 1);
    TXREG= c;
}

Then, in both cases I receive 0x03.

I use MPLAB X v3.30, XC8 1.37, PIC18F14K50

Please, if You have any idea what do I wrong, share it. Thank you.

UPDATE:

I checked the disassy and it should work. Maybe my mcu partly died or something magic...

PeterPal
  • 51
  • 3
  • Try making `i` of type `uintptr_t` (the type should be defined in `stdint.h`). It's possible you are ending up with weird integer overflows - it's not exactly the best compiler in the world. – Tom Carpenter Jun 19 '16 at 21:35
  • do you have optimization turned on ? What happens when you set optimization to 0 (if you have it to something higher than 0) ? – efox29 Jun 19 '16 at 21:51
  • @TomCarpenter I tried uintptr_t, but I've got the same result. – PeterPal Jun 19 '16 at 22:22
  • @efox29 I can't set a level of optimization, only select mode (free). --opt=default. I typed additional options: --opt=none. The same result. – PeterPal Jun 19 '16 at 22:26
  • 1
    If you use array notation, does that work ? arr[0],arr[1] ? – efox29 Jun 19 '16 at 22:28
  • @efox29 sometimes. If I define array outside of main (global) and write TXREG= arr[1] directly to main, without function call -> it works. If I define array inside main, it not works. ...I think, I have to check disassy, step by step. – PeterPal Jun 19 '16 at 23:01
  • What are your configuration bits set to? I don't see them in your code. – Dan Laks Jun 20 '16 at 07:56
  • Change the order. Arr[2]={'b','a'}. Does a still send or does b send? What about other letters other than and b? – efox29 Jun 20 '16 at 11:52
  • @DanLaks I uploaded the file here: https://drive.google.com/file/d/0BzjPcZR6xiIzaFF1X0IwRVJoR28/view?usp=sharing – PeterPal Jun 20 '16 at 16:48
  • @efox29 I always received the first item. I am 99% sure, the hw died. – PeterPal Jun 20 '16 at 16:51
  • After the first write to the EUSART, try polling the TMRT bit until it goes high (i.e. while (!TMRT);) before writing to the EUSART again. – ConduitForSale Aug 09 '18 at 14:43
  • Might be a long shot, but also try adding the "volatile" qualifier to arr. – ConduitForSale Aug 09 '18 at 14:53

2 Answers2

1

You don't specify your intended baud rate but I'm assuming it is 9600 bps, if so you are setting the baud rate incorrectly.

By using the internal oscillator, you are setting the microcontroller oscillator frequency to 16MHz, you are also setting the BRG16 and BRGH bits to 1, so the baud rate formula is Fosc/[4*(n+1)], where n is the SPBRG value that you are setting to be 832.

By replacing the values with the ones provided you have: $$ {16000000\over 4\times(832+1)} = {16000000\over 3332} = 4801.92...\approx4802 $$ If you want to set the baud rate to 9600 bps you have to reverse the formula to find n.

$$ baudrate = {Fosc\over{4\times(n+1)}} \Leftrightarrow n+1 = {Fosc\over{4\times baudrate}} \Leftrightarrow n = {Fosc\over{4\times baudrate}} - 1 $$

So: $$ {16000000\over 4 \times 9600}-1={16000000\over 38400}-1=416.66(6)-1=415.66(6) \approx416 $$

Therefore you SPBRG value should be 0x1A0.

Bruno Ferreira
  • 4,470
  • 2
  • 25
  • 36
  • You are right, I don't said anything about the baudrate. 4800 is fine. Don't judge me, sometimes I use 1200, too. :) Otherwise, thank you for this hi-quality explanation. – PeterPal Aug 12 '18 at 06:10
  • That was just a guess since 9600 bps is the most common baud rate. – Bruno Ferreira Aug 12 '18 at 08:11
0

2 years ago, but I remember for this annoying issue. Finally, I bought a new PIC, then flashed the same program. Worked correctly.

Conclusion: The first mcu (partly) died.

PeterPal
  • 51
  • 3