|
发表于 2025-2-28 13:07:40
|
显示全部楼层
- #include <STC8G.h>
- #include <intrins.h>
- // Define pins for TM1637
- #define TM1637_CLK P1_0
- #define TM1637_DIO P1_1
- // Define pins for buttons
- #define MODE_BTN P1_2
- #define ADD_BTN P1_3
- // Define relay pin
- #define RELAY P1_4
- // TM1637 commands
- #define ADDR_AUTO 0x40
- #define ADDR_FIXED 0x44
- #define DISPLAY_ON 0x88
- #define STARTADDR 0xC0
- // Display state
- #define STATE_INIT 0
- #define STATE_PAUSE 1
- #define STATE_COUNTDOWN 2
- // Global variables
- unsigned char currentState = STATE_INIT;
- unsigned char minutes = 0;
- unsigned char seconds = 0;
- bit colonState = 1;
- unsigned int timerCounter = 0;
- bit buttonDebounce = 0;
- // Function prototypes
- void delay_ms(unsigned int ms);
- void TM1637_start(void);
- void TM1637_stop(void);
- void TM1637_write_byte(unsigned char b);
- void TM1637_display(unsigned char* digits, bit colon);
- void display_init(void);
- void display_time(unsigned char min, unsigned char sec, bit colon);
- void init_timer0(void);
- void check_buttons(void);
- // Main function
- void main(void)
- {
- // Initialize system
- P1M0 = 0x00; // Set P1 as quasi-bidirectional mode
- P1M1 = 0x00;
-
- // Initialize relay (off)
- RELAY = 0;
-
- // Initialize display
- display_init();
-
- // Initialize timer
- init_timer0();
-
- // Enable global interrupts
- EA = 1;
-
- while(1)
- {
- check_buttons();
-
- // State machine
- switch(currentState)
- {
- case STATE_INIT:
- // Display "--:--"
- {
- unsigned char digits[4] = {0x40, 0x40, 0x40, 0x40}; // Segments for "-"
- TM1637_display(digits, 1);
- }
- break;
-
- case STATE_PAUSE:
- // Display time with colon on
- display_time(minutes, seconds, 1);
- break;
-
- case STATE_COUNTDOWN:
- // Display time with blinking colon
- display_time(minutes, seconds, colonState);
- break;
- }
- }
- }
- // Delay function
- void delay_ms(unsigned int ms)
- {
- unsigned int i, j;
- for(i = 0; i < ms; i++)
- for(j = 0; j < 110; j++); // Adjust for STC8G at typical clock
- }
- // TM1637 communication functions
- void TM1637_start(void)
- {
- TM1637_CLK = 1;
- TM1637_DIO = 1;
- delay_ms(1);
- TM1637_DIO = 0;
- delay_ms(1);
- TM1637_CLK = 0;
- delay_ms(1);
- }
- void TM1637_stop(void)
- {
- TM1637_CLK = 0;
- delay_ms(1);
- TM1637_DIO = 0;
- delay_ms(1);
- TM1637_CLK = 1;
- delay_ms(1);
- TM1637_DIO = 1;
- delay_ms(1);
- }
- void TM1637_write_byte(unsigned char b)
- {
- unsigned char i;
- for(i = 0; i < 8; i++)
- {
- TM1637_CLK = 0;
- delay_ms(1);
-
- if(b & 0x01)
- TM1637_DIO = 1;
- else
- TM1637_DIO = 0;
-
- delay_ms(1);
- TM1637_CLK = 1;
- delay_ms(1);
- b >>= 1;
- }
-
- // Wait for ACK
- TM1637_CLK = 0;
- TM1637_DIO = 1;
- delay_ms(1);
- TM1637_CLK = 1;
- delay_ms(1);
-
- // Read ACK (not used)
- TM1637_CLK = 0;
- delay_ms(1);
- }
- // Display functions
- void TM1637_display(unsigned char* digits, bit colon)
- {
- unsigned char i;
- unsigned char segData[4];
-
- // Segment data for 0-9
- unsigned char digitToSegment[] = {
- 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F
- };
-
- // Convert digits to segment data
- for(i = 0; i < 4; i++)
- {
- if(digits[i] <= 9)
- segData[i] = digitToSegment[digits[i]];
- else
- segData[i] = digits[i]; // Direct segment data
- }
-
- // Add colon if needed (on digit 1)
- if(colon)
- segData[1] |= 0x80;
-
- // Send data to display
- TM1637_start();
- TM1637_write_byte(ADDR_AUTO);
- TM1637_stop();
-
- TM1637_start();
- TM1637_write_byte(STARTADDR);
-
- for(i = 0; i < 4; i++)
- TM1637_write_byte(segData[i]);
-
- TM1637_stop();
-
- TM1637_start();
- TM1637_write_byte(DISPLAY_ON);
- TM1637_stop();
- }
- void display_init(void)
- {
- // Initialize display
- TM1637_start();
- TM1637_write_byte(DISPLAY_ON);
- TM1637_stop();
-
- // Display "--:--"
- unsigned char digits[4] = {0x40, 0x40, 0x40, 0x40}; // Segments for "-"
- TM1637_display(digits, 1);
- }
- void display_time(unsigned char min, unsigned char sec, bit colon)
- {
- unsigned char digits[4];
-
- // Convert minutes and seconds to digits
- digits[0] = min / 10;
- digits[1] = min % 10;
- digits[2] = sec / 10;
- digits[3] = sec % 10;
-
- TM1637_display(digits, colon);
- }
- // Timer initialization
- void init_timer0(void)
- {
- // Configure Timer0 for 10ms interrupts
- TMOD &= 0xF0; // Clear Timer0 mode bits
- TMOD |= 0x01; // Set Timer0 to mode 1 (16-bit timer)
- TH0 = 0xDC; // Initial value for 10ms at 11.0592MHz
- TL0 = 0x00;
- TR0 = 1; // Start Timer0
- ET0 = 1; // Enable Timer0 interrupt
- }
- // Button handling
- void check_buttons(void)
- {
- // Debounce protection
- if(buttonDebounce)
- return;
-
- // Check mode button
- if(MODE_BTN == 0)
- {
- delay_ms(20); // Debounce
- if(MODE_BTN == 0)
- {
- buttonDebounce = 1;
-
- switch(currentState)
- {
- case STATE_INIT:
- // Change to pause state
- currentState = STATE_PAUSE;
- minutes = 0;
- seconds = 0;
- break;
-
- case STATE_PAUSE:
- // Start countdown
- currentState = STATE_COUNTDOWN;
- RELAY = 1; // Turn on relay
- break;
-
- case STATE_COUNTDOWN:
- // Pause countdown
- currentState = STATE_PAUSE;
- RELAY = 0; // Turn off relay
- break;
- }
-
- // Wait for button release
- while(MODE_BTN == 0);
- delay_ms(20); // Debounce
- }
- }
-
- // Check add button (only in pause state)
- if(ADD_BTN == 0 && currentState == STATE_PAUSE)
- {
- delay_ms(20); // Debounce
- if(ADD_BTN == 0)
- {
- buttonDebounce = 1;
-
- // Increment minutes
- minutes++;
- if(minutes > 99)
- minutes = 0;
-
- // Wait for button release
- while(ADD_BTN == 0);
- delay_ms(20); // Debounce
- }
- }
- }
- // Timer0 interrupt service routine
- void timer0_isr() interrupt 1
- {
- // Reload timer
- TH0 = 0xDC;
- TL0 = 0x00;
-
- // Increment counter (100 * 10ms = 1 second)
- timerCounter++;
-
- // Toggle colon every 500ms in countdown mode
- if(timerCounter % 50 == 0 && currentState == STATE_COUNTDOWN)
- colonState = !colonState;
-
- // Update time every second in countdown mode
- if(timerCounter >= 100 && currentState == STATE_COUNTDOWN)
- {
- timerCounter = 0;
-
- // Decrement seconds
- if(seconds > 0)
- {
- seconds--;
- }
- else
- {
- if(minutes > 0)
- {
- minutes--;
- seconds = 59;
- }
- else
- {
- // Timer finished
- currentState = STATE_INIT;
- RELAY = 0; // Turn off relay
- }
- }
- }
-
- // Reset button debounce flag after 50ms
- if(buttonDebounce && timerCounter % 5 == 0)
- buttonDebounce = 0;
- }
复制代码 |
|