I am at my wits end and hope someone more literate than I will help.
In short I had a MPLABX cx32 v1.0 project to target an uno32 board to operate a radioshack tricolor LED p/n 2760249 and it worked PERFECTLY using core timer for precision timing.
However, even after manually installed Microchip's peripheral library on top of xc32 x1.34 and genning the SystemConfig function to complile. the core timer counts are producing erratic results...no matter what I put in blocking whiles for CP0 counts I cant make the pattern....waiting X counts while high is different than while low.
This LED strip works on 24 bits...
a LOGIC one needs to be ~1.5us HIGH followed by .78us LOW
a LOGIC zero needs to be .78us HIGH followed by 1.5us LOW
in the code below i an sending 0xFF00FF....so 8 ones followed by 8 zeros followed by 8 ones with timing above.
To do that I was using core timer counts...for now I just want something that simple w/o interrupts.
Used to be a core timer counts was 25ns like clockwork. That was several years ago and now that I have installed the new versions of the toolchain something is a amiss.
I am including my complete code and a screen shot of a scope plot or 2 showing weird timing.
void send_strip(unsigned int data)
{
int i;
unsigned long long j=0x800000;
for (i=0;i<24;i++)
{
if (data & j)
{
PORTFbits.RF1=1;
start=_CP0_GET_COUNT() ;
while(_CP0_GET_COUNT()<=(start+36)); //40MHz=> period is 25ns...neded this to be 1.55us
PORTFbits.RF1=0;
start=_CP0_GET_COUNT() ;
while(_CP0_GET_COUNT()<=(start));
}
else
{
PORTFbits.RF1=1;
start=_CP0_GET_COUNT() ;
while(_CP0_GET_COUNT()<=(start));
PORTFbits.RF1=0;
start=_CP0_GET_COUNT() ;
while(_CP0_GET_COUNT()<=(start+36));
}
j>>=1;
}
}
void set_white()
{
// INTDisableInterrupts();
int i;
for (i=0;i<10;i++)
{
send_strip(0x00ffff);
}
// INTEnableInterrupts();
PORTFbits.RF1=0;
start=_CP0_GET_COUNT() ;
while(_CP0_GET_COUNT()<=(start+1000));
}
void send_1M_pattern(const unsigned long data[][10], int pattern_no, int frame_rate)
{
int i=0;
int j=0;
UINT32 temp_data;
INTDisableInterrupts();
for (i=0;i<pattern_no;i++)
{
for (j=0;j<10;j++)
{
temp_data=&data[j];
send_strip(temp_data);
}
INTEnableInterrupts();
Question
Chris I
I am at my wits end and hope someone more literate than I will help.
In short I had a MPLABX cx32 v1.0 project to target an uno32 board to operate a radioshack tricolor LED p/n 2760249 and it worked PERFECTLY using core timer for precision timing.
However, even after manually installed Microchip's peripheral library on top of xc32 x1.34 and genning the SystemConfig function to complile. the core timer counts are producing erratic results...no matter what I put in blocking whiles for CP0 counts I cant make the pattern....waiting X counts while high is different than while low.
This LED strip works on 24 bits...
a LOGIC one needs to be ~1.5us HIGH followed by .78us LOW
a LOGIC zero needs to be .78us HIGH followed by 1.5us LOW
in the code below i an sending 0xFF00FF....so 8 ones followed by 8 zeros followed by 8 ones with timing above.
To do that I was using core timer counts...for now I just want something that simple w/o interrupts.
Used to be a core timer counts was 25ns like clockwork. That was several years ago and now that I have installed the new versions of the toolchain something is a amiss.
I am including my complete code and a screen shot of a scope plot or 2 showing weird timing.
#include <xc.h>
#include <cp0defs.h>
#include <sys/attribs.h>
#include <p32xxxx.h>
#include <plib.h>
#pragma config FPLLIDIV = DIV_2 // PLL Input Divider (2x Divider)
#pragma config FPLLMUL = MUL_20 // PLL Multiplier (20x Multiplier)
#pragma config FPLLODIV = DIV_1 // System PLL Output Clock Divider (PLL Divide by 1)
#pragma config FNOSC = PRIPLL // Oscillator Selection Bits (Primary Osc w/PLL (XT+,HS+,EC+PLL))
#pragma config FSOSCEN = OFF // Secondary Oscillator Enable (Enabled)
#pragma config IESO = ON // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = XT // Primary Oscillator Configuration (XT osc mode)
#pragma config FWDTEN = OFF // Watchdog Timer Enable (WDT Enabled)
#define SYS_CLOCK (80000000L)
#define SYS_FREQ (80000000L)
UINT64 start=0;
UINT64 stop=0;
const unsigned long pattern_test_rainbow[10][10]={
{0xff0000,0xff7f00,0xffff00,0x00ff00,0x0000ff,0x6f00ff,0x8f00ff,0x000000,0x000000,0x000000},
{0x000000,0xff0000,0xff7f00,0xffff00,0x00ff00,0x0000ff,0x6f00ff,0x8f00ff,0x000000,0x000000},
{0x000000,0x000000,0xff0000,0xff7f00,0xffff00,0x00ff00,0x0000ff,0x6f00ff,0x8f00ff,0x000000},
{0x000000,0x000000,0x000000,0xff0000,0xff7f00,0xffff00,0x00ff00,0x0000ff,0x6f00ff,0x8f00ff},
{0x8f00ff,0x000000,0x000000,0x000000,0xff0000,0xff7f00,0xffff00,0x00ff00,0x0000ff,0x6f00ff},
{0x6f00ff,0x8f00ff,0x000000,0x000000,0x000000,0xff0000,0xff7f00,0xffff00,0x00ff00,0x0000ff},
{0x0000ff,0x6f00ff,0x8f00ff,0x000000,0x000000,0x000000,0xff0000,0xff7f00,0xffff00,0x00ff00},
{0x00ff00,0x0000ff,0x6f00ff,0x8f00ff,0x000000,0x000000,0x000000,0xff0000,0xff7f00,0xffff00},
{0xffff00,0x00ff00,0x0000ff,0x6f00ff,0x8f00ff,0x000000,0x000000,0x000000,0xff0000,0xff7f00},
{0xff7f00,0xffff00,0x00ff00,0x0000ff,0x6f00ff,0x8f00ff,0x000000,0x000000,0x000000,0xff0000},
};
int main(int argc, char** argv) {
SYSTEMConfigPerformance(80000000);
//SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
TRISF = 0x0000;
PORTF = 0x0000;
send_strip(0xff00ff);
while(1)
{
}
return (EXIT_SUCCESS);
}
void send_strip(unsigned int data)
{
int i;
unsigned long long j=0x800000;
for (i=0;i<24;i++)
{
if (data & j)
{
PORTFbits.RF1=1;
start=_CP0_GET_COUNT() ;
while(_CP0_GET_COUNT()<=(start+36)); //40MHz=> period is 25ns...neded this to be 1.55us
PORTFbits.RF1=0;
start=_CP0_GET_COUNT() ;
while(_CP0_GET_COUNT()<=(start));
}
else
{
PORTFbits.RF1=1;
start=_CP0_GET_COUNT() ;
while(_CP0_GET_COUNT()<=(start));
PORTFbits.RF1=0;
start=_CP0_GET_COUNT() ;
while(_CP0_GET_COUNT()<=(start+36));
}
j>>=1;
}
}
void set_white()
{
// INTDisableInterrupts();
int i;
for (i=0;i<10;i++)
{
send_strip(0x00ffff);
}
// INTEnableInterrupts();
PORTFbits.RF1=0;
start=_CP0_GET_COUNT() ;
while(_CP0_GET_COUNT()<=(start+1000));
}
void send_1M_pattern(const unsigned long data[][10], int pattern_no, int frame_rate)
{
int i=0;
int j=0;
UINT32 temp_data;
INTDisableInterrupts();
for (i=0;i<pattern_no;i++)
{
for (j=0;j<10;j++)
{
temp_data=&data[j];
send_strip(temp_data);
}
INTEnableInterrupts();
start=_CP0_GET_COUNT() ;
while(_CP0_GET_COUNT()<=(start+frame_rate*20000000));
}
}
ScopePlots.docx
Link to comment
Share on other sites
1 answer to this question
Recommended Posts
Archived
This topic is now archived and is closed to further replies.