?? taild.c
字號:
/* tailD.c
* ATmega8 taillight circuit
*
* Last edited: 14-7-2004
* Purpose: A more complex C program that implements different
* flashing patterns under the control of both the push
* buttons and potentiometer. Use your imagination to
* come up with some novel ideas here. Remember however
* that more marks are to be awarded for the quality of
* the code than for the novelness of the patterns.
*/
#include <avr/io.h>
int main(void)
{
// LS LED set to on initially (0 = LED off)
unsigned char pattern = 0x00;
unsigned char pattern1 = 0x01;
unsigned char pattern2 = 0x80;
unsigned int side = 0; //From left to right is 0
unsigned int switchNo = 1;
unsigned int switchPrevious = 1;
unsigned char S1 = 1;
unsigned char S1Previous;
float S1PressTime = 0;//Counting the time for pressing S1
unsigned char S2 = 1;
unsigned char S2Previous;
// ADC configuration:
ADMUX = (1 << REFS0) | (1 << ADLAR);
// Vcc is reference, left adjusted value, input from PC0.
ADCSRA = (1 << ADEN) | 0x07;
// Enable the ADC, prescaler factor = 128.
TCCR1A = 0; // Timer 1 control registers set for:
TCCR1B = 0x0C;// prescaler = /256,mode = CTC using OCR1A.
DDRD = 0xFF; // All Port D pins configured for output
while (1) // Loop forever
{
// Start a conversion
ADCSRA |= (1 << ADSC);
// Read the 8-bit left adjusted ADC result.
// ues ADCH to decide the length of a duty cycle.
OCR1A = (0x0F | ADCH) << 4;
// Update LEDs
if (switchNo == 10) //to get a complex pattern
PORTD = pattern;
else
PORTD = ~pattern;
//Enable PC3 & PC2 as inputs. (default)
DDRC &= ~((1 << PC2) | (1 << PC3));
//Enable pull-ups for tact switches.
PORTC = (1 << PC2) | (1 << PC3);
//Record the previous switch No.
//switchPrevious will decide if a initial pattern
//is applied when we change the patterns.
switchPrevious = switchNo;
//S2Previous will prevent switchNo increase
//more than one, even we just press S2 one time.
//this will heppen when the timer delay is to short,
//and less than press time.
//The way is to increase switchNo when S2 just turn off
S1Previous = S1;
S2Previous = S2;
//check if the switch (S1 & S2) is on
//0 for on, 1 for off
//when switch is pressed, PINC is 0.
S1 = (PINC & (1 << PC2));
S2 = (PINC & (1 << PC3));
/*
* By the depression of one push-button switch (S1) to
* switch 10 different dynamic patterns in an inverse order.
* When first time press S1, the pattern will chang to nest.
* If hold S1 more then 2 seconds. the pattern will change
* by every 0.5 second/pattern. How many patterns changes,
* will decided by how long S1 be hold.
*/
if (S1)
S1PressTime = 0; // S1 is release, Holding time is 0.
else
{
// count the holding time form break time
S1PressTime = S1PressTime + (256 * (float)OCR1A)/4000000;
// if first time press S1, pattern change one next.
if (S1Previous)
switchNo--;
// if the holding time is more than 2 second
// begin to chang patterns by every 0.5 seconds
else if (S1PressTime >= 2)
{
OCR1A = 0x1E84;//0x1E84 decide break time is 0.5s
switchNo--;
}
}
/*
* By the depression of one push-button switch (S2)
* to switch 10 different dynamic patterns.
* By press S2 one time (even very long time),
* the patterns change to next one.
* The action occur when S2 just turn off.
* So S2 is off && S2Previous is on.
*/
if ((!S2) && (S2Previous))
switchNo++;
//when press S2 11 times, switch to the first patterns
//when press S1 11 times, switch to the last patterns
//In order to prevent a time delay, we separate this "if"
//with other "if"s.
if (switchNo == 11)
switchNo = 1;
if (switchNo == 0)
switchNo = 10;
//pattern1: flash the LEDs
if (switchNo == 1)
{
if (pattern == 0x00)//if LEDs off
pattern = 0xFF; //set LEDs on
else
pattern = 0x00; //set LEDs off
}
//pattern2: 55AA
else if (switchNo == 2)
{
if (pattern == 0x55)
pattern = 0xAA;
else
pattern = 0x55;
}
//pattern3: half and half
else if (switchNo == 3)
{
if (pattern == 0xF0)
pattern = 0x0F;
else
pattern = 0xF0;
}
//pattern4: convergence & divergence
else if (switchNo == 4)
{
if (switchPrevious != switchNo)
{
pattern1 = 0x02;
pattern2 = 0x40;
}
if (pattern1 & 0x09)
side ++;
//side = odd : inside
//side = even : outside
if (side%2)
{
pattern1 = pattern1 << 1;
pattern2 = pattern2 >> 1;
}
else
{
pattern1 = pattern1 >> 1;
pattern2 = pattern2 << 1;
}
pattern = pattern1 | pattern2 ;
}
//patterns: right & left shift 1
else if (switchNo == 5|| switchNo <= 6)
{
if (pattern & 0x81)
side ++;
if (side % 2)
{
if (switchPrevious != switchNo)
{
if (switchNo == 5)
pattern = 0xC0;
else
pattern = 0x88;
}
else
pattern = pattern << 1;
}
else
{
if (switchPrevious != switchNo)
{
if (switchNo == 5)
pattern = 0x03;
else
pattern = 0x11;
}
else
pattern = pattern >> 1;
}
}
//Complex pattern 7 & 10
else if (switchNo == 7 || switchNo == 10)
{
if (switchPrevious != switchNo)
pattern = 0x00;
if (!(pattern & 0x81))
side ++;
if (side % 2)
{
if (!(pattern & 0x81))
pattern = 0x01;
else if (pattern & 0x80)
pattern = pattern << 1;
else
pattern |= pattern << 1;
}
else
{
if (!(pattern & 0x81))
pattern = 0x80;
else if (pattern & 0x01)
pattern = pattern >> 1;
else
pattern |= pattern >> 1;
}
}
//pattern8: left 2 | right 3
else if (switchNo == 8)
{
for(int n=0; n<2;n++)
{
if (pattern1 & 0x80)
pattern1 = 0x01 | (pattern1 << 1);
else
pattern1 = pattern1 << 1;
}
for(int n=0; n<3;n++)
{
if (pattern2 & 0x01)
pattern2 = 0x80 | (pattern2 >> 1);
else
pattern2 = pattern2 >> 1;
}
pattern = pattern1 | pattern2 ;
}
//pattern3: counter
else if (switchNo == 9)
{
pattern ++;
}
// Test OCF1A flag in TIFR
// (i.e. wait 0.1 sec from last counter reset)
while (!(TIFR & (1 << OCF1A)));
// Reset flag bit (i.e. write 1 to it)
TIFR |= (1 << OCF1A);
}
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -