Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

More A/D woes

Status
Not open for further replies.

SwingeyP

Member
I have decided to use some of the A/D pins of the 16f877a for the S meter (bargraph) for my Digital VFO (rapidy becoming a 40m receiver) project.

I am trying to configure the A/D as follows:

ADCON0 = %11000001 'set A/D conversion clock to internal source
ADCON1 = %01000000 'set AN0 as analog input

Hopefully that reads

ADCON0 - Internal Clock, ANO, Switch the A/D module on
ADCON1 - Left Justified (no idea why I need this just guessed), Internal Clock, All ports analog

Is there something else I need as it doesn't seem to work in simulation :-(

Cheers - Paul
 
ADCON1 - Left Justified (no idea why I need this just guessed), Internal Clock, All ports analog

The ADC result is stored as a 10bit result in two registers

adc high ... adc low
------xx ... xxxxxxx .. Right justified
xxxxxxx ... xx------ ... Left justified


Are you reading the port similar to this..

C:
int result = 0;
ADCON.GO = 1;
while(ADCON.GO)
result = (int)ADRESH <<8;
result += ADRESL;
return result;
 
hi Paul,
This simple working demo ADC to LCD will show you the settings for project.
The b2a subr at the end.

Give it a run in Oshon.
E

Code:
'04 Feb 2010 Forum

Define LCD_BITS = 4
Define LCD_DREG = PORTB
Define LCD_DBIT = 4

Define LCD_RSREG = PORTB
Define LCD_RSBIT = 3
Define LCD_EREG = PORTB
Define LCD_EBIT = 2
Define LCD_RSREG = PORTB
Define LCD_RWBIT = 1
Define LCD_LINES = 2
Define LCD_CHARS = 16


Define SIMULATION_WAITMS_VALUE = 1  'make this =0 for programming a PIC
'------------------------------------
'setup temp variables
Dim ascbfr4 As Byte
Dim ascbfr3 As Byte
Dim ascbfr2 As Byte
Dim ascbfr1 As Byte
Dim ascbfr0 As Byte

Dim temp3 As Word
Dim binval As Word

Dim volt0 As Word
Dim vref1 As Word

Dim intrcnt As Byte
Dim adcavg1 As Word

'''''''''''''''''''
T1CON.T1OSCEN = 1
T1CON.TMR1CS = 0
T1CON.TMR1ON = 1
T1CON.T1CKPS0 = 1  'tmr1 prescaler /256 gives a 8 microsec clock period
T1CON.T1CKPS1 = 1

TMR1H = 0xcf  'FFFF - CF2C = 30D3 == 12500 * 8 = ~ 0.1 sec/intr
TMR1L = 0x2c

INTCON.GIE = 1
INTCON.PEIE = 1

PIE1.TMR1IE = 1
PIR1.TMR1IF = 0
'''''''''''''''''''''''''''''''

ADCON0 = %01000001  'fosc/8
ADCON1 = %10000100  'Dis clk div,,,an0 > an3 analaog rest dig

TRISA = %00001111
TRISB = %00000001  'reserve portb.0 for ext interrupts, if required
TRISC = %11111111
'-----------------------------------------------------

Lcdinit
Enable  'enable interrupts

main0:
Lcdcmdout LcdClear

main:
'loop
If intrcnt > 4 Then  'count the 0.1sec intrs, get 5 values, average and display every 0.5s
''Break
intrcnt = 0
binval = adcavg1 / 5  '''volt0  'rename for the bin2asc subr
Gosub bin2asc

Lcdcmdout LcdLine1Home
Lcdout "Percent: ", ascbfr3, ascbfr2, ascbfr1, ".", ascbfr0, "%"

binval = adcavg1 / 25  ''volt0 / 5
Gosub bin2asc

Lcdcmdout LcdLine2Home
Lcdout "Val:"ascbfr2, ascbfr1, ".", ascbfr0

adcavg1 = 0

If volt0 > vref1 Or volt0 = vref1 Then
Lcdcmdout LcdLine2Pos(11)
Lcdout "V0 OK "
Else
Lcdcmdout LcdLine2Pos(11)
Lcdout "V0 Low"
Endif

Endif

Goto main

End                                             
On Interrupt
Save System

PIR1.TMR1IF = 0

TMR1H = 0xcf
TMR1L = 0x2c

intrcnt = intrcnt + 1

Gosub readadc

adcavg1 = adcavg1 + volt0

Resume                                          

'scale the 5V input to 4.88v using a resistive divider
readadc:
'read adc word
Adcin 0, volt0
Adcin 1, vref1  'this is the compare to voltage
Return                                          



'you can convert any binary value from 0000h to fffFh to 0000 to 65535 decimal
'just name the binary word as binval and call this subr and the ASCII
'result will be in ascbfr4,3,2,1,0, ready for your LCD or UART
'just pop the DP in the output to the LCD [as shown above]

bin2asc:
'ascbfr4 = binval / 10000' add these 4 lines for 16 bit conv
'temp3 = binval Mod 10000

'ascbfr3 = temp3 / 1000
'temp3 = binval Mod 1000

ascbfr3 = binval / 1000  'delete for 16 bit conv
temp3 = binval Mod 1000  'delete for 16 bit

ascbfr2 = temp3 / 100
temp3 = temp3 Mod 100

ascbfr1 = temp3 / 10
ascbfr0 = temp3 Mod 10
'results are BCD so
'convert to ASCII for LCD or UART
ascbfr4 = ascbfr4 Or 0x30
ascbfr3 = ascbfr3 Or 0x30
ascbfr2 = ascbfr2 Or 0x30
ascbfr1 = ascbfr1 Or 0x30
ascbfr0 = ascbfr0 Or 0x30
Return
 

Attachments

  • LCD_ADC3.bas
    3.2 KB · Views: 314
Last edited:
With different kinds of PICs I had a problem when setting the "enable" bit at the same time with other bits. ADC got enabled, but kept using settings that were in the control registry before. So, I had to split it in two assignments - one sets all the settings with the "enable" bit off, then a separate instruction sets the "enable" bit. I can't remember if I had to put "nop" between assignments or not.
 
Status
Not open for further replies.

Latest threads

Back
Top