|
|
View previous topic :: View next topic |
Author |
Message |
antiwingates
Joined: 31 May 2010 Posts: 5
|
using i2C and PWM at the same time in 16f876 |
Posted: Mon May 31, 2010 9:48 am |
|
|
Hi Folks.
I'm using the 24c256 code library to read an external eeprom to perform a DAC using the PWM port on RC2 and RC3.
Very disapointed. i can't use them at the same time 'cause, change base freq. of timer2.
any help is useful.. |
|
|
davefromnj
Joined: 03 May 2007 Posts: 42
|
|
Posted: Mon May 31, 2010 12:40 pm |
|
|
Is this a #PRIORITY problem?
Are you trying to read too many I2C bytes?
Have you tried the hardware PWM and SOFTWARE I2C? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 31, 2010 1:02 pm |
|
|
It works for me. Here's a test program that was compiled with vs. 4.107
and run on a PicDem2-Plus board. On the CCP1 channel (pin C2), I get
PWM at 3.9KHz with a 50% duty cycle. On CCP2 (pin C1) I get the same
frequency, with a 25% duty cycle. On pin C3 I get the i2c clock at
100 KHz and I get i2c data on pin C4. It's working. The PWM freq is
correct. The i2c baud rate is correct. This is using hardware i2c.
Code: |
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)
//==================================
void main()
{
setup_timer_2(T2_DIV_BY_1, 255, 1);
setup_ccp1(CCP_PWM); // PWM out on Pin C2
set_pwm1_duty(128);
setup_ccp2(CCP_PWM); // PWM out on Pin C1
set_pwm2_duty(64);
while(1)
{
i2c_write(0x55); // i2c on pins C3 (scl) and C4 (sda)
}
} |
|
|
|
antiwingates
Joined: 31 May 2010 Posts: 5
|
Here my code |
Posted: Tue Jun 01, 2010 4:09 am |
|
|
The goal it's read each byte of a sinewave waveform using i2c and send to the CCP1 to generate an analog waveform.
Code: |
#int_timer2
void temporizador1()
{
if (contador) contador--;
}
void speech (void)
{
unsigned long sample=0;
unsigned int data=0;
set_tris_c(0xC0); //RX = input
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_ccp2 (CCP_PWM);
setup_timer_2(T2_DIV_BY_16,49,1); //f=6250khz
set_pwm2_duty(0x80); // view freq. on the scope
while (1)
{
for (sample=0; sample<6251; sample++) //sample waveform
{
data=read_ext_eeprom(sample); //Read i2c byte
set_pwm1_duty(data); //put on PWM register
contador=1; // wait until next period
while(contador); //it is 0 when inter happens
}
}
}
|
This code, modified the base freq. of timer2, and I have a not sync freq. on PWM2 and of course PWM1
What am I doing wrong?? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 01, 2010 12:34 pm |
|
|
Quote: | setup_timer_2(T2_DIV_BY_16,49,1); //f=6250khz
set_pwm2_duty(0x80); // view freq. on the scope
|
In 8-bit PWM mode, the duty cycle number cannot be greater than the
PR2 parameter (49) in setup_timer_2(). If it is, the PWM output will be
constantly high. For example, if you set the duty cycle to 50 or greater
the PWM output will be high constantly. Notice in my example that I set
the PR2 value to 255. Then I use duty cycle numbers that are less than
this.
So the problem is not related to the i2c bus. The problem is caused
because you are using bytes (read from eeprom) that range from 0 to
255, and some of these values are greater than the PR2 number, and
therefore the PWM output goes to a constant high level for these values.
You could use 10-bit PWM mode. But before explaining that mode, I need
to ask how important is the PWM frequency of 6250 Hz ? Could you
accept a lower frequency ? |
|
|
antiwingates
Joined: 31 May 2010 Posts: 5
|
i'm wrong |
Posted: Wed Jun 02, 2010 10:00 am |
|
|
Yeap, you're right.
I've change my code to generate using a table a sinewave, and that's works great.
see code:
Code: |
void speech (void)
{
unsigned int sample=0;
unsigned int data=0;
byte const sinewave[32]={128,148,167,185,200,213,222,228,230,228,222,213,200,
185,167,148,128,108,89,71,56,43,34,28,26,28,34,43,
56,71,89,108};
contador=1;
set_tris_c(0x98); //RX = input, SCL=SDA=input
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_ccp2 (CCP_PWM);
setup_timer_2(T2_DIV_BY_1,0xff,1); //t=4901.96
while (1)
{
for (sample=0; sample<32; sample++) //sample waveform
{
set_pwm1_duty(sinewave[sample]); //put on PWM register
set_pwm2_duty(sinewave[sample]);
//output_high(PIN_C1);
while (contador);
contador=1;
}
}
}
|
PWM1 is connect through a RC Lowpass filter
PWM2 copy of PWM1 without RC filter
the table is identical on the i2c memory.
thats works great, and generate a 610hz sinewave, but when i change from code table to i2c table i'have nothing!!!!
to get something i need to put this
Code: |
data=read_ext_eeprom(sample); //sinewave on i2c (32 steps)
set_tris_c(0x98); //RX = input, SCL=SDA=input
set_pwm1_duty(data); //put on PWM register
|
another trisc!!!!. The port C is disconfigured.
output quality is very poor.
So, the i2c routine change i/o ports (not only SCL and SDA), many, many times.....
what do you think??? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jun 02, 2010 11:07 am |
|
|
You don't need to set the TRIS if you use the CCS functions. The
compiler will set it correctly for you. Don't use #fast_io. Let the
compiler handle the TRIS. |
|
|
antiwingates
Joined: 31 May 2010 Posts: 5
|
Same problem |
Posted: Wed Jun 09, 2010 6:11 am |
|
|
I did the TRIS by the compiler, remove the FAST_IO.
Same problem. No good results
The only thing that i think is to change to another pins of other port and read ext_eeprom, to check the result.
keep you on tune. |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Wed Jun 09, 2010 7:11 am |
|
|
I don't think that is going to work. You are trying to read something via I2C and then trying to set the duty cycle. That just takes too long. No wonder you are getting a very poor quality sine wave. It works when you place a constant array in ROM since that access is very quick. Try lowering the frequency of the sine wave as much as possible. |
|
|
|
|
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
|