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

using i2C and PWM at the same time in 16f876

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



Joined: 31 May 2010
Posts: 5

View user's profile Send private message

using i2C and PWM at the same time in 16f876
PostPosted: Mon May 31, 2010 9:48 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon May 31, 2010 12:40 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon May 31, 2010 1:02 pm     Reply with quote

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

View user's profile Send private message

Here my code
PostPosted: Tue Jun 01, 2010 4:09 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 01, 2010 12:34 pm     Reply with quote

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

View user's profile Send private message

i'm wrong
PostPosted: Wed Jun 02, 2010 10:00 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jun 02, 2010 11:07 am     Reply with quote

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

View user's profile Send private message

Same problem
PostPosted: Wed Jun 09, 2010 6:11 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Wed Jun 09, 2010 7:11 am     Reply with quote

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.
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