使用七段数码管方法,制作一个红灯绿灯各30秒的带倒计时的红绿灯,黄灯3秒
时间: 2023-06-13 15:06:59 浏览: 378
以下是使用七段数码管制作红绿灯的电路连接图和代码:
电路连接图:
```
+5V
|
|
R1
|
VCC
ATmega328P | 7 6 5 4 3 2 1 0
PB0 --|---|---|---|---|---|---|---|-- G
PB1 --|---|---|---|---|---|---|---|-- F
PB2 --|---|---|---|---|---|---|---|-- A
PB3 --|---|---|---|---|---|---|---|-- B
PB4 --|---|---|---|---|---|---|---|-- E
PB5 --|---|---|---|---|---|---|---|-- D
PB6 --|---|---|---|---|---|---|---|-- C
|
|
GND
```
代码:
```c
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define F_CPU 16000000UL
#define RED_TIME 30
#define YELLOW_TIME 3
#define GREEN_TIME 30
#define BLANK_TIME 1
volatile uint8_t seconds = 0;
volatile uint8_t state = 0;
void init_timer()
{
TCCR1B |= (1 << WGM12); // Set CTC mode
OCR1A = 15624; // Set compare value for 1 second
TIMSK1 |= (1 << OCIE1A); // Enable Timer/Counter1 Compare Match A interrupt
sei(); // Enable global interrupts
TCCR1B |= (1 << CS12) | (1 << CS10); // Start timer with 1024 prescaler
}
ISR(TIMER1_COMPA_vect)
{
seconds++;
}
void set_digit(uint8_t digit)
{
switch (digit)
{
case 0:
PORTB = 0b11111100;
break;
case 1:
PORTB = 0b01100000;
break;
case 2:
PORTB = 0b11011010;
break;
case 3:
PORTB = 0b11110010;
break;
case 4:
PORTB = 0b01100110;
break;
case 5:
PORTB = 0b10110110;
break;
case 6:
PORTB = 0b00111110;
break;
case 7:
PORTB = 0b11100000;
break;
case 8:
PORTB = 0b11111110;
break;
case 9:
PORTB = 0b11100110;
break;
default:
PORTB = 0b00000000;
break;
}
}
void set_timer(uint8_t timer_value)
{
uint8_t digit1 = timer_value / 10;
uint8_t digit2 = timer_value % 10;
set_digit(digit1);
_delay_ms(5);
set_digit(digit2);
}
int main(void)
{
DDRB = 0b11111110; // Set PB0-PB6 as output
PORTB = 0b00000000; // Turn off all segments
init_timer();
while (1)
{
switch (state)
{
case 0: // Red light
set_digit(8); // Show number 8 on display
set_timer(RED_TIME - seconds);
if (seconds >= RED_TIME)
{
seconds = 0;
state = 1;
}
break;
case 1: // Red and yellow light
set_digit(6); // Show number 6 on display
set_timer(YELLOW_TIME - seconds);
if (seconds >= YELLOW_TIME)
{
seconds = 0;
state = 2;
}
break;
case 2: // Green light
set_digit(0); // Show number 0 on display
set_timer(GREEN_TIME - seconds);
if (seconds >= GREEN_TIME)
{
seconds = 0;
state = 3;
}
break;
case 3: // Yellow light
set_digit(6); // Show number 6 on display
set_timer(YELLOW_TIME - seconds);
if (seconds >= YELLOW_TIME)
{
seconds = 0;
state = 0;
}
break;
default:
break;
}
}
return 0;
}
```
说明:
该代码使用了 ATmega328P 单片机,通过 PB0-PB6 控制七段数码管的 8 个 LED 灯。使用定时器和中断实现秒数计数,从而控制红绿灯的倒计时。其中状态机的设计实现了红、黄、绿灯的循环显示,并在每次状态转换时重置计数器。
阅读全文