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.

Pic18F14k50 - ADC causing pic to hang? Possible?

Status
Not open for further replies.

krich

New Member
I'm having an odd issue with my PIC18F14K50 chip and have basically ignoring for a while. I'm to a point in my project where I can't ignore it anymore and my best (admittedly feeble) troubleshooting skills have not revealed the cause.

I have a small bit of code (displayed below) that initializes the USART and the ADC, and then goes into the main loop. The main loop simply samples the ADC a number of times, finds the maximum value over that period, performs some calculations on the max number and then uses printf to dump the results to the USART. Rinse, Repeat.

The input to the is a current transformer fed through a full wave rectifier and gain=1 peak detector circuit. The voltage input is roughly proportional to the current passing through the transformer coil. I've spent quite a bit of time making sure that it is correct and I've double and triple checked it with my scope and dummy loads and it's showing the proper voltage levels (max 1V @ ~16.5A).

Here's my issue:

When I power on the PIC, it runs through the main loop a few times and then hangs. Reset it and it runs a few more times and then quits. Reset it again and it runs through the main loop once and dies. The number of times through the loop is inconsistent, but the hangs are almost certain. A couple times I've been able to run it for hours without issue. To troubleshoot, I installed the blinking LED, thinking it could be the USART that is simply not giving me output. Well, no. When the PIC hangs, so does the LED. This leads me to think that it could be an ADC issue (with my code), but at this point I'm not terribly sure.

I thought it might be high voltage spikes, or analog noise that could be confusing the ADC, so I've checked the output voltages and I don't see anything like that. I thought it might be something wrong with my MCLR reset pin. Nope. Different ADC channel. No go. To try to make the problem go away, I've moved off my (self made) development board onto a very bare bones breadboard setup and I still get the issue. Cry.

Here's to hoping one of you guys has seen this behavior before and can explain to me the error of my ways. Here's the full code:


#include <p18cxxx.h>
#include <usart.h>
#include <delays.h>
#include <stdlib.h>
#include <stdio.h>
#include <GenericTypeDefs.h>


/*
** PIC18LF14K50 Configuration Bit:
**
** FOSC = IRC - Internal RC Oscillator
** CPUDIV = NOCLKDIV - No CPU System Clock divide
** PLLEN = OFF - PLL is under software control
** FCMEN = OFF - Fail-Safe Clock Monitor disabled
** BOREN = OFF - Brown-out Reset disabled in hardware and software
** WDTEN = OFF - WDT is controlled by SWDTEN bit of the WDTCON register
** MCLRE = ON - MCLR pin enabled, RE3 input pin disabled
** LVP = OFF - Single-Supply ICSP disabled
*/
#pragma config FOSC = IRC, CPUDIV = NOCLKDIV, PLLEN = OFF
#pragma config FCMEN = OFF, BOREN = OFF
#pragma config WDTEN = OFF, MCLRE = ON, LVP = OFF


void delay_ms (unsigned int ms) // approximate
{
do {
Delay1KTCYx(4);
} while(ms--);
}

void delay_us (unsigned int us) {
do {
Delay1TCY();
Delay1TCY();
Delay1TCY();
Delay1TCY();
} while (us--);
}

void printfloat(float x) {
unsigned long v1 = 0;
unsigned long v2 = 0;

v1 = (long)((float)x);
v2 = (long)((float)x * 1000) - (v1 * 1000);
printf((rom far char*)"%li.%03li",v1,v2);
}

void main(void)
{

UINT16 result = 0;
UINT16 c = 0;
UINT16 i = 0;
float volts = 0;
float voltsrms = 0;
float v = 0.001;
UINT16 max = 0;
float a = 0.0141; // Irms = 0.098, I = 0.0141
float amps = 0;
float ampsrms = 0;

// Select 16MHz Clock
OSCCONbits.IRCF2=1;
OSCCONbits.IRCF1=1;
OSCCONbits.IRCF0=1;

// Initialize ports
TRISA &= ~(0x20); // Set RA5 port to output
LATA |= 0x20; // Init RA5 port to high (LED off)

// configure USART
OpenUSART( USART_TX_INT_OFF &
USART_RX_INT_OFF &
USART_ASYNCH_MODE &
USART_EIGHT_BIT &
USART_CONT_RX &
USART_BRGH_HIGH,
25 );

// ADC Initialization

// Using AN7 which is RC3 and is pin7 on the dip version of the pic18F14K50

ANSEL = 0x00; // enable digital input buffer
ANSELH = 0x00; // enable digital input buffer
ANSELbits.ANS7=1; // disable digital input buffer on AN3 only

TRISC = 0x00;
TRISCbits.TRISC3=1; // set port direction to input, disable output driver

ADCON0bits.CHS3=0; // ADC port channel 7 (AN7)
ADCON0bits.CHS2=1;
ADCON0bits.CHS1=1;
ADCON0bits.CHS0=1;
ADCON0bits.ADON=1; // Enable ADC

REFCON0bits.FVR1EN=1; // Enable Fixed Voltage Reference
REFCON0bits.FVR1S1=0; // Select voltage 01=1v, 10=2v, 11=4v
REFCON0bits.FVR1S0=1;
ADCON1=0x00;
ADCON1bits.PVCFG1=1; // Use Internal Fixed Voltage Reference for Positive Reference
ADCON1bits.PVCFG0=0;
ADCON1bits.NVCFG1=0; // Use Vss for Negative Reference
ADCON1bits.NVCFG0=0;

ADCON2bits.ADFM=1; // Right justify result = 1; Left justify result = 0;
ADCON2bits.ACQT2=1; // 20 TAD
ADCON2bits.ACQT1=1;
ADCON2bits.ACQT0=1;
ADCON2bits.ADCS2=0; // Select Fosc/64
ADCON2bits.ADCS1=1;
ADCON2bits.ADCS0=1;

while(1)
{
result = 0;
max = 0;
volts = 0.0;
c++;

for (i = 0; i < 200; i++) {
delay_us(500);
ADCON0bits.GO=1;
while (ADCON0bits.GO); // Wait conversion done

result = ADRESH;
result = (result << 8);
result += ADRESL;

if (result > max) max = result;
}

volts = max * (float)v;
voltsrms = volts * 0.7;
amps = max * (float)a;
ampsrms = amps * 0.7;

printf((rom far char*)"%d (%d): V: ",c, max);
printfloat(volts);
printf((rom far char*)", I: ");
printfloat(amps);
printf((rom far char*)", Vrms: ");
printfloat(voltsrms);
printf((rom far char*)", Irms: ");
printfloat(ampsrms);
printf((rom far char*)"\r\n");
//LATA ^= 0x20;

}
}


 
Last edited:
Do you have a Microchip programmer which also has in-circuit debugging like the PICkit 3? And also using MPLAB?

If yes, then that helps me a lot to find problems. Perhaps you could stop it when it hangs and see where in the program it is at when you stop it. Also you can use break points.
 
Remember your PIC GPIO comes up randomised. Isolate that u haven't assumed a startup zero value by clearing all your GPIO variables with a loop as the first item to do when u pwr up. I had a simailar situation 2 weeks ago and that was partially responsible. The other issue was the PGM pin. A new pic comes with PGM /LVP enabled. Thus u have to ensure that your config forces LVP_OFF otherwise the PGM pin can float hi and send the pic in prg mode. If u not using the PGM PIN gnd it with a 10K .
 
Thanks guys. Good thoughts, but at the end of the day, we should all remember to read the silicon errata. In my case,

When the ADC is configured to operate with the internal FRC oscillator (ADCON2<2:0> = X11) and the device is not in Sleep, then the ADC may fail to complete the conversion which is indicated by the GO/DONE bit of the ADCON0 register remaining in the GO state indefinitely.​

and

Under certain device operating conditions, the ADC conversion may not complete properly. When this occurs, the ADC Interrupt Flag (ADIF) does not get set, the ADGO/ DONE bit does not get cleared, and the conversion result does not get loaded into the ADRESH and ADRESL result registers.​

Problem solved. Lesson learned. Time to go find another MCU...
 
I read where some people were have same problem they change oscillator setting. I got some for the usb haven't tried adc
 
...The other issue was the PGM pin. A new pic comes with PGM /LVP enabled. Thus u have to ensure that your config forces LVP_OFF otherwise the PGM pin can float hi and send the pic in prg mode. If u not using the PGM PIN gnd it with a 10K .
Just make sure the LVP is off and forget the resistor. Or did you say that?
 
Read the datasheet Sheet Errata There a problem with that chip ADC It can some how not finish a conversion and locks the chip microchip fixed it if you have newer chips some with v8 on there label
 
  • Like
Reactions: 3v0
Status
Not open for further replies.

Latest threads

Back
Top