|
|
View previous topic :: View next topic |
Author |
Message |
toni
Joined: 26 Jan 2013 Posts: 9
|
pic adc/pwm |
Posted: Sat Jan 26, 2013 11:51 am |
|
|
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
|
|
Posted: Sat Jan 26, 2013 12:07 pm |
|
|
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
|
|
Posted: Sat Jan 26, 2013 12:30 pm |
|
|
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
|
|
Posted: Sat Jan 26, 2013 12:33 pm |
|
|
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
|
|
Posted: Sat Jan 26, 2013 1:16 pm |
|
|
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
|
|
Posted: Sat Jan 26, 2013 6:51 pm |
|
|
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
|
|
Posted: Sun Jan 27, 2013 7:44 pm |
|
|
Okay, thank you. I guess I have a lot of reading to do then. |
|
|
|
|
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
|