- UID
- 373967
- 帖子
- 9162
- 主題
- 2609
- 精華
- 0
- 積分
- 1010
- 楓幣
- 0
- 威望
- 987
- 存款
- 36862
- 贊助金額
- 0
- 推廣
- 0
- GP
- 1205
- 閱讀權限
- 70
- 在線時間
- 466 小時
- 註冊時間
- 2023-1-12
- 最後登入
- 2025-1-19
|
製作單片機數字時鐘
需要以下材料:
ATmega8A 單片機 x 1
16MHz 晶振 x 1
74HC595 串聯輸出器 x 2
共陰極 7 段 4 位 LED 數碼管 x 1
電阻:220 歐姆 x 8、1K 歐姆 x 1、10K 歐姆 x 1
電容:22pF x 2
按鈕開關 x 4
電位器 10K 歐姆 x 1
9V 電池或 DC 電源
以下是連結腳位和程式碼:
ATmega8A 單片機引腳連線圖:
+-----+
PC0 --| 1 28|-- PC5 (ADC5/SCL)
PC1 --| 2 27|-- PC4 (ADC4/SDA)
PC2 --| 3 26|-- PC3 (ADC3)
VCC --| 4 25|-- GND
GND --| 5 24|-- XTAL2
XTAL1--| 6 23|-- XTAL1
(RXD)PD0 --| 7 22|-- (TXD)PD1
(RXC)PD2 --| 8 21|-- (TXC)PD3
PD4 --| 9 20|-- (ICP)PD5
PD6 --|10 19|-- (OC1B)PD7
PB0 --|11 18|-- (OC1A)PB1
PB2 --|12 17|-- (OC0)PB3
PB4 --|13 16|-- (SS)PB5
PB6 --|14 15|-- (MOSI)PB7
+-----+
74HC595 串聯輸出器連接圖:
將兩個 74HC595 串聯起來,然後將第一個 74HC595 的 Q7' 輸出連接到第二個 74HC595 的 SER 輸入,並將兩個 74HC595 的 OE、SRCLR、RCLK、SRCLK 和 Q7' 輸出分別連接到 ATmega8A 單片機的相應引腳。
共陰極 7 段 4 位 LED 數碼管連接圖:
將 LED 數碼管的共陰極連接到 GND,然後將四個數碼管的七段顯示器分別連接到第一個 74HC595 的 Q0 ~ Q3 輸出和第二個 74HC595 的 Q0 ~ Q3 輸出。
按鈕開關、
按鈕開關、電位器連接腳位:
將四個按鈕開關分別連接到 ATmega8A 單片機的 PD0、PD1、PD2 和 PD3 引腳,然後將電位器的一端連接到 VCC,另一端連接到 GND,中間端點連接到 ATmega8A 單片機的 ADC0 引腳。
連結完後,您可以使用以下程式碼來驅動時鐘顯示:
#include <avr/io.h>
#include <util/delay.h>
// 設定 74HC595 引腳
#define HC595_PORT PORTC
#define HC595_DDR DDRC
#define HC595_DS PC2
#define HC595_SHCP PC3
#define HC595_STCP PC4
// 設定按鈕引腳
#define KEY_PIN PIND
#define KEY1 PD0
#define KEY2 PD1
#define KEY3 PD2
#define KEY4 PD3
// 設定電位器引腳
#define POT_ADC 0
#define POT_DDR DDRA
#define POT_PORT PORTA
// 設定時鐘顯示的數值
unsigned char disp_buf[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
// 初始化函數
void init()
{
// 設定 74HC595 引腳為輸出模式
HC595_DDR |= (1<<HC595_DS) | (1<<HC595_SHCP) | (1<<HC595_STCP);
// 設定按鈕引腳為輸入模式,並啟用內部上拉電阻
DDRD &= ~(1<<KEY1) & ~(1<<KEY2) & ~(1<<KEY3) & ~(1<<KEY4);
PORTD |= (1<<KEY1) | (1<<KEY2) | (1<<KEY3) | (1<<KEY4);
// 設定電位器引腳為輸入模式
POT_DDR &= ~(1<<POT_ADC);
POT_PORT |= (1<<POT_ADC);
// 啟用 ADC,並設定為單次轉換模式,預分頻因子為 128
ADCSRA |= (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
}
// 讀取 ADC 值的函數
unsigned int read_adc(unsigned char channel)
{
ADMUX = (ADMUX & 0xf0) | (channel & 0x0f);
ADCSRA |= (1<<ADSC);
while (ADCSRA & (1<<ADSC));
return ADC;
}
// 將數值轉換為數
unsigned char convert(unsigned char num)
{
if (num >= sizeof(disp_buf)/sizeof(unsigned char)) {
num = 0;
}
return disp_buf[num];
}
// 主函數
int main()
{
unsigned char num = 0;
unsigned char key_value = 0;
// 初始化
init();
// 主循環
while (1)
{
// 讀取按鈕值
key_value = (KEY_PIN & ((1<<KEY1) | (1<<KEY2) | (1<<KEY3) | (1<<KEY4)));
if (key_value == 0) {
// 如果有按鈕按下,則切換顯示的數值
num++;
}
// 讀取電位器值
unsigned int adc_value = read_adc(POT_ADC);
// 將 ADC 值轉換為數值
num = (adc_value/256) % 10;
// 輸出到 74HC595
HC595_PORT &= ~(1<<HC595_STCP);
for (unsigned char i = 0; i < 8; i++) {
HC595_PORT &= ~(1<<HC595_SHCP);
if (num & 0x80) {
HC595_PORT |= (1<<HC595_DS);
} else {
HC595_PORT &= ~(1<<HC595_DS);
}
num <<= 1;
HC595_PORT |= (1<<HC595_SHCP);
}
HC595_PORT |= (1<<HC595_STCP);
// 延時
_delay_ms(5);
}
return 0;
} |
|