CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

AD issue for 16F877A

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
anson



Joined: 27 Apr 2009
Posts: 6

View user's profile Send private message

AD issue for 16F877A
PostPosted: Wed Apr 29, 2009 5:28 am     Reply with quote

hi guys, does anyone have any idea why my PIC only can work when the R0 input voltage is bigger than 1 V?
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Wed Apr 29, 2009 5:37 am     Reply with quote

Repeat the question and specify details.
Question you asked is like this: Can anybody tell mi why my car doesn't work.
anson



Joined: 27 Apr 2009
Posts: 6

View user's profile Send private message

PostPosted: Wed Apr 29, 2009 5:43 am     Reply with quote

sorry man. what i mean is when the input voltage of R0 is less than 1V the PIC totally not working, but while i increase the voltage more than 1V , then it can work. i dont know how to solve it.
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Wed Apr 29, 2009 5:50 am     Reply with quote

Well first of all, do you measure voltage directly on pin?
How is your reference voltage specified?
How did you set the conversion clock?

If you have VDD-VSS reference and 255 resolution than the minimal voltage, that would register on pin would be in case of 5V power: 5V / 255 = 0,0196 volts.
anson



Joined: 27 Apr 2009
Posts: 6

View user's profile Send private message

PostPosted: Wed Apr 29, 2009 5:55 am     Reply with quote

yap. i use Vdd which is 5V as my reference voltage and since for PIC 16F877A the ADC results is a 10 bits number so for my case is 5/0x3FF. and i connect RA0 directly to the input voltage. i think i should not float it right?
anson



Joined: 27 Apr 2009
Posts: 6

View user's profile Send private message

PostPosted: Wed Apr 29, 2009 5:58 am     Reply with quote

here is my code
Code:
void adinitial_voltage(void)
{
//   unsigned int AD_data[5]={0,0,0,0,0};
   unsigned int i=0,j=0,temp=0;
    for(j=0;j<=4;++j)
   {
      ADCON0=0B01000001;
      ADCON1=0B11101110;
        ADGO=1;
        while(ADGO);
         adresult.adre[0]=ADRESL;
            adresult.adre[1]=ADRESH;
            AD_data[j]=adresult.y1;
   }
//   unsigned char AD_max=AD_data[0];
//   unsigned char AD_min=AD_data[0];
//ADC=0;
//for(i=0;i<18;i++)
//{
//   if(AD_data[i]>AD_max)
//      {
//         AD_max=AD_data[i];
//        }            
//   else if(AD_data[i]<AD_min)
//      {      
//         AD_min=AD_data[i];
//        }                
//    ADC+=AD_data[i];
//}
//ADC=ADC-AD_max-AD_min;
//
    for(j=0;j<=4;++j)
      if(AD_data[j]>AD_data[j+1])
         {temp=AD_data[j];AD_data[j]=AD_data[j+1];AD_data[j+1]=temp;}
   ADC=(int)temp*5/0x3FF;

//   for(j=0;j<=3;++j)
//      if(AD_data[j]<AD_data[j+1])
//         {temp=AD_data[j];AD_data[j]=AD_data[j+1];AD_data[j+1]=temp;}
//   ADC=((AD_data[0]+AD_data[1]+AD_data[2])/3)/213.20008328128253175098896523006*1000;
//   A=ADC*10;
   bai=ADC%1000/100;
   shi=ADC%100/10;
   ge=ADC%10; 
//   bai=A%10;
//   shi=A%1;
//   ge=A%1*10; 
//   delay(1);             
}
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Wed Apr 29, 2009 6:13 am     Reply with quote

Well first thing I noticed is that all variables are integers.

To be sure that AD is working correctly try to display non-converted value from AD. If this is OK, than problem is in conversion. ;)
anson



Joined: 27 Apr 2009
Posts: 6

View user's profile Send private message

PostPosted: Wed Apr 29, 2009 6:21 am     Reply with quote

yes, i just display the int number for simple. but what i dont understand is why the input voltage must be more than 1V? when RA0=0.9V,LCD displays nothing, but when RA0=1.1V,LCD displays 'voltage=1'. do you know why?
bungee-



Joined: 27 Jun 2007
Posts: 206

View user's profile Send private message

PostPosted: Wed Apr 29, 2009 7:56 am     Reply with quote

Try this:


Code:
#include <16F877A.h>
#device adc=10

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected

#use delay(clock=8000000)

#include <LCD.C>


void main()
{
   int16 adc_value;

   setup_adc_ports(AN0);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   lcd_init();

 
  while (1)
  {
      adc_value=read_adc();
      printf(lcd_putc," Val=%Lu",adc_value);
      delay_ms(500);
  }

}


If you have different freq. change code accordingly.
Guest








PostPosted: Wed Apr 29, 2009 8:20 am     Reply with quote

Anson,

Just as a matter of style, I'd like to make a few comments:

1. You posted a very imcomplete, and cryptic description of your problem
2. You posted an very incomplete piece of code with 90% of it commented out
3. You didn't even do the most basic troubleshooting yourself

You basically came to the forum and said "this doesn't work... why?"

Have all basic communications and troubleshooting skills gone right out the window??

Dave
anson



Joined: 27 Apr 2009
Posts: 6

View user's profile Send private message

PostPosted: Wed Apr 29, 2009 7:02 pm     Reply with quote

to above:
1. ok, now let me intro my issue again from starting. Basically what I want to do is using PIC to do the ADC for my current detector. Since now I am testing the ADC function, so I just connect the R0 PIN to input signal. And in order to make sure that the R0 PIN isn't floating, I connect a 4Koms resistor to it.
2. The code I post is the AD part and I think there should have no problem with the LCD display, so I didn't upload it. While I have attached my whole program below without all the commented lines.
3. Of course I had done some troubleshooting. Except the hardware connection checking, I have tried quite a lot ways to do the ADC, this you should see from the code which are commented out.
4. Hope this time I have made a clear description.
5. The crystal oscillator I used is 4MHz, capacitor is 22pF.
Code:

#include<pic.h>
union  adres
{int  y1;
unsigned  char  adre[2];
}adresult;

unsigned int ADC=0;
unsigned int AD_data[5]={0,0,0,0,0};
void adinitial_voltage(void);
const char TABLE[]={'0','1','2','3','4','5','6','7','8','9'};
const char data[3]={'0','0','0'};
#define rs RA1
#define rw RA2
#define e  RA3
const char voltage[ ]={'V','O','L','T','A','G','E','='};
unsigned char ge=0,shi=0,bai=0;
void init();
void lcd_init();
void lcd_dis();
void write_voltage();             
void write(char x);
void lcd_enable();
void delay();

void main()
{
    unsigned char a;
    init();
    while(1)
   {
      adinitial_voltage();
        lcd_init();
        for(a=10;a>=1;a--)
      {
         PORTD=0X80;               
            lcd_enable();
         delay(20);
            write_voltage();           
            PORTD=TABLE[bai];
            lcd_dis();     
            PORTD=TABLE[shi];
            lcd_dis();     
            PORTD=TABLE[ge];
            lcd_dis();
         } 
     }
 }
 

void init()
{
   ADCON1=0X0;
    TRISA=0B00000001;
    TRISD=0X00;
}

void lcd_init()
{
    PORTD=0X1;
    lcd_enable();
    PORTD=0X38;
    lcd_enable();
    PORTD=0X0c;
    lcd_enable();
    PORTD=0X06;
    lcd_enable();   
}
 

void write_voltage()
{
    unsigned char  i;
    for(i=0;i<=7;i++)
       {
         write(voltage[i]);
       }
}

void write(char x)
{
  PORTD=x;
  lcd_dis();
}

void lcd_enable()
{
   rs=0;
   rw=0;
   e=0;
   delay();
   e=1;
}

void lcd_dis()
{
   rs=1;
   rw=0;
   e=0;
   delay();
   e=1;
}
 

void delay()
{
   int i;
   for(i=0;i<50;i++);
}

void adinitial_voltage(void)
{
   unsigned int i=0,j=0,temp=0;
    for(j=0;j<=4;++j)
   {
      ADCON0=0B01000001;
      ADCON1=0B11101110;
        ADGO=1;
        while(ADGO);
         adresult.adre[0]=ADRESL;
            adresult.adre[1]=ADRESH;
            AD_data[j]=adresult.y1;
   }

    for(j=0;j<=4;++j)
      if(AD_data[j]>AD_data[j+1])
         {temp=AD_data[j];AD_data[j]=AD_data[j+1];AD_data[j+1]=temp;}
   ADC=(int)temp*5/0x3FF;

   bai=ADC%1000/100;
   shi=ADC%100/10;
   ge=ADC%10; 

}

to Bungee: I will try to edit my own code to make it work in case of Bulabula... really appreciate for your help. And maybe you can have a look at my whole program when you are free. Since I just want to make it simple so that when I do the testing I just input a DC value and display the integer number only.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Apr 29, 2009 9:36 pm     Reply with quote

This is code for the Hi-Tech C compiler. You should ask questions
about it on their forum:
http://forum.htsoft.com/all/postlist.php/Cat/0/Board/pic
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group