- 打卡等级:以坛为家I
- 打卡总天数:294
- 最近打卡:2026-03-19 00:08:12
已绑定手机
高级会员
- 积分
- 794
|
求教各大佬:想用AI8H4K64TL触摸按键8段数码管测试板V1.1做一个万年历,需要把hhmmss-wyyyymmdd中的小数点点亮“hh.mm.ss-w.yyyy.mm.dd”,代码怎么写。
#include <AI8H.H>
#include <intrins.h>
#include <absacc.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
// 引脚定义
#define NTC P06 // 0 高阻
#define BUZ P07 // 0 推挽
#define COM0 P20 // 0 推挽
#define COM1 P21 // 0 推挽
#define COM2 P22 // 0 推挽
#define COM3 P23 // 0 推挽
#define COM4 P24 // 0 推挽
#define COM5 P25 // 0 推挽
#define COM6 P26 // 0 推挽
#define COM7 P27 // 0 推挽
#define RXD P30 // 1 双向
#define TXD P31 // 1 推挽
#define SCL P32 // 1 双向
#define SDA P33 // 1 双向
#define SEGC P34 // 0 推挽
#define SEGD P35 // 0 推挽
#define SEGE P36 // 0 推挽
#define CMP+ P37 // 0 高阻
#define SEG0 P40 // 0 推挽
#define SEG1 P41 // 0 推挽
#define SEG2 P42 // 0 推挽
#define SEG3 P43 // 0 推挽
#define SEG4 P44 // 0 推挽
#define SEG5 P45 // 0 推挽
#define SEG6 P46 // 0 推挽
#define SEG7 P47 // 0 推挽
#define FOSC 24000000UL //主时钟
#define BAUD 115200UL //波特率
#define TMRF 200UL //定时器频率
#define BRT (0x10000-FOSC/BAUD/4) //波特率值
#define TMR (0x10000-FOSC/TMRF/12) //定时器值
#define T_Buf_Len 64 //Uart1发送缓存长度
#define R_Buf_Len 64 //Uart1接收缓存长度
// 时间结构体
typedef struct {
unsigned char hour;
unsigned char minute;
unsigned char second;
unsigned char week; // 1-7 表示星期一到星期日
unsigned int year;
unsigned char month;
unsigned char day;
} DateTime;
unsigned char RP; //Uart2接收指针
unsigned char TP; //Uart2发送指针
unsigned char Uart_R_Len; //Uart2接收长度
unsigned char Uart_T_Len; //Uart2发送长度
unsigned char xdata R_Buf[R_Buf_Len]; //Uart2接收缓存
unsigned char xdata T_Buf[T_Buf_Len]; //Uart2发送缓存
unsigned char code Seg_Map[18]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x40,0x00}; //0~F,杠,空格
unsigned char Seg_Buf[16];
unsigned char LED_Buf[16];
bit blink_state = 0;
DateTime current_time; // 当前时间
unsigned char time_update_flag = 0; // 时间更新标志
// 初始化时间为2023年12月20日星期三 12:30:45(示例时间)
void Init_Time(void) {
current_time.hour = 9;
current_time.minute = 58;
current_time.second = 00;
current_time.week = 3; // 星期三
current_time.year = 2026;
current_time.month = 01;
current_time.day = 03;
}
// 判断是否为闰年
unsigned char Is_Leap_Year(unsigned int year) {
return ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
}
// 获取月份的天数
unsigned char Get_Month_Days(unsigned int year, unsigned char month) {
unsigned char days;
switch(month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
days = 31;
break;
case 4: case 6: case 9: case 11:
days = 30;
break;
case 2:
days = Is_Leap_Year(year) ? 29 : 28;
break;
default:
days = 30;
}
return days;
}
// 更新时间(每秒调用一次)
void Update_Time(void) {
// 更新秒
current_time.second++;
if(current_time.second >= 60) {
current_time.second = 0;
current_time.minute++;
if(current_time.minute >= 60) {
current_time.minute = 0;
current_time.hour++;
if(current_time.hour >= 24) {
current_time.hour = 0;
current_time.day++;
current_time.week++;
if(current_time.week > 7) {
current_time.week = 1; // 回到星期一
}
// 检查月份天数
if(current_time.day > Get_Month_Days(current_time.year, current_time.month)) {
current_time.day = 1;
current_time.month++;
if(current_time.month > 12) {
current_time.month = 1;
current_time.year++;
}
}
}
}
}
}
// 将时间格式化为"hhmmss-wyyyymmdd"格式并存入Seg_Buf
void Format_Time_To_Seg(void) {
// 格式: hhmmss-wyyyymmdd
// 索引: 012345 7 89012345
// Seg_Buf数组对应16个数码管位置
// hh - 小时(2位)
Seg_Buf[0] = current_time.hour / 10; // 十位
if(Seg_Buf[0] == 0) Seg_Buf[0] = 17; // 显示空格
Seg_Buf[1] = current_time.hour % 10; // 个位
// mm - 分钟(2位)
Seg_Buf[2] = current_time.minute / 10; // 十位
Seg_Buf[3] = current_time.minute % 10; // 个位
// ss - 秒(2位)
Seg_Buf[4] = current_time.second / 10; // 十位
Seg_Buf[5] = current_time.second % 10; // 个位
// 第6位显示 '-' (16对应杠)
Seg_Buf[6] = 16;
// w - 星期(1位,1-7)
Seg_Buf[7] = current_time.week; // 直接显示1-7
// yyyy - 年(4位)
Seg_Buf[8] = (current_time.year / 1000) % 10; // 千位
Seg_Buf[9] = (current_time.year / 100) % 10; // 百位
Seg_Buf[10] = (current_time.year / 10) % 10; // 十位
Seg_Buf[11] = current_time.year % 10; // 个位
// mm - 月(2位)
Seg_Buf[12] = current_time.month / 10; // 十位
if(Seg_Buf[12] == 0) Seg_Buf[12] = 17; // 显示空格
Seg_Buf[13] = current_time.month % 10; // 个位
// dd - 天(2位)
Seg_Buf[14] = current_time.day / 10; // 十位
if(Seg_Buf[14] == 0) Seg_Buf[14] = 17; // 显示空格
Seg_Buf[15] = current_time.day % 10; // 个位
}
void UART_Send(unsigned int x)
{
while(Uart_T_Len);
TP=0;
Uart_T_Len=x;
TI=1;
}
void UART_Return(unsigned char temp)
{
memcpy(T_Buf,R_Buf,temp);
UART_Send(temp);
}
void Buzzer(void)
{
// 蜂鸣器控制逻辑
BUZ = 0; // 默认关闭蜂鸣器
}
void Seg_Display(void)
{
// 数码管显示逻辑 - 显示时间信息
Format_Time_To_Seg();
}
void LED_Display(void)
{
// LED显示逻辑 - 秒的个位数LED闪烁
unsigned char i;
// 先关闭所有LED
for(i = 0; i < 16; i++) {
LED_Buf = 0x00;
}
// 根据blink_state控制秒个位数LED闪烁
// 假设秒个位数对应Seg_Buf[5],可能需要根据实际硬件连接调整
if(blink_state) {
// 点亮秒个位数对应的LED
// 注意:LED_Buf索引可能与Seg_Buf对应,也可能需要映射
LED_Buf[5] = 0x01; // 尝试点亮第5个LED
}
}
void LED(void)
{
unsigned char i;
unsigned char xdata *p=XBYTE+0xFB10;
// 更新数码管显示
Seg_Display();
// 更新LED显示
LED_Display();
// 写入显示缓存
for(i=0;i<8;i++)
{
*(p+i)=Seg_Map[Seg_Buf];
*(p+8+i)=(LED_Buf&0x07)<<4;
*(p+16+i)=Seg_Map[Seg_Buf[8+i]];
*(p+24+i)=(LED_Buf[8+i]&0x07)<<4;
}
}
void Init(void)
{
P_SW2|=EAXFR;
P0=0x00;
P1=0x00;
P2=0x00;
P3=0x0F;
P4=0x00;
P5=0x00;
P0M0=0x80;
P0M1=0x7F;
P1M0=0x00;
P1M1=0xFF;
P2M0=0xFF;
P2M1=0x00;
P3M0=0x72;
P3M1=0x80;
P4M0=0xFF;
P4M1=0x00;
P5M0=0x00;
P5M1=0xFF;
AUXR=0x05; //设置定时器0时钟为12T模式,设置定时器2为1T模式,设置定时器2为波特率发生器
TMOD=0x01; //设置定时器0为16位不自动重装载模式
TH0=TMR>>8; //设置定时器0初始值
TL0=TMR; //设置定时器0初始值
TF0=0; //清除TF0中断标志位
ET0=1; //启用定时器0中断
TR0=1; //启动定时器0
SCON=0x50; //设置UART1模式为8位数据可变波特率
T2H=BRT>>8; //设置UART1波特率
T2L=BRT; //设置UART1波特率
AUXR|=T2R; //打开定时器2
ES=1; //启用UART1中断
COMEN=0xFF; //使能COM
SEGENL=0xFF; //使能SEG
SEGENH=0x70; //使能SEG
LEDCTRL=0xA0; //使能LED驱动器,共阴共阳模式,亮度100%
LEDCKS=0x00; //
EA=1; //启用总中断
COM0_DA_L=0x00;
COM0_DA_H=0x00;
COM1_DA_L=0x00;
COM1_DA_H=0x00;
COM2_DA_L=0x00;
COM2_DA_H=0x00;
COM3_DA_L=0x00;
COM3_DA_H=0x00;
COM4_DA_L=0x00;
COM4_DA_H=0x00;
COM5_DA_L=0x00;
COM5_DA_H=0x00;
COM6_DA_L=0x00;
COM6_DA_H=0x00;
COM7_DA_L=0x00;
COM7_DA_H=0x00;
COM0_DC_L=0x00;
COM0_DC_H=0x00;
COM1_DC_L=0x00;
COM1_DC_H=0x00;
COM2_DC_L=0x00;
COM2_DC_H=0x00;
COM3_DC_L=0x00;
COM3_DC_H=0x00;
COM4_DC_L=0x00;
COM4_DC_H=0x00;
COM5_DC_L=0x00;
COM5_DC_H=0x00;
COM6_DC_L=0x00;
COM6_DC_H=0x00;
COM7_DC_L=0x00;
COM7_DC_H=0x00;
memset(R_Buf,0x00,sizeof R_Buf);
memset(T_Buf,0x00,sizeof T_Buf);
// 初始化时间
Init_Time();
}
void main(void)
{
Init();
while(1)
{
LED(); // 更新显示
Buzzer(); // 蜂鸣器控制
// 如果时间需要更新
if(time_update_flag) {
time_update_flag = 0;
Update_Time(); // 更新时间
}
}
}
void Uart_Start(void)
{
TH0=TMR>>8;
TL0=TMR;
TR0=1;
}
void Uart_Stop(void)
{
TR0=0;
TH0=TMR>>8;
TL0=TMR;
RP=0;
memset(R_Buf,0x00,sizeof R_Buf);
}
// 定时器0中断服务程序 - 用于更新时间基准和LED闪烁
void Timer0_Isr(void) interrupt TMR0_VECTOR
{
static unsigned int time_counter = 0;
static unsigned char blink_counter = 0;
// 重新装载定时器
TH0 = TMR >> 8;
TL0 = TMR;
// UART处理
if(RP > 0) {
UART_Return(RP);
Uart_Stop();
}
// 时间计数(200Hz中断)
time_counter++;
if(time_counter >= 200) { // 1秒
time_counter = 0;
time_update_flag = 1; // 设置时间更新标志
}
// LED闪烁控制(2Hz,每秒闪烁2次)
blink_counter++;
if(blink_counter >= 100) { // 0.5秒
blink_counter = 0;
blink_state = !blink_state; // 切换闪烁状态
}
}
void Uart1_Isr(void) interrupt UART1_VECTOR
{
if(RI)
{
RI=0;
Uart_Start();
R_Buf[RP]=SBUF;
if(RP==R_Buf_Len-1)
{
Uart_Stop();
}
else if(TR0)
{
RP++;
}
}
if(TI)
{
TI=0;
if(TP==Uart_T_Len)
{
TP=0;
Uart_T_Len=0;
}
if(Uart_T_Len!=0)
{
SBUF=(T_Buf[TP]);
TP++;
}
}
}
|
|