PIC12F675 C code doesnt work - Page 1
Forum section: electronics / general

author: ocset
author_rank: Super Contributor
timestamp: May 24, 2018, 12:02:42 pm
content: HelloDo you know why this C code for PIC12F675 doesn’t work?Its using XC8 CAll it does is make GP0 = 0 if the ADC reads the ‘busvoltage’ variable as being greater than 0x19. If the ‘busvoltage’ variable is less than 0x19 then it should make GP0 = 1;However, it does not work.I think its the ADC function doADC(); ...but i am not sure.When i don’t call the doADC function i have got it able to oscillate the GP0 output. (but i don’t want the code to do that, we want the code to read ADC and act accordingly.)Code://Main for the crammed long PCB//Each Buckboost has a PIC12F675 to control it.// PIC12F675 Configuration Bit Settings// 'C' source line config statements// CONFIG#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)#pragma config PWRTE = OFF // Power-Up Timer Enable bit (PWRT disabled)#pragma config MCLRE = OFF // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)#pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD disabled)#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 statements should precede project file includes.// Use project enums instead of #define for ON and OFF.#include <xc.h>#include <stdint.h>#include <pic12f675.h>#define _XTAL_FREQ 4000000//#define driversOff GP0 = 1//#define driversOn GP0 = 0//#define udhigh GP2 = 1//#define udlow GP2 = 0//#define cshigh GP5 = 1//#define cslow GP5 = 0uint8_t count;uint8_t count1;uint8_t count2;uint8_t busvoltage;void zeropot(void);void decrement(void);void increment(void);void doADC(void);void up5steps (void);void up35steps (void);void up64steps (void);void up5steps (void) {for (count=5; count=0; count--) {__delay_us(100);GP2 = 0; //UD = low__delay_us(100);GP2 = 1; //UD = high__delay_us(100);}return;}void up35steps (void) {for (count=35; count=0; count--) {__delay_us(100);GP2 = 0; //UD = low__delay_us(100);GP2 = 1; //UD = high__delay_us(100);}return;}void up64steps (void) {for (count=64; count=0; count--) {__delay_us(100);GP2 = 0; //UD = low__delay_us(100);GP2 = 1; //UD = high__delay_us(100);}return;}void doADC(void) {//Initiate ADRESH, ADRESLbusvoltage = 0x00;ADRESL = 0x00;__delay_us(100);ADON = 1; //Turn on ADC module__delay_ms(1);GO_DONE = 1; //start conversionwhile (GO_DONE) {;} //Wait for conversion to finish__delay_us(100);busvoltage = ADRESL;ADON = 0; //Turn off ADC module__delay_us(100);return;}void increment(void) { //GET DIGIPOT READY FOR INCREMENT__delay_us(100);GP5 = 1; //CS HIGH__delay_us(100);GP2 = 0; //UD low__delay_us(100);GP2 = 1; //UD high__delay_us(100);GP5 = 0; //CS LOW ....NOW inCREMENT__delay_us(100);return;}void decrement(void) { //GET DIGIPOT READY FOR DECREMENT__delay_us(100);GP5 = 1; //CS HIGH__delay_us(100);GP2 = 1; //UD high__delay_us(100);GP2 = 0; //UD low__delay_us(100);GP5 = 0; //CS LOW ....NOW DECREMENT__delay_us(100);return;}void zeropot(void) { //get wiper to bottom of resistor ladder, ie GND//ZERO THE DIGI POT__delay_us(100);GP5 = 1; //CS HIGH__delay_us(100);GP2 = 1; //UD HIGH__delay_us(100);GP2 = 0; //UD LOW__delay_us(100);GP5 = 0; //CS LOW ....NOW DECREMENT__delay_us(100);//Now decrement 64 timesfor (count = 65; count = 0; count--) {__delay_us(100);GP2 = 1;__delay_us(100);GP2 = 0;__delay_us(100);} //Now wiper is at the bottom.return;}void main(void) {//Setup ports//GP0 = OP SHUTDOWN; High is shutdown//GP1 = OP UNUSED OUTPUT//GP2 = OP U/D MCP4013//GP3 = IP MCLR//GP4/AN3 = IP ADC input from input rail//GP5 = OP CS MCP4013//To increment CS LOW, AFTER UD high//To decrement CS lOW AFTER UD LOW//HW SETUPGP0 = 1; //SHUTDOWNGP1 = 0; //UNUSEDGP2 = 0; //UD LOW//GP3 = INPUT//GP4 = ADC INPUTGP5 = 1; //CS HIGHTRISIO = 0x18; //ADC ININTCON = 0x00;OPTION_REG = 0xD7;CMCON = 0x07;ADCON0 = 0x0C; //0000-1100 ADCoff_noconv; ch AN3; VREF=VDD;ADON is OFF//L justANSEL = 0x68; //fosc/64, AN3,//5 second delayfor (count=1;count<=10;count++) {__delay_ms(1);}GP0 = 1; //Shutdown the led driverszeropot();increment();up64steps();GP0 = 0; //Turn on LEDsdoADC();if (busvoltage >= 0x19) {GP0 = 1;}while(1) {;}/* while(1) {GP0 = 1; //driversOff;for (count=1;count<=10;count++) {__delay_ms(100); }GP0 = 0; //driversOn;for (count=1;count<=10;count++) {__delay_ms(100); }} */return;}

author: StillTrying
author_rank: Super Contributor
timestamp: May 24, 2018, 12:49:00 pm
content: Fosc/64 is 4 times too slow ?

author: MarkF
author_rank: Super Contributor
timestamp: May 24, 2018, 01:25:38 pm
content: Define "Does not work".Does the LED stay ON or go OFF?What voltage are you checking for? (i.e. What is 0x19?)

author: Buriedcode
author_rank: Super Contributor
timestamp: May 24, 2018, 01:46:55 pm
content: You've set the result as left justified in ADCON0, and you're only checking ADRESL for > 0x19.This effectively means the lower 6 bits of ADRESL are always 0. And that the two MSB's are the two LSBs of the ADC result. So... any ADC result > 0x00 will be seen as greater than 0x19, because an ADC result of 0x0001 would read b'01000000 in ADRESL, which is clearly greater than 00011001.What you do depends on what percentage of VDD your threshold is set at. Is the 0x19 (25 decimal) 25/1024 = 2.44% of VDD? Or are you assuming you're reading the upper 8 bits of the ADC result? (0x19 is the first 8 bits of the ADC results (100/1024 = 9.77%of VDD)If you're just reading the lower 8 bits of the result then change ADCON0 to 0x1C for right justified. Otherwise read ADRESH for busvoltage.

author: SiliconWizard
author_rank: Super Contributor
timestamp: May 24, 2018, 02:29:16 pm
content: You don't like function parameters, or functions that return a value, do you?(Oh, and a return statement at the end of a C function returning void is completely useless.)And yes, there additionally seems to be a problem with the ADC sample format you are using as Buriedcode said.But just looking at this piece of code makes me sad. I'm going to need a shot of whiskey.

author: ocset
author_rank: Super Contributor
timestamp: May 24, 2018, 06:57:11 pm
content: QuoteThankyou very much, i was taking "ADRESL" as meaning "ADRESS LEFT" instead of "ADDRESS LOW".Your help is much appreciated.

author: Howardlong
author_rank: Super Contributor
timestamp: May 25, 2018, 06:25:14 pm
content: I think it’s supposed to be a short form for ADc RESult Low rather than ADdRESs Low.

author: hexreader
author_rank: Frequent Contributor
timestamp: May 25, 2018, 07:12:56 pm
content: Code:for (count=35; count=0; count--) {This looks completely wrong to me. Try...Code:for (count = 35 ; count > 0; count--) {And same change for the other similar functions.

author: Howardlong
author_rank: Super Contributor
timestamp: May 25, 2018, 10:05:44 pm
content: Quote from: hexreader on May 25, 2018, 07:12:56 pmGood spot.