Jump to content

A 2 D Conv.

Recommended Posts

Lets try it this way.


#include <system.h>


//Target PIC12F675 configuration word



//Set clock frequency

#pragma CLOCK_FREQ 4000000



volatile bit gp0@GPIO.0;//analog i/p

volatile bit gp1@GPIO.1;//analog i/p

volatile bit gp2@GPIO.2;//motor drive


volatile bit gp4@GPIO.4;//enable

volatile bit gp5@GPIO.5;//motor drive


#define motor_clockwise gp2 //pointer travels up

#define motor_anticlockwise gp5 //pointer travels down

#define enable gp4


unsigned char AD_Result;


void a2d (char);


void interrupt( void )


//Handle timer0 interrupt

if( intcon & (1<<T0IF) )


clear_bit( intcon, T0IF ); //clear timer 0 interrupt bit



//Handle timer1 interrupt

if( pir1 & (1<<TMR1IF) )


clear_bit( pir1, TMR1IF ); //clear timer 1 interrupt bit




void main( void )


//Configure GPIO port

trisio = 0x03;//gpio0 & gpio1 as a2d input.

gpio = 0x00;


cmcon = 0;//comparator off.

//ansel = 0;


//Set Timer0 mode

clear_bit( option_reg, T0CS ); //configure timer0 as a timer

//Set prescaler assignment

clear_bit( option_reg, PSA ); //prescaler is assigned to timer0

//Set prescaler rate

clear_bit( option_reg, PS2 ); //prescaler rate 1:2

clear_bit( option_reg, PS1 );

clear_bit( option_reg, PS0 );

//Set timer0 source edge selection

set_bit( option_reg, T0SE ); //increment on high-to-low transition on RA4/T0CKI pin


//Set timer 1 prescaler rate

clear_bit( t1con, T1CKPS1 ); //prescaler rate 1:1

clear_bit( t1con, T1CKPS0 );

//Set timer 1 mode

clear_bit( t1con, TMR1ON ); //disable timer 1


//Enable interrupts (Timer0)

intcon = 10100000b;

a2d(AD_Result);//pot i/p.

//Endless loop

while( 1 )



enable = 1;

if(AD_Result>5)//arbitory value to prove a2d returning sensible value.


motor_clockwise = 0;

motor_anticlockwise = 1;

motor_clockwise = 1;

motor_anticlockwise = 0;






void a2d (char AD_Result)










set_bit(adcon0,ADFM); // Turn on the A/D converter, select channel 0.








volatile bit Go_Done@ADCON0.1;

volatile unsigned char ad_h@ADRESH;

volatile unsigned char ad_l@ADRESL;


unsigned int shiftH;

unsigned int shiftL;


set_bit(adcon0,Go_Done); // Start conversion




shiftH = ad_h;

shiftL = ad_l;


AD_Result = (shiftH<<2) | (shiftL>>6); // Combine the two registers to get full 10 bits.


adcon0 = 0; // Shut off the AD converter.


Link to comment
Share on other sites

You seem to have ANSEL set for input AN0 but the channel selection (CHSX) set for channel 1 (AN1).


Don't forget when you change a channel to allow a settling time to charge up the sampling capacitor before you start the conversion.


You have also set 32 Tosc which is 8us per bit. Conversion takes some 11 bit times exceeding your 20us timer. Best to wait for conversion complete (GO/DONE bit = 0).


Not sure what the shifting of the result is supposed to be doing. You cannot squeeze 10 bits into an 8 bit char.





Link to comment
Share on other sites

Thanks for replying so promptly, it really helps to have another pair of eyes look at a problem.

I will change the code as you've suggested and hopefully get some good results.




Dave, Pavel will the IDE simulator have the facility to simulate 12f*** pics' soon?

Link to comment
Share on other sites

Still cannot get it working.


Does anybody have a working version of code for a2d conv. on a 12f675 that I can compare to?


I would guess the problem is the comparator needs to be turned off but I am not sure how that would affect the AD since you are using it on a different pin.


I do not have the 12F675 but I here is some code that works on the 12F683 which should work the same on the 12F675 except for the configuration bits



#include <system.h>


#pragma CLOCK_FREQ 1000000





unsigned short ADRead( void );


#define LED gpio.2




unsigned short adc;


trisio = 0b11111011; // Port I/O configuration


osccon = 0b01000001; // Set to 1MHZ

cmcon0 = 0b00000111; // disable comparator

ansel = 0b01000010; // Fosc/4, AN1 selected

adcon0 = 0b10000101; // Right justified, AN1, A/D on


LED = 0;


while( 1 )


adc = ADRead(); // Read Analog value

LED = !LED; // toggle LED

delay_ms( adc >> 2 ); // delay based on 1/4 Analog value




unsigned short ADRead( void )


adcon0.GO_DONE = 1; // start AD conversion

while( adcon0.GO_DONE ); // wait for it to complete


return( (adresh << 8 ) + adresl );




Perhaps not very interesting of a program but it shows how to setup and use the ADC. It just blinks an LED at a rate based on the AD output.



Link to comment
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Create New...