I am trying to time multiplex using interrupt service routine. My ports appear to be configured properly as I am able to illuminate the same digit on each display.
However I am having issue with the code inside the ISR. Does anyone have suggestion on how to code/debug? I would like to display 2-digit numbers.
Thank you,
Tiefe
UPDATED CODE*
/*
* Lab02_Time Multiplexed IO.cpp
*
* Created: 9/15/2020 1:03:15 PM
* Author : campb
*/
#include <avr/io.h>
#include <avr/interrupt.h>
int main(void)
{
//configure outputs
DDRD = 0xff; //set PortD as outputs
PORTC|= (1<<PORTC4)|(1<<PORTC5); //set pin C4 & C5 as outputs - digital controls
//configure timer 1
//toggle OCR1A to CTC, run in clear timer on compare
TCCR1A = (0<<COM1A1)|(0<<COM1A0)|(0<<WGM11)|(0<<WGM10);
//toggle CTC mode on timer, clock N=64
TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS12)|(1<<CS11)|(0<<CS10);
TIMSK1 |= (1<<OCIE1A); //enables interrupt on match
OCR1A = 62499; //N=64--->(.5s)*(16mhz/64)
//configure external interrupt
EICRA = (0<<ISC01)|(1<<ISC00); //configure interrupt for any pin change
EIMSK = (1<<INT0)|(INT1); //enable INT0
//enable global interrupts
sei();
while (1) //do nothing until interrupt occurs every .25s, checks inputs and updates outputs
{
}
}
ISR(TIMER1_COMPA_vect) //stores interrupt address/timer compare interrupt service routine
{
PORTC ^=(1<<PORTC4); //Breadcrumb toggle
if(PINC&(1<<PINC4)); //Check digital control 1
{
PORTC|=(1<<PORTC4); //set digital control 1 high
PORTC|=(0<<PORTC5); //set digital control 2 low
switch(PINC&0b00001111){ //read-in PINC and mask for PC0 through PC3
//maps the correct output for 7-segment display
case 0: PORTD = 0x01; break; //set all pins except g to low to display 0
case 1: PORTD = 0x4F; break; //set pins b & c to low, all other pins high to display 1
case 2: PORTD = 0x12; break; //set pins c & f to high, all other pins to low to display 2
case 3: PORTD = 0x06; break; //set pins e & f to high, all other pins low to display 3
case 4: PORTD = 0x4C; break; //set pins a &e to high, all other pins low to display 4
case 5: PORTD = 0x24; break; //set pins b & e to high, all other pins low to display 5
case 6: PORTD = 0x20; break; //set pin b high, all other pins low to display 6
case 7: PORTD = 0x0F; break; //set pins d-g hight and a-c low to display 7
case 8: PORTD = 0x00; break; //set all pins to low to display 8
case 9: PORTD = 0x0C; break; //set pins d & e to high, all other pins low to display 9
}
}
else
{
PORTC|=(0<<PORTC4); //set digital control 1 low
PORTC|=(1<<PORTC5);
//set digital control 2 high
switch(PINB&0b00001111){ ////read-in PINB and mask for PB0 through PB3
case 0: PORTD = 0x01; break; //set all pins except g to low to display 0
case 1: PORTD = 0x4F; break; //set pins b & c to low, all other pins high to display 1
case 2: PORTD = 0x12; break; //set pins c & f to high, all other pins to low to display 2
case 3: PORTD = 0x06; break; //set pins e & f to high, all other pins low to display 3
case 4: PORTD = 0x4C; break; //set pins a &e to high, all other pins low to display 4
case 5: PORTD = 0x24; break; //set pins b & e to high, all other pins low to display 5
case 6: PORTD = 0x20; break; //set pin b high, all other pins low to display 6
case 7: PORTD = 0x0F; break; //set pins d-g hight and a-c low to display 7
case 8: PORTD = 0x00; break; //set all pins to low to display 8
case 9: PORTD = 0x0C; break; //set pins d & e to high, all other pins low to display 9
}
}
}
DDRD |= (1<<PORTD1); //set pin D1 as an output
DDRD |= (1<<PORTD2); //set pin D2 as an output
DDRD |= (1<<PORTD3); //set pin D3 as an output
DDRD |= (1<<PORTD4); //set pin D4 as an output
DDRD |= (1<<PORTD5); //set pin D5 as an output
DDRD |= (1<<PORTD6); //set pin D6 as an output
DDRD |= (1<<PORTD7); //set pin D7 as an output
Seriously? Even ignoring the embedded comment you had on that first line.
You clearly are not used to the Arduino IDE, are you? This could be done in a loop setting pinMode for each of those pins, but however you look at it, it is simpler and cleaner to just
DDRD = 0xff;
But frankly, your avoidance of the Arduino IDE utilities makes it almost impossibly obscure, to me at least. While using a timer interrupt can certainly make the multiplexing of a display deadly reliable, most of the time sensible use of the millis() function in the main loop() is perfectly adequate.
So you are using this to switch between two displays
PORTC ^= (1<<PORTC4); //toggles "breadcrumb"
So what hardware do you have that makes this a viable option.
With this sort of embedded programming it is essential to under the hardware and the software. By only posting the software we can’t tell if it is correct for the hardware you have.
This is why when you read the how to use this forum sticky post it will tell you about asking questions and will tell you to post a schematic of what you have wired up.
Also-:
Your code does not appear to write two different numbers to the segments, just the same one each time.
Paul__B:
Seriously? Even ignoring the embedded comment you had on that first line.
You clearly are not used to the Arduino IDE, are you? This could be done in a loop setting pinMode for each of those pins, but however you look at it, it is simpler and cleaner to just
DDRD = 0xff;
But frankly, your avoidance of the Arduino IDE utilities makes it almost impossibly obscure, to me at least. While using a timer interrupt can certainly make the multiplexing of a display deadly reliable, most of the time sensible use of the millis() function in the main loop() is perfectly adequate.
Yes, I am very new to Arduino IDE. I am trying to teach myself, we all start from somewhere. I appreciate the feedback. It seemed onerous to set each individual pin. I've not been able to find a reliable resource for programming the arduino board in C++ ...
Grumpy_Mike:
So you are using this to switch between two displays
PORTC ^= (1<<PORTC4); //toggles "breadcrumb"
So what hardware do you have that makes this a viable option.
With this sort of embedded programming it is essential to under the hardware and the software. By only posting the software we can’t tell if it is correct for the hardware you have.
This is why when you read the how to use this forum sticky post it will tell you about asking questions and will tell you to post a schematic of what you have wired up.
Also-:
Your code does not appear to write two different numbers to the segments, just the same one each time.
Thanks for bring to my attention. I quickly looked over the "how-to-post", Ill make sure to provide hardware details in the future.
I am using a pocket programmer with Atmega328p. The setup for this uses 2 common anode 7-segment displays, 2 p-channel MOSFETS and a dip-switch board (input switches). I have D0-D6 configured to drive the 7-segment displays. I had to split the the inputs between PortB (B0-B3) and PortC (C0-C3).
I am not sure how to check the input values from two different ports to display a 2 digit number.
I started with driving a single 7-seg display and everything worked well.
Sorry but schematics are the only way to convey a circuit, words simply do not cut it. They are ambiguous and leave out so much detail. What you have told me is a list of parts, without even part numbers. Words like
I have D0-D6 configured to drive the 7-segment displays
Might sound to you it covers what you did, but it tells us nothing.