32 output 보드를 이용한 fade in / fade out 연습
//**************************************************************//
// Name : shiftPWMout //
// Author : D. Cuartielles //
// Date : 24 Sept, 2007 //
// Version : 1.0 //
// Notes : Code for using Sadi's 32OUTPUT board //
// : to count from 0 to 255 //
// Acknowledgements: gonium.net for the original timer //
//****************************************************************
//Pin connected to ST_CP of 74HC595
//int latchPin = 10;
//Pin connected to SH_CP of 74HC595
//int clockPin = 9;
////Pin connected to DS of 74HC595
//int dataPin = 8;
//#include < avr / interrupt.h >
//#include < avr / io.h >
#define INIT_TIMER_COUNT 6
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT
int int_counter = 0;
volatile int second = 0;
int oldSecond = 0;
long starttime = 0;
int numPWMs = 32;
int msTick = 0;
int duration[]= {
0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0 }; //internal timer for current note
int flags[]= {
0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0 }; //internal flags, 0=nothing happens, 1=fade in, 2=fade out
int cont = 1;
int tendency = 1;
int sizePeriod = 63;
void shiftOutLSB(byte val)
{
int i;
for (i = 0; i < 8; i++) {
if (val>>i & B1) PORTB |= B1;
else PORTB &= ~B1;
PORTB |= B10;
//delayMicroseconds(1);
PORTB &= ~B10;
}
}
void fadeout(int pin) {
flags[pin-1] = 1;
}
void fadein(int pin) {
flags[pin-1] = 2;
}
ISR(TIMER2_OVF_vect) {
int adder = 0;
RESET_TIMER2;
int_counter += 1;
if (int_counter == 1000) {
second+=1;
int_counter = 0;
adder = 1;
}
int pinSetA = 0;
int pinSetB = 0;
msTick++; //increment timer tick at 1 ms intervals
if (msTick > sizePeriod) msTick = 0;
//check flags
for (int i = 0; i < numPWMs; i++)
switch (flags[i]) {
case 1:
if (duration[i] > 0) duration[i] -= adder;
else flags[i] = 0;
break;
case 2:
if (duration[i] < sizePeriod) duration[i] += adder;
else flags[i] = 0;
break;
default:
break;
}
for (int i = 0; i < numPWMs; i++)
if(i<numPWMs/2) pinSetA |= ((msTick<duration[i])<<i);
else pinSetB |= ((msTick<duration[i])<<(i-numPWMs/2));
PORTB &= ~B100;
shiftOutLSB(pinSetA & B11111111);
shiftOutLSB(pinSetA>>8);
shiftOutLSB(pinSetB & B11111111);
shiftOutLSB(pinSetB>>8);
PORTB |= B100;
};
void setup() {
//set pins to output because they are addressed in the main loop
//pinMode(latchPin, OUTPUT);
//pinMode(clockPin, OUTPUT);
//pinMode(dataPin, OUTPUT);
// To accelerate the process we are going to take 8, 9, 10 as outputs
// - 8 will be the data
// - 9 will be the clock
// - 10 will be the latch
DDRB |= 7; //set data direction reg bit 0 to output
PORTB &=~(7); //set outputs low
Serial.begin(9600);
Serial.println("Initializing timerinterrupt");
//Timer2 Settings: Timer Prescaler /64, using prescaler 1 --> 16000000/ 64 / 1 --> 250KHz
TCCR2B |= (1<<CS20);
TCCR2B &= ~((1<<WGM22) | (1<<CS22) | (1<<CS21));
// Use normal mode
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
// Use external clock
ASSR |= (1<<AS2) | (1<<EXCLK);
//Timer2 Overflow Interrupt Enable
TIMSK2 |= (1<<TOIE2) | (0<<OCIE2A);
RESET_TIMER2;
sei();
starttime = millis();
}
void loop() {
if (oldSecond != second) {
//Serial.print(second);
//Serial.print(". ->");
//Serial.print(millis() - starttime);
//Serial.println(".");
//Serial.print("tendency ");
//Serial.print(tendency,DEC);
//Serial.print(" - cont - ");
//Serial.println(cont);
if(tendency) fadein(cont);
else fadeout(cont);
oldSecond = second;
cont++;
if(cont > numPWMs) {
cont = 1;
// checking if lamps are still fading
int fadelevel = 0;
for(int i = 0; i < numPWMs; i++)
if (flags[i]>0 && flags[i]<=2) fadelevel = flags[i];
if(fadelevel==0) {
tendency ^= B1;
//Serial.println(fadelevel,DEC);
}
}
}
}