Go Down

Topic: problem with interupts (Read 538 times) previous topic - next topic

king_vash

Feb 02, 2009, 02:16 am Last Edit: Feb 02, 2009, 02:20 am by king_vash Reason: 1
I am working on a project similar to this http://tinkerlog.com/2008/08/31/led-matrix-projector/#more-162

all the code used to work then I upgraded to 74hc595's and tried to run the code and it no longer worked. I believe it has to do with interupts

It this code changing
Code: [Select]
 if (soft_prescaler >= 257) {
to
Code: [Select]
 if (soft_prescaler >= 256) {
causes it to fail.

This is my test code
Code: [Select]
#include <avr/pgmspace.h>
#include <string.h>

#define FIRST_GND_PIN   2
#define STORE_PIN       12
#define SHIFT_CLOCK_PIN 13
#define DATA_PIN        11
#define SPEED_PIN       0 //analog pin

int soft_prescaler = 0;
byte activeRow = 0;
int screenMem[16];


void setup() {

 // Calculation for timer 2
 // 16 MHz / 8 = 2 MHz (prescaler 8)
 // 2 MHz / 256 = 7812 Hz
 // soft_prescaler = 15 ==> 520.8 updates per second
 // 520.8 / 8 rows ==> 65.1 Hz for the complete display
 TCCR2A = 0;           // normal operation
 TCCR2B = (1<<CS21);   // prescaler 8
 TIMSK2 = (1<<TOIE2);  // enable overflow interrupt

 // define outputs for serial shift registers
 pinMode(STORE_PIN, OUTPUT);
 pinMode(SHIFT_CLOCK_PIN, OUTPUT);
 pinMode(DATA_PIN, OUTPUT);

 // define outputs for 8 rows
 pinMode(FIRST_GND_PIN + 0, OUTPUT);    // PB0, row 0
 pinMode(FIRST_GND_PIN + 1, OUTPUT);    // PB1, row 1
 pinMode(FIRST_GND_PIN + 2, OUTPUT);   // PB2, row 2
 pinMode(FIRST_GND_PIN + 3, OUTPUT);   // PB3, row 3
 pinMode(FIRST_GND_PIN + 4, OUTPUT);   // PB4, row 4
 pinMode(FIRST_GND_PIN + 5, OUTPUT);   // PB5, row 5
 pinMode(FIRST_GND_PIN + 6, OUTPUT);    // PD2, row 6
 pinMode(FIRST_GND_PIN + 7, OUTPUT);    // PD3, row 7
}


/**
* ISR TIMER2_OVF_vect
* This is the timer interrupt service routine.
* It gets called at 7812 times per second.
*/
ISR(TIMER2_OVF_vect) {

 soft_prescaler++;
 if (soft_prescaler >= 256) {
   // display the next row
   displayActiveRow();
   soft_prescaler = 0;
 }

}

/**
* displayActiveRow
* The row is active low. But we are using a ULN2803, that is inverting.
* So we have to use high to switch a row on.
*/
void displayActiveRow() {

 // disable current row
 digitalWrite(FIRST_GND_PIN + activeRow, LOW);
 // next row
 activeRow = (activeRow+1) % 8;
 // shift out values for this row
 shiftOutRow(screenMem[activeRow], screenMem[8+activeRow]);
 // switch to new row
 digitalWrite(FIRST_GND_PIN + activeRow, HIGH);
}


void shiftOutRow(int red, int green) {
 digitalWrite(STORE_PIN, LOW);

 shiftOut(DATA_PIN, SHIFT_CLOCK_PIN, LSBFIRST, green);  
 shiftOut(DATA_PIN, SHIFT_CLOCK_PIN, LSBFIRST, red);  

 digitalWrite(STORE_PIN, HIGH);
}


void loop() {
 for (byte i = 0; i < 16; i++) {  
   screenMem[i] = i;
 }
 delay(1);
}


and my old code was

Code: [Select]

#include <avr/pgmspace.h>
#include <string.h>

#define FIRST_GND_PIN 2
#define SHIFT_CLOCK_PIN 12
#define DATA_PIN 13


byte soft_prescaler = 0;
byte activeRow = 0;
int screenMem[16];

byte color = 1;

byte sprites[][8] = {  

 {

   0b00110000, //___XX___   A

   0b01111000, //__XXXX__

   0b01001000, //__X__X__

   0b11001100, //_XX__XX_

   0b11001100, //_XX__XX_

   0b11111100, //_XXXXXX_

   0b11001100, //_XX__XX_

   0b11001100  //_xx__XX_

 },

 {

   0b00110000, // 1

   0b01110000,

   0b11110000,

   0b00110000,

   0b00110000,

   0b00110000,

   0b11111100,

   0b11111100

 },

 {

   0b01111000, // 2

   0b11001100,

   0b11001100,

   0b00011000,

   0b00110000,

   0b01100000,

   0b11111000,

   0b11111000

 },

 {

   0b01110000, // 3

   0b11111000,

   0b00001100,

   0b00111000,

   0b00111000,

   0b00001100,

   0b11111000,

   0b01110000

 },

 {

   0b11011000, // 4

   0b11011000,

   0b11011000,

   0b11011000,

   0b11111100,

   0b11111100,

   0b00011000,

   0b00011000

 },  

 {

   0b11111100, // 5

   0b11111100,

   0b11000000,

   0b11111000,

   0b00001100,

   0b00001100,

   0b11111000,

   0b11110000

 },

 {

   0b00001100, // 6

   0b00011000,

   0b00110000,

   0b00000000,

   0b00000000,

   0b00000000,

   0b00000000,

   0b00111000

 },

 {

   0b11111100, // 7

   0b11111100,

   0b00001100,

   0b00011000,

   0b00110000,

   0b01100000,

   0b11000000,

   0b11000000

 },

 {

   0b01111000, // 8

   0b11001100,

   0b11001100,

   0b01111000,

   0b01111000,

   0b11001100,

   0b11001100,

   0b01111000

 },

 {

   0b00111000, // 9

   0b01101100,

   0b11001100,

   0b11001100,

   0b01111000,

   0b00011000,

   0b00110000,

   0b01100000

 },

};


void setup() {

 // Calculation for timer 2
 // 16 MHz / 8 = 2 MHz (prescaler 8)
 // 2 MHz / 256 = 7812 Hz
 // soft_prescaler = 15 ==> 520.8 updates per second
 // 520.8 / 8 rows ==> 65.1 Hz for the complete display
 TCCR2A = 0;           // normal operation
 TCCR2B = (1<<CS21);   // prescaler 8
 TIMSK2 = (1<<TOIE2);  // enable overflow interrupt

 // define outputs for serial shift registers
 pinMode(SHIFT_CLOCK_PIN, OUTPUT);
 pinMode(DATA_PIN, OUTPUT);

 // define outputs for 8 rows
 pinMode(FIRST_GND_PIN + 0, OUTPUT);    // row 0
 pinMode(FIRST_GND_PIN + 1, OUTPUT);    // row 1
 pinMode(FIRST_GND_PIN + 2, OUTPUT);    // row 2
 pinMode(FIRST_GND_PIN + 3, OUTPUT);    // row 3
 pinMode(FIRST_GND_PIN + 4, OUTPUT);    // row 4
 pinMode(FIRST_GND_PIN + 5, OUTPUT);    // row 5
 pinMode(FIRST_GND_PIN + 6, OUTPUT);    // row 6

 pinMode(FIRST_GND_PIN + 7, OUTPUT);    // row 7
 
 Serial.begin(9600);
}


/**
* ISR TIMER2_OVF_vect
* This is the timer interrupt service routine.
* It gets called at 7812 times per second.
*/
ISR(TIMER2_OVF_vect) {
 soft_prescaler++;
 if (soft_prescaler == 15) {
   // display the next row
   displayActiveRow();
   soft_prescaler = 0;
 }
}


/**
* displayActiveRow
* The row is active low. But we are using a ULN2803, that is inverting.
* So we have to use high to switch a row on.
*/
void displayActiveRow() {

 // disable current row
 digitalWrite(FIRST_GND_PIN + activeRow, LOW);
 
 // next row
 activeRow = (activeRow+1) % 8;

 // shift out values for this row
 shiftOutRow(screenMem[activeRow], screenMem[8+activeRow]);
 
 // switch to new row
 digitalWrite(FIRST_GND_PIN + activeRow, HIGH);
}


void shiftOutRow(int red, int green) {
 byte red1 = red;
 byte red2 = red >> 8;
//  byte green1 = green;
//  byte green2 = green >> 8;
//  shiftOut(DATA_PIN, SHIFT_CLOCK_PIN, LSBFIRST, green2);
//  shiftOut(DATA_PIN, SHIFT_CLOCK_PIN, LSBFIRST, green1);  
 shiftOut(DATA_PIN, SHIFT_CLOCK_PIN, LSBFIRST, red2);
 shiftOut(DATA_PIN, SHIFT_CLOCK_PIN, LSBFIRST, red1);  
}


void copyToDisplay(byte color, byte sprite2[8], byte sprite[8]) {
 byte i;
 int row;
 for (i = 0; i < 8; i++) {
   row = ( (sprite2[i] << 8) + sprite[i] );
   if ((color & 1) == 1) {
     screenMem[i] = row;
   }
   if ((color & 2) == 2) {
     screenMem[i+8] = row;
   }
 }
}

byte incomingByte;
byte letter; //space or empty characture by default
byte oldletter; //space or empty characture by default

void loop() {  
 // send data only when you receive data:
 if (Serial.available() > 0) {
   // read the incoming byte:
   incomingByte = Serial.read();
   if ( incomingByte == 32 ) { oldletter = letter; letter = 26; }  
   if ( incomingByte >= 65 and incomingByte <= 95 ) { oldletter = letter; letter = incomingByte - 65; } //uppercase alphabet
   if ( incomingByte >= 97 and incomingByte <= 122 ) { oldletter = letter; letter = incomingByte - 97; } //lowercase alphabet
   if ( incomingByte >= 48 and incomingByte <= 57 ) { oldletter = letter; letter = incomingByte - 48 + 27; } //numbers
   copyToDisplay(1, sprites[oldletter], sprites[letter]);
//    Serial.print(incomingByte, BYTE);
 }
 delay(50);
}

Go Up