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 CCS Technical Support

18F45K22 ADC vs DAC

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



Joined: 15 Nov 2018
Posts: 5

View user's profile Send private message

18F45K22 ADC vs DAC
PostPosted: Tue Dec 18, 2018 1:48 am     Reply with quote

Hi All

I am not trying anything complex, just working to read the ADC and output it to the DAC with the following code. Running at 64Mhz Internal Clock.

Code:

#include <18F45K22.h>
#device ADC=8
#include <stdlib.h>

#fuses INTRC_IO,NOWDT,NOPUT,NOBROWNOUT,NOLVP,NOMCLR,NOIESO             
#use delay(clock=64M)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,bits=8,stream=STU)


#byte PORTA = 0xF80


unsigned int8 value_adc=0;
long int x=100;

void main() {
   set_tris_a(0x08);
   set_tris_d(0xF0);
   set_tris_b(0x06);
   set_tris_c(0xC0);

   setup_comparator(NC_NC_NC_NC);
   setup_wdt(WDT_OFF);
   setup_dac(DAC_VSS_VDD | DAC_OUTPUT);
   setup_adc(ADC_CLOCK_INTERNAL); 
   setup_adc_ports(sAN3);
   set_adc_channel(3);
 
  while(1)
  {
  value_adc = read_adc();
  delay_us(10);
  dac_write(value_adc);

  }



}



The problem what I do face is when I tried to input an amplified audio signal to adc and read the same back on DAC, what I heard was just cracking noise. Decided to check the internals and fed the ADC with 4.99 Volts, Output read on DAC PIN was 4.63 Volts.

What wrong am I making here. Is there any special configurations to be done on this controller to read ADC? I have worked the same on a different controller without much problems. I have some quality issues as the output was on PWM. But nothing like this.

Please advise.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Dec 18, 2018 2:15 am     Reply with quote

Quote:

When I tried to input an amplified audio signal to adc and read the same
back on DAC, what I heard was just cracking noise.

You have an 8-bit ADC result, but your DAC is only 5-bits. So with a
1:1 write, you are only writing the lower 5 bits of the ADC to the DAC.
This will probably appear as mostly noise. You need to right-shift the
ADC result by 3 bits before sending it to the DAC. Or just divide by 8.
Example:
Code:
dac_write(value_adc/8);

Quote:
any special configurations to be done on this controller to read ADC?

For proper accuracy, you should be using Div by 64, not the internal
ADC clock. Example:
Code:
setup_adc(ADC_CLOCK_DIV_64);


Both these answers are in the PIC data sheet, in the DAC and ADC sections.
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Tue Dec 18, 2018 2:46 am     Reply with quote

Also

ADC_CLOCK_INTERNAL

Is not recommended for use with a clock speed above 1MHz. Again data
sheet will tell you the recommended clock divisor at 64MHz.
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Dec 18, 2018 2:50 pm     Reply with quote

and....

PIC ADCs are usually POSITIVE DC signal devices NOT AC, so you can't 'read' an analog voltage like a sine wave. You can't read say -2 volts.

Jay
aviarunash



Joined: 15 Nov 2018
Posts: 5

View user's profile Send private message

Thank you
PostPosted: Mon Dec 24, 2018 2:42 am     Reply with quote

Hi All

Thank you for your reply. DAC output is still not good when shifting 3 bits, whereas the PWM output is far more better than DAC. However, I have comeup with an other problem in turning ON/OFF PORTB.3 Digital IO.

Code:

#include <18F45K22.h>
#device ADC=8
#include <stdlib.h>

#fuses INTRC_IO,NOWDT,NOPUT,NOBROWNOUT,NOLVP,NOMCLR,NOIESO         
#use delay(clock=64M)

#byte PORTA = 0xF80
#byte PORTB = 0xF81

#bit RLED=PORTA.3
#bit MAINS = PORTB.1
#bit CUTOFF = PORTB.3



void main() {



   set_tris_a(0x00);
   set_tris_b(0x00);
   
   setup_comparator(NC_NC_NC_NC);
   setup_dac(DAC_OFF);
   setup_adc(ADC_OFF);
   setup_adc_ports(NO_ANALOGS);
   setup_wdt(WDT_OFF);
   setup_ccp2(CCP_OFF);

MAINS=1;

  while(1)
  {
   
   MAINS=0;
   CUTOFF=1;
   delay_ms(2);
    CUTOFF=0;
   MAINS=1;
   delay_ms(2);

   /* - WORKING BLOCK
   MAINS=0;
   RLED=1;
   delay_ms(2);
    RLED=0;
   MAINS=1;
   delay_ms(2);
   */

}


 



}





If I do change CUTOFF to RLED PIN, I have the pulse 2 ms ON/OFF in PORTB.1. But when I use the CUTOFF PIN, I dont see even the PULSE in PORTB.1, assume that PORTB.3 is being reserved and when used, it is behaving abnormally.

Please advice.

NOTE: OUTPUT_HIGH / LOW (PIN_B3) Works fine. Just don't know why it doesn't work when I do it as above.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Dec 24, 2018 12:24 pm     Reply with quote

Try it with the Latch registers instead of the Port registers. Example:
Code:

//#byte PORTA = 0xF80
//#byte PORTB = 0xF81

//#bit RLED=PORTA.3
//#bit MAINS = PORTB.1
//#bit CUTOFF = PORTB.3

//---------------------

#byte LATA = getenv("SFR:LATA")
#byte LATB = getenv("SFR:LATB")

#bit RLED   = LATA.3
#bit MAINS  = LATB.1
#bit CUTOFF = LATB.3


If you want to know the reason for doing this, use these search terms
with Google to find articles:
Quote:
site:microchip.com/forums PORTB read modify write
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Wed Dec 26, 2018 7:19 am     Reply with quote

Though limited to 32 levels, the DAC should perform well, _unless_ you are
imposing even a small load on the output. It is a simple resistive divider, so the
output is massively affected by load. Needs an op-amp buffer if any current
is involved at all.

General comments on the posted code.

The clock declaration should say:

#use delay(INTERNAL=64M)

You are 'relying' on the compiler knowing that the fuse is selected for
INT_RC, and that it will automatically generate the correct PLL for this.
Better to tell it this. I think the chip will actually only be running at
16MHz with the selection you post.

The PORT register is the 'input' reads the actual pins. The LAT is the
output latch. It is always better to write to this. The chip is meant to
automatically write to the output latch if you write to the port, but it sounds
as if this is not working for some reason. The CCS output instruction does
write to the output latch not the port.
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