Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ADC program MikroBasic help

Status
Not open for further replies.

heina

Junior Member level 3
Joined
Dec 21, 2009
Messages
25
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Philippines
Activity points
1,471
uhm..

HI!

I have here a sample program but I can't seem to figure out how to simulate this on my oshon software's pic simulator. Nothing seems to happen whenever I load this program and try out different combinations of the input in Port A.

Any help would be very much appreciated..help is really needed..

Thank you very much.

Sincerely,

Heina

Code:
program ADC_on_LEDs
dim temp_res as word

main:
  ANSEL  = 0x04    ' Configure AN2 pin as analog
  ANSELH = 0       ' Configure other AN pins as digital I/O
  C1ON_bit = 0     ' Disable comparators
  C2ON_bit = 0

  TRISA  = 0xFF    ' PORTA is input
  TRISC  = 0       ' PORTC is output
  TRISD  = 0       ' PORTD is output

  while (TRUE)
    temp_res = Adc_Read(2)      ' Get 10-bit results of AD conversion
    PORTD = temp_res            ' Send lower 8 bits to PORTD
    PORTC = word(temp_res >> 8) ' Send 2 most significant bits to RC1, RC0
  wend
end.
 

Hi,
Try this instead:
Code:
program ADC_on_LEDs
dim temp_res as word

main:
  ANSEL  = 0x04    ' Configure AN2 pin as analog
  ANSELH = 0       ' Configure other AN pins as digital I/O
  C1ON_bit = 0     ' Disable comparators
  C2ON_bit = 0

  TRISA  = 0xFF    ' PORTA is input
  TRISC  = 0       ' PORTC is output
  TRISD  = 0       ' PORTD is output
  PORTC = 0
  PORTD = 0

  while (TRUE)
    temp_res = Adc_Read(2)      ' Get 10-bit results of AD conversion
    PORTD = Low(temp_res)            ' Send lower 8 bits to PORTD
    PORTC = Hi(temp_res) ' Send 2 most significant bits to RC1, RC0
  wend
end.
Hope it helps.
Tahmid.
 

Hi Tahmid! Thank you for replying. What is ANSEL? and ANSELH? can't find a clear explanation. :-(
 

Hi,
ANSEL and ANSELH are two registers which select if the ADC channels are to be analogue or digital. Take for example PIC16F887. It has 14 ADC input channels. If you want to use ADC, your ADC input channels must be set to analogue, otherwise if you want to use it for digital I/O operation, they have to be set as digital, or else you'll face problems.
ANSELH and ANSEL are two 8 bit registers that form a 16 bit register.
Take a look at the ADC chapter in the datasheet. The two registers are shown.
They are arranged like this:
ANSELH:
NU NU CH13 CH12 CH11 CH10 CH9 CH8
ANSEL:
CH7 CH6 CH5 CH4 CH3 CH2 CH1 CH0

NU = Not Used

CH0 to CH13 correspond to the ADC channels.
Setting 1 to the bit means selecting it as analogue.

Eg. If you write
Code:
ANSEL = 1
ANSELH = 0
, it means that ANSEL = 0000 0001. This means that CH0 is configured for analogue and the rest as digital. So you can use the other channels for digital R/W I/O operations and CH0 for ADC operation.

Hope this helped.
Tahmid.
 

Thank you very much. I'll check the datasheet.
I have an ADC program here originally written in assembly and I'm trying to convert it in Mikrobasic. It's not yet working right but I hope I'm on the right path.


here's the assembly code:
Code:
		list P=16F877
		__config _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_ON & _CPD_OFF & _LVP_OFF & _BODEN_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC
		radix hex
		include "p16f877.inc"

CBLOCK 0X20
	count
	count10
	tempd
ENDC

org 0x000

bcf STATUS, RP1
bsf STATUS, RP0	; TO BANK 1
movlw 0xFF
movwf TRISA		; SET PORTA AS INPUT
clrf TRISC
clrf TRISD

movlw b'00001110'
movwf ADCON1		;RA0, VREF- RA2, VREF+ RA3

bcf STATUS, RP0

repeat movlw b'01000001'
	movwf ADCON0		;F OSC/8, ENABLE A/D
					;20us delay loop with 4MHz oscillator frequency
call delay1

bsf ADCON0,GO ;initiate conversion

call delay1
call delay1

test	btfsc ADCON0,GO ;conversion done?
goto test ;not finished
call delay1
call delay1
	bcf STATUS, RP1
	bsf STATUS, RP0
	bsf ADCON1, ADFM
	movf ADRESL, W
	bcf STATUS, RP0
	
	movwf PORTD
	movf ADRESH, W
	movwf PORTC

goto repeat

delay1 movlw 0x06
	movwf count ;initialize count
loop
	decfsz count, f ;dec count, store in count
	goto loop ;not finished
	return 
end

and here's my conversion to Mikrobasic:

Code:
program ADC_on_LEDs
 dim AD_Res as word


main:
TRISA  = %11111111       ' PORTA is input
TRISC  = %00000000
TRISD  = %00000000       ' PORTD is output
ADCON1 = %00001110       ' PORTA is in analog mode,
                         '   0 and 5V are referent voltage values,
                         '   and the result is aligned right
ADCON0 = %01000001


eloop:
  AD_Res = ADC_read(2)   ' Execute conversion and store result
                         '   in variable AD_Res.
PORTC= Hi(AD_Res)
PORTD = Lo(AD_Res)       ' Display lower byte of result on PORTD
Delay_ms(500)            ' 500 ms pause
goto eloop               ' Repeat all

end.

I might be missing something.. Does it involve the ANSEL and ANSELH?
Your help will be really appreciated.

Thank you.

Sincerely,

Heina
 

Hi,
Change your code to:

Code:
program ADC_on_LEDs

 dim AD_Res as word


main:
  TRISA  = %11111111       ' PORTA is input
  TRISC  = %00000000
  TRISD  = %00000000       ' PORTD is output
  PORTC = 0
  PORTD = 0
  ADCON1 = %00001110

  while true
    AD_Res = ADC_read(0) 'Read from channel 0

    PORTC= Hi(AD_Res)
    PORTD = Lo(AD_Res)       ' Display lower byte of result on PORTD
    Delay_ms(500)            ' 500 ms pause
   wend               ' Repeat all

end.

It has nothing to do with ANSEL and ANSELH as 16F877 has no ANSEL or ANSELH register.

Hope this helps.
Tahmid.

Added after 3 minutes:

Notes:

When you use the ADC_Read() function, you cannot have an 8-bit result, instead a 10-bit result, which can be bit shifted right 2 times or divided by 4 to obtain an 8-bit value.

Try to use the while...wend loop.

You don't need to touch the ADCON0 register as the ADC_Read() function configures it properly.

Unless you need to use the ADC input pins for digital functions, you won't even need to touch the ADCON1 register.

Your program was written to read from channel 0 but you read from channel 2, so result was always 0.

Try the code with input at channel 0. Hopefully it'll work now.

Hope it helps.
Tahmid.
 

hi tahmid...I can't make it work in my simulation...:-( hmm.. what do I have to do?
 

hi tahmid!! This is what I came up with:
Code:
program ADC_on_LEDs


main:

TRISA = %111111      ' Port A is input
PORTD = 0
TRISD = %00000000
PORTC= 0
TRISC=  %00000000

ADCON1 = %00001110   
ADCON0 = %01000001   


Delay_us (40)       ' 500 ms pause

While (TRUE)

  ADCON0.2 = 1        ' Conversion starts

if ADCON0.2 = 1 then

   Delay_us (40)
end if

PORTD = ADRESH       ' Set lower 8 bits on port D
PORTC= ADRESL


Delay_us (40)        ' 500 ms pause


wend

This works fine but I don't know if it has a drawback. What do you think?
Thanks!

Sincerely,

Heina
 

Hi,
It's fine, just doesn't use the internal function, but it's fine, no drawbacks I guess.
Only you commented 500ms, but gave 40us.

Hope this helps.
Tahmid.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top