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

PIC10F322 A/D Converter Problems

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



Joined: 10 Jan 2013
Posts: 5

View user's profile Send private message

PIC10F322 A/D Converter Problems
PostPosted: Thu Jan 10, 2013 1:31 pm     Reply with quote

OK, I'm new to this so please be gentle Smile

I have a Microchip PIC10F322 Dev Kit (AC103011) and can't get the A/D to work at all. I've tried my code to flash leds without the A/D etc. and that seems ok.

Am I missing something real obvious as this should be pretty basic I think. I've searched the forums but found nothing specific to the 10F3XX series.

Compiler Version: PCM 4.140
Target: PIC10F322
Run Mode: Standard
Target Voltage: 5VDC powered from ICD3
Target Oscillator: 8MHz internal RC
Code:

#include <10F322.h>
#device adc=8

#FUSES NOWDT               //No Watch Dog Timer
#FUSES INTRC               //Internal RC Osc
#FUSES NOBROWNOUT          //No brownout reset
#FUSES NOPUT               //No Power Up Timer
#FUSES NOMCLR              //No MCLR - Used For I/O
#FUSES NOPROTECT           //No Code Protect From Reading
#FUSES NOLVP               //No Low Voltage Programming
#FUSES NOLPBOR             //No Low Power Brown Out Reset
#FUSES NOWRT               //No Program Memory Write Protect
#FUSES NODEBUG             //No ICD Debug

#use delay(int=8000000)

#define LED_RED PIN_A0
#define LED_GREEN PIN_A1
#define DELAY 500

#ZERO_RAM

unsigned int8 i;
unsigned int8 value;

void main()
{

SETUP_WDT(WDT_OFF);
SETUP_CLC1(CLC_DISABLED);

   set_tris_a(0b1100);
   setup_adc_ports(sAN2);
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel(sAN2);

   output_low(LED_RED);
   output_low(LED_GREEN);

   enable_interrupts(INT_AD);
   enable_interrupts(GLOBAL);

   do {
//
//         for(i=0; i<8; ++i)
//            {
//               delay_ms(DELAY);
//               value = i;
//               delay_ms(DELAY);
//               output_toggle(LED_GREEN);
//               if(value<4)
//                  output_low(LED_RED);
//               if(value>=4)
//                  output_high(LED_RED);
//            }
//
               delay_ms(100);
//               value = Read_ADC();
               value=read_adc(ADC_START_AND_READ);
               delay_ms(100);
               output_toggle(LED_GREEN);
               if(value<127)
                  output_low(LED_RED);
               if(value>=127)
                  output_high(LED_RED);
               value=0;

      } while (TRUE);
}

Any help would be very much appreciated, and apologies in advance if this is something really obvious, I'm just starting out!

Thanks
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Thu Jan 10, 2013 1:46 pm     Reply with quote

I looked at this briefly so: there might be more things...

I suggest you remove:
Code:
   set_tris_a(0b1100);

and let the compiler handle that.


Make sure you are providing your ADC with the right TAD (See Datasheet)
Code:
   setup_adc(ADC_CLOCK_INTERNAL);



I see logical issues/problems:

once you read your ADC and set your "LED_RED" to what ever state, your main loop goes back to the FOR loop which ALSO writes to the "LED_RED" so you will overwrite the State of the LED immediatly after you set it, but based on the conditions set by the FOR loop and not the ADC


make your code SMALLER... remove all the Flashing LED code or place that OUTSIDE of the infinite loop... and try to use diferent pins for status and result outputs.... (so that you avoid the logical issues i mentioned above)

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Thu Jan 10, 2013 1:49 pm     Reply with quote

... i just noticed you had half the program commented out... sorry.


Code:
   enable_interrupts(INT_AD);


where is the ISR? and why are you using this?
_________________
CCS PCM 5.078 & CCS PCH 5.093
needmoresleep



Joined: 10 Jan 2013
Posts: 5

View user's profile Send private message

PostPosted: Thu Jan 10, 2013 3:06 pm     Reply with quote

Thanks for taking the time to reply Gabriel.

I left the commented code in (for reference), as thats the code I got the LEDS to flash with.

I've tried it with and without setting the tris_a register, prior to posting, but it didn't work either way. In fact I think the LEDs wouldn't flash unless I set them - I think I've read somewhere they default to analog.

enable_interrupts (INT_AD) and enable_interrupts (global) was a last ditch attempt to try to get it working, as I wasn't sure they were needed. Again it didn't seem to work either way.

I wasn't sure if using the internal ADC clock in conjunction with the read_adc(ADC_START_AND_READ) function meant that it tested the 'conversion done' bit in the SFR and therefore waited the required time. I also added (again rightly or wrongly) the use_delay() before and after the read_adc().
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Thu Jan 10, 2013 3:24 pm     Reply with quote

havent tested this...

but i cleaned it for you (too much clutter) and changed what i think is wrong...


Code:
#include <10F322.h>
#device adc=8

#FUSES NOWDT               //No Watch Dog Timer
#FUSES INTRC               //Internal RC Osc
#FUSES NOBROWNOUT          //No brownout reset
#FUSES NOPUT               //No Power Up Timer
#FUSES NOMCLR              //No MCLR - Used For I/O
#FUSES NOPROTECT           //No Code Protect From Reading
#FUSES NOLVP               //No Low Voltage Programming
#FUSES NOLPBOR             //No Low Power Brown Out Reset
#FUSES NOWRT               //No Program Memory Write Protect
#FUSES NODEBUG             //No ICD Debug

#use delay(int=8000000)    // <-----------------8MHZ so your TAD is probably wrong.

#define LED_RED PIN_A0
#define LED_GREEN PIN_A1
#define DELAY 500

#ZERO_RAM


unsigned int8 value;

void main()
{

   SETUP_ADC_PORTS(sAN2);               // Select Analog channels on PIC
   SETUP_ADC(ADC_CLOCK_DIV_16);         // Should be the right TAD/clock     <---8MHZ

   output_low(LED_RED);


   While(1)            // I dont like Do/while
   {

               delay_ms(100);       
               value = Read_ADC();

               output_toggle(LED_GREEN);// toggle for ON confirmation
 
               if(value<127)
                  output_low(LED_RED);
               if(value>=127)
                  output_high(LED_RED);
               value=0;
         }
}


try that...

G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
needmoresleep



Joined: 10 Jan 2013
Posts: 5

View user's profile Send private message

PostPosted: Thu Jan 10, 2013 4:20 pm     Reply with quote

Thanks again for your help Gabriel.

I don't think I've fully understood the TAD delays and how the ADC clock influences them. I'll read up some more on them.

If I wanted to setup 2 analog channels (to compare the results) I presume I would add code such as:

Code:

SETUP_ADC_PORTS(sAN1);   //set RA1 as analog I/P
SETUP_ADC_PORTS(sAN2);   //set RA2 as analog I/P

set_adc_channel(1);             //select ADC channel 1
dealy_uS(100);                    //a little delay for ADC channel changeover
value1 = Read_ADC();         //store ADC channel 1 value in 'value1'
set_adc_channel(2);             //select ADC channel 2
dealy_uS(100);                    //same as for channel 1
value2 = Read_ADC();         //same as for channel 1


Does that look correct?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jan 10, 2013 5:33 pm     Reply with quote

Quote:
SETUP_ADC_PORTS(sAN1); //set RA1 as analog I/P
SETUP_ADC_PORTS(sAN2); //set RA2 as analog I/P

Does that look correct?

No. See this post:
http://www.ccsinfo.com/forum/viewtopic.php?t=42766&start=1

Quote:

#define LED_GREEN PIN_A1

SETUP_ADC_PORTS(sAN1);

The green LED and the analog input are assigned to the same pin.
That's not going to work. Get a larger PIC with more pins.
needmoresleep



Joined: 10 Jan 2013
Posts: 5

View user's profile Send private message

PostPosted: Fri Jan 11, 2013 5:18 am     Reply with quote

I've tried the single ADC channel code suggested and still it doesn't work Sad

I've also tried setting the ADC clock to DIV_8 (for 1uS) and DIV_32 (for 4uS) and still no joy...

I then tried setting the TRIS_A to 0x04, no joy

and then SETUP_ADC_PORTS(sAN2), again no joy...

Could it be incorrect fuse settings or maybe an issue with the compiler??

Please help Sad
Ttelmah



Joined: 11 Mar 2010
Posts: 19349

View user's profile Send private message

PostPosted: Fri Jan 11, 2013 6:13 am     Reply with quote

Gabrel's code should work, except he doesn't select the ADC channel.

Compiling this with that one change, gives:
Code:

....................    SETUP_ADC_PORTS(sAN2);               // Select Analog channels on PIC
002C:  MOVLW  04
002D:  MOVWF  08
....................    SETUP_ADC(ADC_CLOCK_DIV_16);         // Should be the right TAD/clock     <---8MHZ
002E:  BSF    1F.5
002F:  BCF    1F.6
0030:  BSF    1F.7
0031:  BSF    1F.0
....................    SET_ADC_CHANNEL(2);
0032:  MOVLW  08
0033:  MOVWF  41
0034:  MOVF   1F,W
0035:  ANDLW  E3
0036:  IORWF  41,W
0037:  MOVWF  1F
....................    output_low(LED_RED);
0038:  BCF    06.0
0039:  BCF    05.0
.................... 
.................... 
....................    While(1)            // I dont like Do/while
....................    {
.................... 
....................                delay_ms(100);       
003A:  MOVLW  64
003B:  MOVWF  45
003C:  GOTO   004
....................                value = Read_ADC();
003D:  BSF    1F.1
003E:  BTFSC  1F.1
003F:  GOTO   03E
0040:  MOVF   1E,W
0041:  MOVWF  44


Which all looks correct. Sets the right bits to select the channel, correct bits to start conversion, and detect it has finished, etc..

Best Wishes
needmoresleep



Joined: 10 Jan 2013
Posts: 5

View user's profile Send private message

PostPosted: Fri Jan 11, 2013 6:28 am     Reply with quote

It works Very Happy Very Happy Very Happy Very Happy Very Happy

I had thought that the channel needed to be set but I posted the wrong line that I had tested...

"and then SETUP_ADC_PORTS(sAN2), again no joy... "

but I actually tested

SET_ADC_CHANNEL(sAN2);
Which gave me:
0032: MOVLW 10

I changed it to:
SET_ADC_CHANNEL(2);
Which gave me:
0032: MOVLW 08

and it works!!!!

Thank you Ttelmah Very Happy

And thank you Gabriel Very Happy

I nearly ran out of time and gave up!
Gabriel



Joined: 03 Aug 2009
Posts: 1067
Location: Panama

View user's profile Send private message

PostPosted: Fri Jan 11, 2013 6:45 am     Reply with quote

glad to hear it works!

@Ttelmah: indeed i missed selecting the channel, i just noticed i removed the channel select line when cleaning up his code by mistake... nice catch!


Quick Note:
Test your code--
Code:
dealy_uS(100);                    //same as for channel 1




G.
_________________
CCS PCM 5.078 & CCS PCH 5.093
Ttelmah



Joined: 11 Mar 2010
Posts: 19349

View user's profile Send private message

PostPosted: Fri Jan 11, 2013 7:07 am     Reply with quote

That type of 'miss', is the commonest one from reasonably experienced programmers 'typing untested', straight to the board. Have done exactly the same thing on many occasions. I did the 'proof reading', realised this was missing, then thought I'd double check the compiler was generating correct values.

Best Wishes
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