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

pic adc/pwm

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



Joined: 26 Jan 2013
Posts: 9

View user's profile Send private message Yahoo Messenger

pic adc/pwm
PostPosted: Sat Jan 26, 2013 11:51 am     Reply with quote

HI all. I am a beginner in programming pics. I am working on a project using PIC 18F4520 where a signal generator inputs a sine wave of 100Hz and the pic adc would convert this into digital samples and write them in an external eeprom. a button is pressed to initiate this writing and to read the stored samples , another button is pressed. The pic pwm would then convert this stored digital samples back to analog through a low pass filter. however, I am getting nothing close to the initial input I have pasted my code below. Please I need your help. Thank you.


[#include <18f4520.h>
#fuses HS,NOLVP,NOWDT,NOPROTECT
#use delay(clock=8000000)
#use i2c(MASTER, FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW) // use hardware i2c controller
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7) // Set up PIC UART on RC6 (tx) and RC7 (rx)


#define EEPROM_WR 0xA0 // Define initial EEPROM write address block (See EEPROM data sheet)
#define EEPROM_RD 0xA1 // Define initial EEPROM read address block (See EEPROM data sheet)

int button1, button2, data_rx = 48; // Initialize variables
int16 i, temp, value, address = 0, data;

void seq_write(int16 address, int16 data)//Writing to the EEPROM function
{
i2c_start();
i2c_write(EEPROM_WR);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
delay_ms(5);//Delay time needed in order to allow EEPROM to write data from buffer to memory sector
}

int16 seq_read(int16 address)// Reading from the EEPROM function
{
i2c_start();
i2c_write(EEPROM_WR);
i2c_write(address>>8);
i2c_write(address);
i2c_start();
i2c_write(EEPROM_RD);
value = i2c_read(0);
i2c_stop();
return(value);
}

void main() //Main Function
{

setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1, 110, 1);
setup_adc_ports(AN0); //Setup Analog Inputs
set_adc_channel(0);
setup_adc(ADC_CLOCK_INTERNAL);


while (TRUE)
{
button1 = input(PIN_D0); // Button one is pressed when the user wants to write to the EEPROM
button2 = input(PIN_D1); // Button two is pressed when the user wants to read from the EEPROM and send the data to Matlab

if (button1 == 0) {
output_high(PIN_D4);
address = 0x00;
delay_ms(10);

for (i=0; i<1000; i++){
data = read_adc();//Read in data from analog input (In this case it was attached to a function generator)
seq_write(address, data); // Send data from analog input to write function
address++; // Increment up the address location on the EEPROM for the next time it writes something
}
output_low(PIN_D4);// LED is turned off to show that writing to the EEPROM is complete
delay_ms(100);

}

if (button2 == 0) {
output_high(PIN_D5);
address = 0x00; // start at the first address location
delay_ms(10);
for (i=0; i<1000; i++){
temp = seq_read(address); //read data from adress location
set_pwm1_duty(temp);
address++; // increment up the address so it can read from the next data sector
}
output_low(PIN_D5);// LED is turned off to show that writing to the EEPROM is complete
delay_ms(100);



}
}

}][/code]
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sat Jan 26, 2013 12:07 pm     Reply with quote

Learn to use the code button so that indentation etc is preserved.

Break your code down into bite sized chunks.
Get each chunk to work properly then move on to the next one.

When you have problems tell us what's working and what's not.

Above all keep it simple.

Mike

EDIT Add errors to your RS232.
toni



Joined: 26 Jan 2013
Posts: 9

View user's profile Send private message Yahoo Messenger

PostPosted: Sat Jan 26, 2013 12:30 pm     Reply with quote

Thank you Mike. I am new to the forum so please pardon the mistakes. The code is working cos i can see changes in the pwm duty cycle, but its the output of the filter that's not what I desired. I am not sure if its the sampling frequency of the adc or the pwm frequency or the the filter.


Code:

#include <18f4520.h>
#fuses HS,NOLVP,NOWDT,NOPROTECT
#use delay(clock=8000000)
#use i2c(MASTER, FAST, SCL=PIN_C3, SDA=PIN_C4, FORCE_HW) // use hardware i2c controller
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7) // Set up PIC UART on RC6 (tx) and RC7 (rx)


#define EEPROM_WR 0xA0 // Define initial EEPROM write address block (See EEPROM data sheet)
#define EEPROM_RD 0xA1 // Define initial EEPROM read address block (See EEPROM data sheet)

int button1, button2, data_rx = 48; // Initialize variables
int16 i, temp, value, address = 0, data;

void seq_write(int16 address, int16 data)//Writing to the EEPROM function
{
i2c_start();
i2c_write(EEPROM_WR);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
delay_ms(5);//Delay time needed in order to allow EEPROM to write data from buffer to memory sector
}

int16 seq_read(int16 address)// Reading from the EEPROM function
{
i2c_start();
i2c_write(EEPROM_WR);
i2c_write(address>>8);
i2c_write(address);
i2c_start();
i2c_write(EEPROM_RD);
value = i2c_read(0);
i2c_stop();
return(value);
}

void main() //Main Function
{

setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1, 110, 1);
setup_adc_ports(AN0); //Setup Analog Inputs
set_adc_channel(0);
setup_adc(ADC_CLOCK_INTERNAL);


while (TRUE)
{
button1 = input(PIN_D0); // Button one is pressed when the user wants to write to the EEPROM
button2 = input(PIN_D1); // Button two is pressed when the user wants to read from the EEPROM and send the data to Matlab

if (button1 == 0) {
output_high(PIN_D4);
address = 0x00;
delay_ms(10);

for (i=0; i<1000; i++){
data = read_adc();//Read in data from analog input (In this case it was attached to a function generator)
seq_write(address, data); // Send data from analog input to write function
address++; // Increment up the address location on the EEPROM for the next time it writes something
}
output_low(PIN_D4);// LED is turned off to show that writing to the EEPROM is complete
delay_ms(100);

}

if (button2 == 0) {
output_high(PIN_D5);
address = 0x00; // start at the first address location
delay_ms(10);
for (i=0; i<1000; i++){
temp = seq_read(address); //read data from adress location
set_pwm1_duty(temp);
address++; // increment up the address so it can read from the next data sector
}
output_low(PIN_D5);// LED is turned off to show that writing to the EEPROM is complete
delay_ms(100);



}
}

}
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Sat Jan 26, 2013 12:33 pm     Reply with quote

Think about the time needed. Writing the EEPROM takes 5+mSec. The '+' is four transactions taking at least 320uSec. Implies less than two samples per cycle.
Twice the signal frequency (Nyquist), is the _minimum_ to actually record the presence of a particular frequency without aliasing, not the sample rate needed to reproduce a signal at all. The difference between a sine wave, square wave, triangular wave etc., is stored in the harmonics of the 'fundamental'. You are not even sampling fast enough to get the fundamental, let alone the harmonics....
As a comment, is ADC_CLOCK_INTERNAL recommended at your clock rate? Read the data sheet.

Best Wishes
temtronic



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

View user's profile Send private message

PostPosted: Sat Jan 26, 2013 1:16 pm     Reply with quote

Please forget about code for a few minutes...

You are aware that the PIC ADC only read POSITIVE voltages ? IE . it only accept from 0 to +Vdd..it does not read negative voltages, thus cannot read a sine wave.

...unless the analog 'front end' shifts the sinewave...simple opamp circuit....

hth
jay
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sat Jan 26, 2013 6:51 pm     Reply with quote

Like I said first time, keep it simple.

Your hardware's all wrong. You can't write to the EEPROM fast enough to record enough data samples to be able to reproduce a copy of the original waveform, you need faster RAM, or a buffer. OR do some basic reading.

OK, you've found the code button but your code's no easier to read.

My understanding of indenting is to arrange each closing { immediately below it's opening }.
The idea is to make it easy to see your program flow

Code:
void main()
{
  // top level code here
  .....
   {
    // second level code
    .....
    .....
    {
       // third level code etc
       ....
       ....
    }  // third level code exits here
    .... // more seond level code
  } // second level code exits here
  ....// more top level code
} // Top level code ends here


Mike
toni



Joined: 26 Jan 2013
Posts: 9

View user's profile Send private message Yahoo Messenger

PostPosted: Sun Jan 27, 2013 7:44 pm     Reply with quote

Okay, thank you. I guess I have a lot of reading to do then.
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