View previous topic :: View next topic |
Author |
Message |
picer
Joined: 25 Jan 2005 Posts: 28 Location: Taxahoma
|
i2c issues if pwm routine is enabled |
Posted: Sun Feb 13, 2005 9:58 pm |
|
|
I finally got the following to work between a 819 (slave) and 877A (master)
http://www.ccsinfo.com/forum/viewtopic.php?t=21456&sid=1e2c7f51d403d8fd45f8bb39789f7218
Now the problem, I have another interupt that does my pwm and with it in there the I2C does nothing at all altho the pwm works still (using timer2). Ok instead of using interupts I'll just put my code in the main routine and do it there with no additional interupts (used interupts because it seems to make a more stable pwm output).
Here's the main routine, everything else is from the above link and works if I comment out my pwm loop.
Code: |
long freq = 3200;
long duty = 1600;
long pwm = 0;
void main()
{
debug_state = 0;
i2c_initialize();
enable_interrupts(GLOBAL);
while (1)
{
for (pwm=0; pwm < freq; pwm++)
{
if (pwm < duty)
{
output_high(PIN_B0);
}
else
{
output_low(PIN_B0);
}
}
}
}
|
Why would this be? I assume the interupt is taking priority even while in the pwm loop? The pwm still works just fine either way but I2C only works if I do nothing else?? Am I doing something wrong?
Thanks |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Feb 13, 2005 10:45 pm |
|
|
No code = No help
But guessing, you ain't doing the I2C right. Most probably, you aren't handling errors namely the overflow. |
|
|
picer
Joined: 25 Jan 2005 Posts: 28 Location: Taxahoma
|
|
Posted: Sun Feb 13, 2005 10:58 pm |
|
|
The above code is in the main routine of the slave main(), just took out what was in the main while loop and added the pwm stuff.
The full i2c code is in the link above also, I didn't write that just trying to use it. That's all there is other than the fuse settings which are:
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
Like I said the i2c routines work fine untill I do the pwm, what else do I need? compiler is PCM 3.186 |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1937 Location: Norman, OK
|
|
Posted: Sun Feb 13, 2005 11:27 pm |
|
|
With that massive SSP interrupt routine I am not surprised PWM gives it heartburn! You have several places in the interrupt routine that can really hang up the PIC when it needs to be doing other things. I would definitely still use the SSP interrupt but queue the register state and the data one after the other, set a flag and get out then handle the SSP info you got and any responses in main. I also just noticed you dont have the ERRORS parm in your RS232 setup in case of framing errors. |
|
|
picer
Joined: 25 Jan 2005 Posts: 28 Location: Taxahoma
|
|
Posted: Sun Feb 13, 2005 11:48 pm |
|
|
I tried to use the I2C routines in the ccs examples but couldn't get them to work so after searching here I found the above I2C routines that a few seem to be using with success. So these I2C routines aren't of much use then if the pic can't ever do anything else but accept a word of data and echo it back :( I believe the master code is the ccs example for the most part. The more I play with pics the more I seem to be leaning to just learning assembly or going motorola, sorry for the rant. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1937 Location: Norman, OK
|
|
Posted: Mon Feb 14, 2005 7:20 am |
|
|
Picar,
The routines are just fine but they were not intended to be all thrown into an interrupt routine together with all your processing. I write software for three other processors including the M68000 and on ALL OF THEM the thing I always do is keep the interrupt routines as short as I possibly can.
Here is a rough example of how I would handle it:
Code: |
#INT_SSP
void ssp_interupt ()
{
// I make a circular queue 30 to 50 bytes deep to give me plenty
// of time to service the queue and catch up if I get busy doing
// something else. Test the Queue pointer to see if you need to wrap around before storing the next data bytes
// Put SSP Register Status on Queue
SSPQueue[next_in++] = PIC_SSPSTAT & i2c_mask
// Now put SSP data on Queue
// You do a limited mask test of the SSPStat bits
// either store data or put a zero in the processing queue for the data
// if the status indcates an abort condition
If you absolutely have to handle an emergency based on the register status, do it here otherwise wait until the SSP_data_handler to take care of it.
// 0x99 just an example here since I dont know the bits you want to test
if (PIC_SSPSTAT && 0x99)
SSPQueue[next_in++] = 0
else
SSPQueue[next_in++] = read_i2c();
SSPDataReadyFlag=true;
}
Void Main()
}
// In some cases where I have lots of data coming in or a lot of time being eaten up in main I put the following statement in Main several places so I can be sure not to miss anything.
if (SSPDataReadyFlag) I2C_ data_handler().
stuff to do in main
......
if (SSPDataReadyFlag) I2C_ data_handler().
More stuff to do in main
......
if (SSPDataReadyFlag) I2C_ data_handler().
Even more stuff to do in main
......
}
void I2C_ data_handler().
{
SSPDataReadyFlag:=false;
// After you enter the data handler always pull TWO bytes off the Queue
// The first is the SSP register stataus when the data came in and ther second will be zero or the data depending on which you put on the queue.
Pull all your current I2C_Interrrupt _handler code here.
}
|
Hope this helps....
dave |
|
|
picer
Joined: 25 Jan 2005 Posts: 28 Location: Taxahoma
|
|
Posted: Mon Feb 14, 2005 8:16 am |
|
|
Thanks for your help, will give it a shot. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Feb 14, 2005 8:18 am |
|
|
Now how the heck is learning assembly going to make it easier |
|
|
valemike Guest
|
|
Posted: Mon Feb 14, 2005 12:32 pm |
|
|
Perhaps your software isn't bad at all.
Try disconnecting whatever load you have that is connected to the other end of your PWM.
You see, it's possible that if your PWM is being used to switch high currents, then all that noise can be killing your i2c communications. |
|
|
picer
Joined: 25 Jan 2005 Posts: 28 Location: Taxahoma
|
|
Posted: Tue Feb 15, 2005 10:18 am |
|
|
There is nothing connected to the PWM now, just checking it with a scope. |
|
|
|