PIC16F887 Programming Dilemma

Thread Starter

Contzo

Joined Apr 16, 2020
6
Hello everyone, this is my first post here and I apologize if my thread is confusing in any way.

I am a beginner when it comes to PIC programming and i encountered a strange problem while trying to command a DDS chip ( AD9850 ). I have successfully created a program able to load parallel data on the chip and it worked very. I have implemented the code using Mikro C ( in which I have a little bit of experience ) but I am trying to convert the program to MPLAB X because I find the XC8 compiler to be more suited for working with float variables. I have zero experience with MPLAB, but I followed some tutorial online and I was able to successfully blink a LED just to get a hang of it.
This is the code in MPLAB with the main function and the other two I am using :

#include <xc.h>
#include "XC8.h"
#include <stdio.h>
#include <string.h>
#include <stdint.h>

#define FU_UD RA1
#define RESET RA2
#define W_CLK RA0
#define data_DDS PORTC

void DDS_RESET()
{

W_CLK = 0 ;
FU_UD = 0 ;
RESET = 0 ;
__delay_ms(5) ;
FU_UD = 1 ;
__delay_ms(5) ;
RESET = 1 ;
__delay_ms(5) ;
RESET = 0 ;
__delay_ms(5) ;
}

void parallel_DDS( float freq )
{
int i ;
static uint8_t W_1[5] ;
uint32_t tuning_word ;
long double pow_2 = 4294967295;
long double fs = 125000000;
tuning_word = (uint32_t) ((freq /fs) * pow_2 + 0.5);
W_1[4] = tuning_word ;
W_1[3] = tuning_word>> 8 ;
W_1[2] = tuning_word >> 16 ;
W_1[1] = tuning_word >> 24 ;
W_1[0] = 0x00 ;

FU_UD = 0 ;

for( i = 0 ; i < 5 ; i++ )
{
data_DDS = W_1 ;
W_CLK = 1 ;
W_CLK = 0 ;
}
FU_UD = 1 ;

}



void main(void)
{
OSCCON = 0x77 ; // Internal osc 8MHz
TRISA = 0x00 ;
TRISC = 0x00 ;
DDS_RESET() ;
ANSEL = 0 ;
ANSELH = 0 ;

while(1)
{
parallel_DDS( 1000 ) ;
}
}

and the configuration bits :

#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

#define _XTAL_FREQ 8000000



The CLK, frequency upload, and reset bit are connected to RA. It is strange why the code works well in Mikro C and I can't get it to work in MPLAB , I miss something for sure. If some one could help me it would be grate.


The code build without errors, I am using MPLAB X IDE v5.35 and XC8 v2.10
 
Last edited:

AlbertHall

Joined Jun 4, 2014
9,899
Move the two 'ansel' lines to before the 'tris' lines.
You are only doing outputs and outputs will still work without clearing the ansel bits - EXCEPT that you output to single bits and thus will run foul of the 'read-modify-write' problem and the read part of that will not work correctly without clearing the 'ansel' registers.
 

Thread Starter

Contzo

Joined Apr 16, 2020
6
Move the two 'ansel' lines to before the 'tris' lines.
You are only doing outputs and outputs will still work without clearing the ansel bits - EXCEPT that you output to single bits and thus will run foul of the 'read-modify-write' problem and the read part of that will not work correctly without clearing the 'ansel' registers.
I moved those lines up but still not working. I find this confusing because it works without problems when using Mikro C .
 

Thread Starter

Contzo

Joined Apr 16, 2020
6
#include <stdint.h>

#define W_CLK PORTA.RA0
#define FU_UD PORTA.RA1
#define RESET PORTA.RA2
#define data_DDS PORTC

void DDS_RESET()
{

W_CLK = 0 ;
FU_UD = 0 ;
RESET = 0 ;
delay_ms(5) ;
FU_UD = 1 ;
delay_ms(5) ;
RESET = 1 ;
delay_ms(5) ;
RESET = 0 ;
delay_ms(5) ;
}



void parallel_DDS( float freq )
{
int i ;
static uint8_t W_1[5] ;
uint32_t tuning_word ;
long double pow_2 = 4294967295;
long double fs = 125000000;
tuning_word = (uint32_t) ((freq /fs) * pow_2 + 0.5);
W_1[4] = tuning_word ;
W_1[3] = tuning_word>> 8 ;
W_1[2] = tuning_word >> 16 ;
W_1[1] = tuning_word >> 24 ;
W_1[0] = 0x00 ;

FU_UD = 0 ; // initializare incarcare date

for( i = 0 ; i < 5 ; i++ )
{
data_DDS = W_1[ i ] ;
W_CLK = 1 ; // incarca un cuvant
W_CLK = 0 ;
}
FU_UD = 1 ; // finalizare incarcare date

}







void main() {
OSCCON = 0x77 ;
ansel = 0 ;
anselh = 0 ;
TRISA.RA0 = 0 ;
TRISA.RA1 = 0 ;
TRISA.RA2 = 0 ;
TRISC = 0 ;
DDS_RESET() ;

while(1)
{

parallel_DDS( 1000 ) ;
}

}




This is the code in Mickro C working fine loading the data parallel in DDS which is outputting a 1kHz square wave.
For some reason in the thread I started the DDS_RESET() function didn't copied, but in the MPLAB program it is also called before the while(1) just like in this one.
 

AlbertHall

Joined Jun 4, 2014
9,899
OK, next attempt:
In Mikro C a long double is a 32 bit float.
In XC8 it may be 24 or 32 bit.
Check production / set project configuration / customize / XC8 Linker / memory model, and make sure the size of double is set to 32 bits.
 
tuning_word = (uint32_t) ((freq /fs) * pow_2 + 0.5);
I confess I've never done any PICs with C, but my experience with floating point in other stuff makes me wonder if this line is being interpreted differently between the two compilers. Would the 0.5 actually be automatically cast to the right data type?
Maybe break it down into steps and see where that goes...

Can you send hard coded values to the DAC and make it work?
 

XC8_Mark

Joined Apr 16, 2020
1
Contzo,

Thanks for using XC8!

First, the file to include is xc.h, not XC8.h. Next, You are redefining RESET. XC8 has a macro that will cause the micro to do a reset. Depending on where xc.h is in relation to your definition, you could be getting the wrong macro.

I would also do something like:

long double pow_2 = 4.29E9;
long double fs = 1.25E8;

Depending on the precision you need. Using the constants you have, you should be getting a warning that the compiler does not support 64-bit integers on the target architecture. I also would not use floats as they are very expensive on this micro in terms of code size and execution speed. You would be able to uint_64_t if you switched to a newer chip.

One other thing. You are showing the configuration separate from your code. Did you cut and paste it into your file? The CONFIG Bits view in MPLAB X IDE does not set these for you, but give you the code to use in your project.

Mark.
 

Thread Starter

Contzo

Joined Apr 16, 2020
6
Contzo,

Thanks for using XC8!

First, the file to include is xc.h, not XC8.h. Next, You are redefining RESET. XC8 has a macro that will cause the micro to do a reset. Depending on where xc.h is in relation to your definition, you could be getting the wrong macro.

I would also do something like:

long double pow_2 = 4.29E9;
long double fs = 1.25E8;

Depending on the precision you need. Using the constants you have, you should be getting a warning that the compiler does not support 64-bit integers on the target architecture. I also would not use floats as they are very expensive on this micro in terms of code size and execution speed. You would be able to uint_64_t if you switched to a newer chip.

One other thing. You are showing the configuration separate from your code. Did you cut and paste it into your file? The CONFIG Bits view in MPLAB X IDE does not set these for you, but give you the code to use in your project.

Mark.
First I want to thank you all for your responses, I defined RES_B instead of RESET and it works fine. Thank you very much for the info !
 
Top