|
- #include "STC8H.H"
- #include <intrins.h>
- #include <string.h>
- /*-------- 引脚定义 --------*/
- sbit TM1640_1_DIN = P3^7; // 第一个TM1640数据线
- sbit TM1640_1_SCLK = P3^6; // 第一个TM1640时钟线
- sbit TM1640_2_DIN = P1^0; // 第二个TM1640数据线
- sbit TM1640_2_SCLK = P1^1; // 第二个TM1640时钟线
- sbit KEY_SET = P1^4; // 设置键
- sbit KEY_UP = P1^5; // 增加键
- sbit KEY_DOWN = P1^6; // 减少键
- sbit KEY_BRIGHT = P1^7; // 亮度键
- /*-------- 常量定义 --------*/
- #define SETTING_TIMEOUT 150 // 15秒超时(100ms*150)
- // 数码管段码表 (共阴)
- const unsigned char segCode[] = {
- 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F, // 0-9
- 0x40,0x00, // '-'和关闭
- 0x39,0x5E,0x79,0x71,0x3D,0x76,0x30,0x1E,0x7A,0x38, // 星期1-7
- 0x63 // °C
- };
- /*-------- 系统状态结构体 --------*/
- typedef struct {
- // 时间数据
- unsigned int year;
- unsigned char month;
- unsigned char day;
- unsigned char hour;
- unsigned char minute;
- unsigned char second;
- unsigned char weekday;
-
- // 环境数据
- float temperature;
- float humidity;
-
- // 系统状态
- unsigned char brightness;
- unsigned char setting_mode; // 0:正常 1:年 2:月 3:日 4:时 5:分 6:星期
- unsigned char blink_counter;
- unsigned long key_press_time;
- unsigned char inactive_counter;
- } SystemState;
- SystemState sys;
- /*-------- 函数声明 --------*/
- void DelayMS(unsigned int ms);
- bit KeyPressed(sbit key);
- bit KeyLongPressed(sbit key);
- void TM1640_SendByte(unsigned char dat, sbit din_pin, sbit sclk_pin);
- void TM1640_SetBrightness(unsigned char level, sbit din_pin, sbit sclk_pin);
- void TM1640_Display(unsigned char *data, unsigned char len, sbit din_pin, sbit sclk_pin);
- void ProcessBlink(unsigned char *displayData, unsigned char pos);
- void PrepareDisplayData1(unsigned char *displayData);
- void PrepareDisplayData2(unsigned char *displayData);
- void AdjustBrightness();
- void ProcessTimeSetting();
- void UpdateDisplay();
- void SystemInit();
- /*-------- 函数实现 --------*/
- void DelayMS(unsigned int ms) {
- unsigned int i, j;
- for(i=0; i<ms; i++)
- for(j=0; j<114; j++);
- }
- bit KeyPressed(sbit key) {
- if(key == 0) {
- DelayMS(10);
- if(key == 0) {
- while(!key);
- sys.inactive_counter = 0;
- return 1;
- }
- }
- return 0;
- }
- bit KeyLongPressed(sbit key) {
- if(key == 0) {
- sys.key_press_time = 0;
- while(key == 0) {
- DelayMS(10);
- sys.key_press_time += 10;
- if(sys.key_press_time >= 5000) {
- while(!key);
- sys.inactive_counter = 0;
- return 1;
- }
- }
- }
- return 0;
- }
- void TM1640_SendByte(unsigned char dat, sbit din_pin, sbit sclk_pin) {
- unsigned char i;
- for(i=0; i<8; i++) {
- sclk_pin = 0;
- _nop_();
- din_pin = (dat & 0x01);
- _nop_();
- sclk_pin = 1;
- _nop_();
- dat >>= 1;
- }
- }
- void TM1640_SetBrightness(unsigned char level, sbit din_pin, sbit sclk_pin) {
- if(level < 1) level = 1;
- if(level > 7) level = 7;
-
- din_pin = 1;
- sclk_pin = 1;
- _nop_();
- din_pin = 0;
- _nop_();
-
- TM1640_SendByte(0x40 | (level & 0x07), din_pin, sclk_pin);
-
- din_pin = 0;
- sclk_pin = 0;
- _nop_();
- sclk_pin = 1;
- _nop_();
- din_pin = 1;
- }
- void TM1640_Display(unsigned char *data, unsigned char len, sbit din_pin, sbit sclk_pin) {
- unsigned char i;
- din_pin = 1;
- sclk_pin = 1;
- _nop_();
- din_pin = 0;
- _nop_();
-
- TM1640_SendByte(0x40, din_pin, sclk_pin);
- TM1640_SendByte(0xC0, din_pin, sclk_pin);
-
- for(i=0; i<len; i++) {
- TM1640_SendByte(data[i], din_pin, sclk_pin);
- }
-
- TM1640_SetBrightness(sys.brightness, din_pin, sclk_pin);
- }
- void ProcessBlink(unsigned char *displayData, unsigned char pos) {
- if(sys.setting_mode > 0) {
- sys.blink_counter++;
- if(sys.blink_counter >= 10) sys.blink_counter = 0;
- if(sys.blink_counter < 5) {
- displayData[pos] = segCode[0];
- if(pos < 15) displayData[pos+1] = segCode[0];
- }
- }
- }
- void PrepareDisplayData1(unsigned char *displayData) {
- memset(displayData, 0, 16);
-
- // 月份(GRID1-2)
- displayData[0] = segCode[sys.month/10];
- displayData[1] = segCode[sys.month%10];
-
- // 日(GRID3-4)
- displayData[2] = segCode[sys.day/10];
- displayData[3] = segCode[sys.day%10];
-
- // 时间(GRID5-10)
- displayData[4] = segCode[sys.hour/10];
- displayData[5] = segCode[sys.hour%10];
- displayData[6] = segCode[sys.minute/10];
- displayData[7] = segCode[sys.minute%10];
- displayData[8] = segCode[sys.second/10];
- displayData[9] = segCode[sys.second%10];
-
- // 温度(GRID11-13)
- int tempInt = (int)sys.temperature;
- displayData[10] = segCode[tempInt/10];
- displayData[11] = segCode[tempInt%10] | 0x80; // 第12位数码管DP常亮
- displayData[12] = segCode[(int)(sys.temperature*10)%10];
-
- // 湿度(GRID14-15)
- displayData[13] = segCode[(int)sys.humidity/10];
- displayData[14] = segCode[(int)sys.humidity%10];
-
- // 星期(GRID16)
- displayData[15] = segCode[11 + sys.weekday];
-
- // 设置模式闪烁
- switch(sys.setting_mode) {
- case 2: ProcessBlink(displayData, 0); break; // 月
- case 3: ProcessBlink(displayData, 2); break; // 日
- case 4: ProcessBlink(displayData, 4); break; // 时
- case 5: ProcessBlink(displayData, 6); break; // 分
- case 6: displayData[15] = (sys.blink_counter < 5) ? segCode[0] : segCode[11 + sys.weekday]; break;
- }
- }
- void PrepareDisplayData2(unsigned char *displayData) {
- memset(displayData, 0, 8);
-
- // 公历年份(GRID1-4)
- displayData[0] = segCode[sys.year/1000];
- displayData[1] = segCode[(sys.year%1000)/100];
- displayData[2] = segCode[(sys.year%100)/10];
- displayData[3] = segCode[sys.year%10];
-
- // 农历月份(GRID5-6)
- displayData[4] = segCode[sys.month/10];
- displayData[5] = segCode[sys.month%10];
-
- // 农历日期(GRID7-8)
- displayData[6] = segCode[sys.day/10];
- displayData[7] = segCode[sys.day%10];
-
- // 年份设置闪烁
- if(sys.setting_mode == 1) {
- for(int i=0; i<4; i++) {
- displayData[i] = (sys.blink_counter < 5) ? segCode[0] : displayData[i];
- }
- }
- }
- void AdjustBrightness() {
- if(KeyPressed(KEY_BRIGHT)) {
- sys.brightness++;
- if(sys.brightness > 7) sys.brightness = 1;
- }
- }
- void ProcessTimeSetting() {
- // 长按5秒进入/退出设置
- if(KeyLongPressed(KEY_SET)) {
- if(sys.setting_mode == 0) {
- sys.setting_mode = 1; // 进入设置
- } else {
- sys.setting_mode = 0; // 退出设置
- // 保存时间到DS3231...
- }
- }
-
- // 设置模式处理
- if(sys.setting_mode > 0) {
- // 短按切换设置项
- if(KeyPressed(KEY_SET)) {
- sys.setting_mode++;
- if(sys.setting_mode > 6) sys.setting_mode = 1;
- }
-
- // 增加键
- if(KeyPressed(KEY_UP)) {
- switch(sys.setting_mode) {
- case 1: sys.year++; if(sys.year > 2099) sys.year = 1901; break;
- case 2: sys.month++; if(sys.month > 12) sys.month = 1; break;
- case 3: sys.day++; if(sys.day > 31) sys.day = 1; break;
- case 4: sys.hour++; if(sys.hour > 23) sys.hour = 0; break;
- case 5: sys.minute++; if(sys.minute > 59) sys.minute = 0; break;
- case 6: sys.weekday++; if(sys.weekday > 6) sys.weekday = 0; break;
- }
- }
-
- // 减少键
- if(KeyPressed(KEY_DOWN)) {
- switch(sys.setting_mode) {
- case 1: sys.year--; if(sys.year < 1901) sys.year = 2099; break;
- case 2: sys.month--; if(sys.month < 1) sys.month = 12; break;
- case 3: sys.day--; if(sys.day < 1) sys.day = 31; break;
- case 4: sys.hour--; if(sys.hour > 23) sys.hour = 23; break;
- case 5: sys.minute--; if(sys.minute > 59) sys.minute = 59; break;
- case 6: sys.weekday--; if(sys.weekday > 6) sys.weekday = 6; break;
- }
- }
-
- // 日期有效性检查
- if(sys.month == 2) {
- int is_leap = (sys.year%4 == 0 && sys.year%100 != 0) || (sys.year%400 == 0);
- if(sys.day > (is_leap ? 29 : 28)) sys.day = is_leap ? 29 : 28;
- }
- else if(sys.month == 4 || sys.month == 6 || sys.month == 9 || sys.month == 11) {
- if(sys.day > 30) sys.day = 30;
- }
-
- // 15秒无操作退出
- sys.inactive_counter++;
- if(sys.inactive_counter >= SETTING_TIMEOUT) {
- sys.setting_mode = 0;
- }
- }
- }
- void UpdateDisplay() {
- unsigned char displayData1[16];
- unsigned char displayData2[8];
-
- PrepareDisplayData1(displayData1);
- PrepareDisplayData2(displayData2);
-
- TM1640_Display(displayData1, 16, TM1640_1_DIN, TM1640_1_SCLK);
- TM1640_Display(displayData2, 8, TM1640_2_DIN, TM1640_2_SCLK);
- }
- void SystemInit() {
- // IO口模式设置
- P1M0 = 0x0F; // P1.0-P1.3推挽输出
- P1M1 = 0x00;
- P1M0 |= 0xF0; // P1.4-P1.7上拉输入
- P3M0 = 0xC0; // P3.6,P3.7推挽输出
- P3M1 = 0x00;
-
- // 初始化时间数据
- sys.year = 2025;
- sys.month = 6;
- sys.day = 27;
- sys.hour = 14;
- sys.minute = 30;
- sys.second = 0;
- sys.weekday = 4;
- sys.temperature = 25.6;
- sys.humidity = 65.2;
- sys.brightness = 4;
- sys.setting_mode = 0;
- sys.blink_counter = 0;
- sys.key_press_time = 0;
- sys.inactive_counter = 0;
- }
- void main() {
- SystemInit();
-
- while(1) {
- // 处理按键
- AdjustBrightness();
- ProcessTimeSetting();
-
- // 更新显示
- UpdateDisplay();
-
- // 系统延时
- DelayMS(100);
- }
- }
复制代码 |
|