Odd timing with LedControl
the purpose of exercise experiment reducing flicker , trying buy more processing time between interrupts.
the program below running 2 8x8 bicolour matrices , using 4 cascaded max7219s. pair each matrix switched timer2 interrupt 2 colours not on described in http://www.arduino.cc/playground/main/multiplexmax72xx. program combination of program , ledcontrol library http://www.arduino.cc/playground/main/ledcontrol.
the latter has been de-libraried (such word?) modified , used direct in code has saved 772 bytes , gives same results intents, have closer access it.
the program works should except speed issue baffles me.
the 2 procedures of concern loop() , following setrow().
if activate startisr() & stopisr() in loop() , disable them in settrow() matrix update runs 3 times faster if reverse.
however, on surface, number of times interrupts interrupted same , time lag difference ought time taken call setrow() procedure , return it.
the eventual aim attempt turn interrupts on/off in latter half of spitransfer() [where commented] had bigger effect on speed , flicker.
could please explain going on?
the program below running 2 8x8 bicolour matrices , using 4 cascaded max7219s. pair each matrix switched timer2 interrupt 2 colours not on described in http://www.arduino.cc/playground/main/multiplexmax72xx. program combination of program , ledcontrol library http://www.arduino.cc/playground/main/ledcontrol.
the latter has been de-libraried (such word?) modified , used direct in code has saved 772 bytes , gives same results intents, have closer access it.
the program works should except speed issue baffles me.
the 2 procedures of concern loop() , following setrow().
if activate startisr() & stopisr() in loop() , disable them in settrow() matrix update runs 3 times faster if reverse.
however, on surface, number of times interrupts interrupted same , time lag difference ought time taken call setrow() procedure , return it.
the eventual aim attempt turn interrupts on/off in latter half of spitransfer() [where commented] had bigger effect on speed , flicker.
could please explain going on?
code: [select]
//saves 772 bytes compiled
#include "binary.h"
//the opcodes max7221 , max7219
#define op_noop 0
#define op_digit0 1
#define op_digit1 2
#define op_digit2 3
#define op_digit3 4
#define op_digit4 5
#define op_digit5 6
#define op_digit6 7
#define op_digit7 8
#define op_decodemode 9
#define op_intensity 10
#define op_scanlimit 11
#define op_shutdown 12
#define op_displaytest 15
#define isr_freq 190 //190=650hz 249=500hz
#define red 0
#define green 1
#define reda 0 // address of max7221 red leds#define reda 0 // address of max7221 red leds
#define greena 1 // address of max7221 green leds
#define redb 2 // address of max7221 red leds#define reda 0 // address of max7221 red leds
#define greenb 3 // address of max7221 green leds
#define spi_mosi 10
#define spi_clk 9
#define spi_cs 8
#define maxdevices 4
byte spidata[16];
byte status[64];
int maxinshutdown=green; // tells max7221 off
unsigned long isrtime; // debug test how long in isr
byte count=0;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void setup() {
pinmode(spi_mosi,output);
pinmode(spi_clk,output);
pinmode(spi_cs,output);
digitalwrite(spi_cs,high);
for(int i=0;i<64;i++)
status[i]=0x00;
for(int i=0;i<maxdevices;i++) {
spitransfer(i,op_displaytest,0);
spitransfer(i, op_scanlimit,7); //scanlimit set max on startup
spitransfer(i,op_decodemode,0); //scanlimit set max on startup
cleardisplay(i);
spitransfer(i, op_shutdown,0); //shutdown-mode on startup
}
spitransfer(reda, op_intensity,12);
spitransfer(redb, op_intensity,12);
spitransfer(greena, op_intensity,15);
spitransfer(greenb, op_intensity,15); // 0 = dim, 15 = full brightness 15
setisrtimer(); // setup timer
startisr(); // start timer toggle shutdown
}
void loop() {
count++;
for(int row=0;row<8;row++) {
//stopisr();
setrow(greenb,row,count);
//startisr();
//stopisr();
setrow(redb,row,b01010101);
//startisr();
//stopisr();
setrow(greena,row,b00001111);
//startisr();
//stopisr();
setrow(reda,row,b11110000);
//startisr();
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void setrow(int addr, int row, byte value) {
int offset;
stopisr();
offset=addr*8;
status[offset+row]=value;
spitransfer(addr, row+1,status[offset+row]);
startisr();
}
void spitransfer(int addr, volatile byte opcode, volatile byte data) {
//create array data shift out
int offset=addr*2;
int maxbytes=maxdevices*2;
for(int i=0;i<maxbytes;i++)
spidata[i]=(byte)0;
spidata[offset+1]=opcode; //put our device data array
spidata[offset]=data;
// stopisr(); //added
digitalwrite(spi_cs,low); //enable line
for(int i=maxbytes;i>0;i--) //now shift out data
shiftout(spi_mosi,spi_clk,msbfirst,spidata[i-1]);
digitalwrite(spi_cs,high); //latch data onto display
// startisr(); //added
}
////////////////////////////////////////////////////////////////////////////
/////////////////////////////isr timer functions ///////////////////////////
isr(timer2_compa_vect) { //this isr toggles shutdown between 2max7221's
// digitalwrite(2, maxinshutdown == red ? high : low);
if(maxinshutdown==red){
spitransfer(greena, op_shutdown,0);
spitransfer(greenb, op_shutdown,0);
spitransfer(reda, op_shutdown,1);
spitransfer(redb, op_shutdown,1);
maxinshutdown=green;
}
else {
spitransfer(reda, op_shutdown,0);
spitransfer(redb, op_shutdown,0);
spitransfer(greena, op_shutdown,1);
spitransfer(greenb, op_shutdown,1);
maxinshutdown=red;
}
}
void setisrtimer(){ // setup isr timer controlling toggling
tccr2a = 0x02; // wgm22=0 + wgm21=1 + wgm20=0 = mode2 (ctc)
tccr2b = 0x05; // cs22=1 + cs21=0 + cs20=1 = /128 prescaler (125khz)
tcnt2 = 0; // clear counter
ocr2a = isr_freq; // set top (divisor) - see #define
}
void startisr(){ // starts isr
// tcnt2 = 0; // clear counter (needed here also)
timsk2|=(1<<ocie2a); // set interrupts=enabled (calls isr(timer2_compa_vect)
}
void stopisr(){ // stops isr
timsk2&=~(1<<ocie2a); // disable interrupts
}
//****************************************************************************
//****************************************************************************
void cleardisplay(int addr) {
int offset;
offset=addr*8;
for(int i=0;i<8;i++) {
status[offset+i]=0;
spitransfer(addr, i+1,status[offset+i]);
}
}
void setled(int addr, int row, int column, boolean state) {
int offset;
byte val=0x00;
offset=addr*8;
val=b10000000 >> column;
if(state)
status[offset+row]=status[offset+row]|val;
else {
val=~val;
status[offset+row]=status[offset+row]&val;
}
spitransfer(addr, row+1,status[offset+row]);
}
void setcolumn(int addr, int col, byte value) {
byte val;
for(int row=0;row<8;row++) {
val=value >> (7-row);
val=val & 0x01;
setled(addr,row,col,val);
}
}
void clearmatrix(){
//stopisr(); // disable interrupts - stop toggling shutdown when updating
cleardisplay(reda);
cleardisplay(greena);
cleardisplay(redb);
cleardisplay(greenb);
//startisr(); // enable interrupts again
}
i have no clue difference is, wonder whether making startisr , stopisr inline functions makes difference. there overhead involved in making call, , returning call. making functions inline removes overhead, since code replicated everywhere function called.
since functions single line functions, code shouldn't much, if any, larger.
have looked @ resulting assembly code in each case?
since functions single line functions, code shouldn't much, if any, larger.
have looked @ resulting assembly code in each case?
Arduino Forum > Forum 2005-2010 (read only) > Software > Syntax & Programs > Odd timing with LedControl
arduino
Comments
Post a Comment