PIC16F877A problem in code - Page 1
Forum section: electronics / general

author: VEGETA
author_rank: Super Contributor
timestamp: April 29, 2013, 09:16:31 pm
content: I made the following code in mikroC for PIC16F877ACode:float v, v1, v2, v_peak;unsigned int adc1, adc2;unsigned char l_byte, h_byte;char ch1, ch2;float ADR, adc;unsigned short channel;unsigned short current_status, prev_status;/////* Definitions */////#define v_rms_min 190 // lowest alloable RMS voltage#define source_1 RD0_bit // source_1 @ pin RD0#define source_2 RD1_bit // source_2 @ pin RD1#define no_active_source RD2_bit // no_active_source indication LED @ pin RD2#define source_1_on RD3_bit // source_1_on indication LED @ pin RD3#define source_2_on RD4_bit // source_2_on indication LED @ pin RD4// LCD module connectionssbit LCD_RS at RB4_bit;sbit LCD_EN at RB5_bit;sbit LCD_D4 at RB0_bit;sbit LCD_D5 at RB1_bit;sbit LCD_D6 at RB2_bit;sbit LCD_D7 at RB3_bit;sbit LCD_RS_Direction at TRISB4_bit;sbit LCD_EN_Direction at TRISB5_bit;sbit LCD_D4_Direction at TRISB0_bit;sbit LCD_D5_Direction at TRISB1_bit;sbit LCD_D6_Direction at TRISB2_bit;sbit LCD_D7_Direction at TRISB3_bit;// End LCD module connections// LCD text variableschar txt1[] = "V1 = ";char txt2[] = "V2 = ";char txt3 = " ";char txt4 = " ";char txt5[] = "V RMS";unsigned int ADCRead(unsigned short channel){if (channel == 0) {ADCON0 = 0x81;} // convert from channel0if (channel == 1) {ADCON0 = 0x89;} // convert from channel1delay_us(80); // Acquisition DelayGO_DONE_bit = 1; // Set GO_DONE bit to start conversionwhile (GO_DONE_bit == 1); // Wait for bit to be cleared// If bit is cleared, conversion is overl_byte = ADRESL;h_byte = ADRESH;ADR = (h_byte<<8)|l_byte;return ADR;}float RMS_calculator (unsigned short source) {channel = source; // pick sourceadc = ADCRead(channel); // read ADC valuev = (adc*0.00488*7.66); // Determine voltage at ADC pinif ( v < 0.11 ) {v = v*0.707*18.3;} // calculate RMS valueelse {v = (v+1.2)*0.707*18.3;}return v;}unsigned short check_status() {if ( v1 >= v_rms_min ) { current_status = 1; }else {if ( v2 >= v_rms_min ) { current_status = 2; }else { current_status = 3; }}return current_status;}void apply_status() {switch ( current_status ) {case 1:{source_2 = 0; // deactivate source_2delay_ms(40); // wait 30mssource_1 = 1; // activate source_1source_2_on = 0; // source_2_on LED is OFFsource_1_on = 1; // source_1_on LED is ONno_active_source = 0; // no_active_source LED is OFFbreak;}case 2:{source_1 = 0; // deactivate source_1delay_ms(40); // wait 30mssource_2 = 1; // activate source_2source_1_on = 0; // source_1_on LED is OFFsource_2_on = 1; // source_2_on LED is ONno_active_source = 0; // no_active_source LED is OFFbreak;}case 3:{source_1 = 0; // source_1 offsource_2 = 0; // source_2 offno_active_source = 1; // no_active_source LED is ONsource_1_on = 0; // source_1_on LED is OFFsource_2_on = 0; // source_2_on LED is OFFbreak;}}}void main() {CMCON = 7; //Disable comparatorPORTA = 0;TRISA = 0xff;PORTD = 0;TRISD = 0;PORTC = 0;TRISC = 0;PORTB = 0;TRISB = 0;ADCON0 = 0x81;ADCON1 = 0xC0; // all portA pins are analog // was 0xCEINTE_bit = 0;source_1 = 0; // source_1 offsource_2 = 0; // source_2 offsource_1_on = 0; // source_1_on LED is OFFsource_2_on = 0; // source_2_on LED is OFFno_active_source = 1; // no_active_source LED is OFFv1 = 0;v2 = 0;adc1 = 0;adc2 = 0;current_status = 3;apply_status();/// LCD initialization ///Lcd_Init(); // Initialize LCDdelay_ms(10);Lcd_Cmd(_LCD_CLEAR); // Clear displaydelay_ms(10);Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor offdelay_ms(10);Lcd_Out(1,1,txt1); // Write text in first rowdelay_ms(10);Lcd_Out(2,1,txt2); // Write text in second row// option_reg=0b00101111;while (1){prev_status = current_status;// calculate channel0 voltagev1 = RMS_calculator (0);//adc1 = ADR;// calculate channel1 voltagev2 = RMS_calculator (1);// adc2 = ADR;current_status = check_status();if ( current_status != prev_status ) { apply_status(); }delay_ms(100);// display v1floattostr(v1,ch1);txt3 = ch1;txt3 = ch1;txt3 = ch1;txt3 = ch1;txt3 = ch1;Lcd_Out(1,6,txt3);delay_ms(10);Lcd_Out(1,12,txt5);// display v2floattostr(v2,ch2);txt4 = ch2;txt4 = ch2;txt4 = ch2;txt4 = ch2;txt4 = ch2;Lcd_Out(2,6,txt4);delay_ms(10);Lcd_Out(2,12,txt5);}}RD0_pin should be ON when 5v is at RA0.RD1_pin should be ON when 5v is at RA1 and no voltage at RA0.RD2_pin is ON when no voltage at RA0 and RA1.the problem is RD0_pin won't go ON at it's condition! and the other 2 ones are correct!I ran the simulation in Proteus ISIS, and it worked but made some errors... like the following:so what happens?please check my subroutine called check_status because it's the one that decide which pin to be active.I attached the hex file.

author: glatocha
author_rank: Regular Contributor
timestamp: May 04, 2013, 02:57:52 am
content: Hi,Didn't check your code in details but on the first look it should be ok.What I would do I would first try to do the code somewhere:Code:current_status = 1;apply_status();Then you can check is the output problem or somewhere is ADC conversion or status selection.

author: Skimask
author_rank: Super Contributor
timestamp: May 04, 2013, 04:22:12 am
content: Posting a hex file is almost useless unless somebody else has the exact same conditions as you've got, e.g. same hardware, same wiring, same mistakes, etc.etc.etc.Posting an .asm file is only slightly better.

author: AlfBaz
author_rank: Super Contributor
timestamp: May 04, 2013, 09:29:49 am
content: The source listing should be good enough, so long as the op provides feedback.I to would like to see what happens if the OP tries glatocha's advice. If that works then I would be inclined to look at the compilers manual and check if there any "gotcha's" in float to int comparisons.

author: glatocha
author_rank: Regular Contributor
timestamp: May 04, 2013, 10:41:09 am
content: Another thought.You have LCD, so display yourself the value from the adc channel 0 and 1. You can check if the conversion and input is correct.I always love to have LCD on the project. Any debugging issue, just display the values and you can find quickly where is a bug.