Author Topic: PIC16F877A problem in code  (Read 2326 times)

0 Members and 1 Guest are viewing this topic.

Offline VEGETATopic starter

  • Super Contributor
  • ***
  • Posts: 1946
  • Country: jo
  • I am the cult of personality
    • Thundertronics
PIC16F877A problem in code
« on: April 29, 2013, 09:16:31 pm »
I made the following code in mikroC for PIC16F877A

Code: [Select]
float  v, v1, v2, v_peak;
unsigned int adc1, adc2;
unsigned char l_byte, h_byte;
char ch1[5], ch2[5];
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 connections
sbit 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 variables
char txt1[] = "V1 = ";
char txt2[] = "V2 = ";
char txt3[6] = "    ";
char txt4[6] = "    ";
char txt5[] = "V RMS";



unsigned int ADCRead(unsigned short channel){

        if (channel == 0) {ADCON0 = 0x81;}          // convert from channel0
        if (channel == 1) {ADCON0 = 0x89;}          // convert from channel1

        delay_us(80);                               // Acquisition Delay
        GO_DONE_bit = 1;                            // Set GO_DONE bit to start conversion
        while (GO_DONE_bit == 1);                   // Wait for bit to be cleared
                                                    // If bit is cleared, conversion is over
        l_byte = ADRESL;
        h_byte = ADRESH;
        ADR = (h_byte<<8)|l_byte;
        return ADR;
}

float RMS_calculator (unsigned short source) {

  channel = source;                       // pick source
  adc = ADCRead(channel);                 // read ADC value
  v = (adc*0.00488*7.66);                 // Determine voltage at ADC pin
  if ( v < 0.11 ) {v = v*0.707*18.3;}    // calculate RMS value
    else {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_2
               delay_ms(40);                             // wait 30ms
               source_1 = 1;                             // activate source_1
               source_2_on = 0;                          // source_2_on LED is OFF
               source_1_on = 1;                          // source_1_on LED is ON
               no_active_source = 0;                     // no_active_source LED is OFF
               break;
               }

        case 2:
               {
                source_1 = 0;                             // deactivate source_1
                delay_ms(40);                             // wait 30ms
                source_2 = 1;                             // activate source_2
                source_1_on = 0;                          // source_1_on LED is OFF
                source_2_on = 1;                          // source_2_on LED is ON
                no_active_source = 0;                     // no_active_source LED is OFF
                break;
                }
               
        case 3:
               {
                source_1 = 0;                               // source_1 off
                source_2 = 0;                               // source_2 off
                no_active_source = 1;                       // no_active_source LED is ON
                source_1_on = 0;                            // source_1_on LED is OFF
                source_2_on = 0;                            // source_2_on LED is OFF
                break;
                }
      }



}

void main() {


        CMCON = 7; //Disable comparator

        PORTA = 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 0xCE
        INTE_bit = 0;

        source_1 = 0;                             // source_1 off
        source_2 = 0;                             // source_2 off
        source_1_on = 0;                          // source_1_on LED is OFF
        source_2_on = 0;                          // source_2_on LED is OFF
        no_active_source = 1;                     // no_active_source LED is OFF
        v1 = 0;
        v2 = 0;
        adc1 = 0;
        adc2 = 0;
        current_status = 3;
        apply_status();
       
        /// LCD initialization ///
       
        Lcd_Init();                        // Initialize LCD
        delay_ms(10);
        Lcd_Cmd(_LCD_CLEAR);               // Clear display
        delay_ms(10);
        Lcd_Cmd(_LCD_CURSOR_OFF);          // Cursor off
        delay_ms(10);
        Lcd_Out(1,1,txt1);                 // Write text in first row
        delay_ms(10);
        Lcd_Out(2,1,txt2);                 // Write text in second row

       
       
       
      // option_reg=0b00101111;
while (1){
         prev_status = current_status;
        // calculate channel0 voltage

        v1 = RMS_calculator (0);
        //adc1 = ADR;




                             // calculate channel1 voltage
        v2 = RMS_calculator (1);
       // adc2 = ADR;

       
       

        current_status = check_status();
        if ( current_status != prev_status ) { apply_status(); }
        delay_ms(100);

       // display v1
       floattostr(v1,ch1);
       txt3[0] = ch1[0];
       txt3[1] = ch1[1];
       txt3[2] = ch1[2];
       txt3[3] = ch1[3];
       txt3[4] = ch1[4];
       
       Lcd_Out(1,6,txt3);
       delay_ms(10);
       Lcd_Out(1,12,txt5);
       
       
       
       // display v2
       floattostr(v2,ch2);
       txt4[0] = ch2[0];
       txt4[1] = ch2[1];
       txt4[2] = ch2[2];
       txt4[3] = ch2[3];
       txt4[4] = ch2[4];

       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.







Offline glatocha

  • Regular Contributor
  • *
  • Posts: 114
Re: PIC16F877A problem in code
« Reply #1 on: May 04, 2013, 02:57:52 am »
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: [Select]
current_status = 1;
apply_status();

Then you can check is the output problem or somewhere is ADC conversion or status selection.
 

Offline Skimask

  • Super Contributor
  • ***
  • Posts: 1433
  • Country: us
Re: PIC16F877A problem in code
« Reply #2 on: May 04, 2013, 04:22:12 am »
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.
I didn't take it apart.
I turned it on.

The only stupid question is, well, most of them...

Save a fuse...Blow an electrician.
 

Offline AlfBaz

  • Super Contributor
  • ***
  • Posts: 2184
  • Country: au
Re: PIC16F877A problem in code
« Reply #3 on: May 04, 2013, 09:29:49 am »
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.
 

Offline glatocha

  • Regular Contributor
  • *
  • Posts: 114
Re: PIC16F877A problem in code
« Reply #4 on: May 04, 2013, 10:41:09 am »
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.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf