C51项目 - 可调万年历

news2025/8/2 16:20:24

目录

  • 一、实验目的
  • 二、实验仪器
  • 三、实验效果预览
    • 1.显示效果
    • 2.调节效果
  • 四、实验原理
  • 五、单片机代码
    • 1.头文件包含
    • 2.类型定义
    • 3.时钟模块
    • 4. 液晶显示模块
    • 5.温度传感器模块
    • 6. 红外通讯模块
    • 7.开机初始化
    • 8.特殊功能函数
    • 9.代码段常量
    • 10.完整代码

一、实验目的

使用51单片机作为主控芯片,制作可调万年历

二、实验仪器

主控芯片 STC89C52
时钟芯片 DS1302
温度传感器 DS18B20
1602液晶 LCD12864
任意红外遥控器
晶振 11.0952M x1,32.768K x1
电阻、电容若干(详见实验原理图)

三、实验效果预览

1.显示效果

1602液晶屏显示:

年/月/日 星期
时:分:秒 AM/PM 温度


图1 1602液晶屏显示效果

2.调节效果

红外遥控器任意按键进入调节模式请添加图片描述
图2 调节模式显示效果

调节模式被选中的数值下方出现光标,按 < 键和 > 键移动光标,按 + 键和 - 键改变光标选中数值,按 = 键退出调节模式(键值需要自行设置)。
请添加图片描述
图3 调节模式中将星期四改变为星期五

四、实验原理

LCD12864液晶屏VO端接电位器R21,调节R21,使液晶对比度最佳。
在这里插入图片描述
图4 可调万年历实验原理图

五、单片机代码

1.头文件包含

#include <reg52.h>
#include <intrins.h>

2.类型定义

定义字节型变量BYTE和字变量WORD

typedef unsigned char BYTE;
typedef unsigned short WORD;

3.时钟模块

sbit TSCLK = P1 ^ 0;	// 时钟线
sbit TIO = P1 ^ 1;		// 数据线
sbit TEN = P1 ^ 2;		// 使能端
// 读一字节
BYTE DS1302_read_byte(BYTE _Cmd)
{
    BYTE i;
    TEN = 0;
    TSCLK = 0;
    TEN = 1;
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        TIO = _Cmd & 0x01;
        TSCLK = 1;
        _Cmd >>= 1;
    }
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        _Cmd >>= 1;
        if (TIO)
            _Cmd |= 0x80;
        TSCLK = 1;
    }
    return _Cmd;
}
// 写一字节
void DS1302_write_byte(BYTE _Cmd, BYTE _Dat)
{
    BYTE i;
    TEN = 0;
    TSCLK = 0;
    TEN = 1;
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        TIO = _Cmd & 0x01;
        TSCLK = 1;
        _Cmd >>= 1;
    }
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        TIO = _Dat & 0x01;
        TSCLK = 1;
        _Dat >>= 1;
    }
}
// 时钟突发突发模式读
void clock_brust_read(BYTE *_Buf)
{
    BYTE i, j = 0xbf;
    TEN = 0;
    TSCLK = 0;
    TEN = 1;
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        TIO = j & 0x01;
        TSCLK = 1;
        j >>= 1;
    }
    for (i = 0; i < 7; i++)
        for (j = 0; j < 8; j++) {
            TSCLK = 0;
            _Buf[i] >>= 1;
            if (TIO)
                _Buf[i] |= 0x80;
            TSCLK = 1;
        }
}
// 时钟突发突发模式写
void clock_brust_write(const BYTE *_Buf)
{
    BYTE i, j = 0xbe, k;
    TEN = 0;
    TSCLK = 0;
    TEN = 1;
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        TIO = j & 0x01;
        TSCLK = 1;
        j >>= 1;
    }
    for (i = 0; i < 7; i++) {
        k = _Buf[i];
        for (j = 0; j < 8; j++) {
            TSCLK = 0;
            TIO = k & 0x01;
            TSCLK = 1;
            k >>= 1;
        }
    }
}

4. 液晶显示模块

#define LCD_DATA P0		// 液晶数据线
sbit LCD_RS = P3 ^ 5; 	// 数据/命令选择端
sbit LCD_WR = P3 ^ 6; 	// 读/写选择端
sbit LCD_EN = P3 ^ 4; 	// 使能端
// 读状态
BYTE LCD_read_state()
{
    BYTE state;
    LCD_RS = 0;
    LCD_WR = 1;
    LCD_EN = 1;
    state = LCD_DATA;
    LCD_EN = 0;
    return state;
}
// 写指令
void LCD_write_cmd(BYTE _Cmd)
{
    LCD_EN = 0;
    LCD_EN = 1;
    LCD_RS = 0;
    LCD_WR = 0;
    LCD_DATA = _Cmd;
    LCD_EN = 0;
}
// 读数据
BYTE LCD_read_data()
{
    BYTE i;
    LCD_RS = 1;
    LCD_WR = 1;
    LCD_EN = 1;
    i = LCD_DATA;
    LCD_EN = 0;
    return i;
}
// 写数据
void LCD_write_data(BYTE _Dat)
{
    LCD_EN = 0;
    LCD_EN = 1;
    LCD_RS = 1;
    LCD_WR = 0;
    LCD_DATA = _Dat;
    LCD_EN = 0;
}
// 等待写指令
void LCD_wait_cmd(BYTE _Cmd)
{
    while (LCD_read_state() & 0x80)
        ;
    LCD_write_cmd(_Cmd);
}
// 等待写数据
void LCD_wait_write_data(BYTE _Dat)
{
    while (LCD_read_state() & 0x80)
        ;
    LCD_write_data(_Dat);
}
// 等待读数据
BYTE LCD_wait_read_data()
{
    while (LCD_read_state() & 0x80)
        ;
    return LCD_read_data();
}
// 写入字符串
void LCD_write_string(const char *_Str)
{
    BYTE i = 0;
    while (_Str[i])
        LCD_wait_write_data(_Str[i++]);
}
#define _LCD_CLS 0x01 // 显示清屏

5.温度传感器模块

sbit DS18B20 = P2 ^ 2;	// 温度传感器1-wire线
// 1-wire初始化时序
void init_DS18B20()
{
    do {
        DS18B20 = 1;
        _nop_();
        DS18B20 = 0;
        timer0_delay(65074); // delay 499.45 us
        DS18B20 = 1;
        timer0_delay(65500); // delay 37.95 us
    } while (DS18B20);
    timer0_delay(65404); // delay 141.95 us
    DS18B20 = 1;
    _nop_();
}
// 1-wire写时序
void write_byte_1wire(BYTE _Dat)
{
    BYTE i;
    for (i = 0; i < 8; i++) {
        DS18B20 = 0;
        _nop_();
        DS18B20 = _Dat & 0x01 ? 1 : 0;
        timer0_delay(65464); // delay 76.95 us
        DS18B20 = 1;
        _nop_();
        _Dat >>= 1;
    }
}
// 1-wire读时序
BYTE read_byte_1wire()
{
    BYTE dat = 0, i;
    for (i = 0; i < 8; i++) {
        dat >>= 1;
        DS18B20 = 0;
        _nop_(); // 产生读时序
        DS18B20 = 1;
        _nop_(); // 释放总线
        if (DS18B20)
            dat |= 0x80;
        timer0_delay(65464); // delay 76.95 us
    }
    return dat;
}
// ROM指令
#define _SEARCH_ROM 0xf0 // 搜索 ROM 指令
#define _READ_ROM   0x33 // 读取 ROM 指令
#define _MATH_ROM   0x55 // 匹配 ROM 指令
#define _SIKP_ROM   0xcc // 忽略 ROM 指令
#define _ALARM_ROM  0xec // 报警搜索指令
// DS18B20功能指令
#define _CONVERT_T         0x44 // 温度转换指令
#define _WRITE_SCRATCHPAD  0x4e // 写暂存器指令
#define _READ_SCRATCHPAD   0xbe // 读暂存器指令
#define _COPY_SCRATCHPAD   0x48 // 拷贝暂存器指令
#define _RECALL_E2         0xb8 // 召回 EEPROM 指令
#define _READ_POWER_SUPPLY 0xb4 // 读电源模式指令

6. 红外通讯模块

BYTE IRtime;    // 红外高低电平持续时间
BYTE IRcord[2]; // 8位地址+8位数据
bit IRdone = 0; // 数据接收完成标志位
// 定时器1中断 - 每中断一次需要256个机器周期
void timer1() interrupt 3
{
    IRtime++; // _MACHINE_CYCLE*256=277.76 μs
}
// 外部中断0
void int0() interrupt 0
{
    static BYTE i;            // 32次数据计数
    static bit startflag = 0; // 开始储存脉宽标志位
    static BYTE IRdata[4];    // 数据接收缓冲区
    BYTE j;
    if (startflag) {
        if (IRtime >= 32 && IRtime < 53) { // 起始码判定 8.8ms~14ms
            i = 0;
            IRtime = 0;
            return;
        }
        j = (i++) >> 3;
        IRdata[j] >>= 1;
        if (IRtime > 5) // 数据0=高电平560μs+低电平560μs=1120μs
            IRdata[j] |= 0x80;
        IRtime = 0;    // 计数清零
        if (i == 32) { // 如果已经存入了32次脉宽
            i = 0;     // 数据计数清零准备下次存入
            if (IRdata[0] == ~IRdata[1] && IRdata[2] == ~IRdata[3]) {
                IRdone = 1; // 32位数据接收完成
                IRcord[0] = IRdata[0];
                IRcord[1] = IRdata[2];
            }
        }
    } else {
        IRtime = 0;
        startflag = 1;
    }
}

7.开机初始化

/* 开机初始化 */
void init()
{
    // 初始化时钟模块
    DS1302_write_byte(0x8e, 0x80); // 开写保护
    // 初始化LCD1802液晶
    delay_ms(15);
    LCD_write_cmd(0x38);
    delay_ms(5);
    LCD_write_cmd(0x38);
    delay_ms(5);
    LCD_write_cmd(0x38);
    LCD_wait_cmd(0x38);     // 显示模式设置
    LCD_wait_cmd(0x0c);     // 开显示 不显示光标 光标不闪烁
    LCD_wait_cmd(_LCD_CLS); // 显示清屏
    /* 红外通讯初始化 - 使用定时器1 */
    TMOD = (TMOD & 0x0f) | 0x20;
    TH1 = 0;
    TL1 = 0;
    TR1 = 1;
    EA = 1;  // 开总中断
    ET1 = 1; // 开定时器1中断
    EX0 = 1; // 开外部中断0
    IT0 = 1; // 设置外部中断0边沿触发
    TR1 = 1; // 启动定时器0
}

8.特殊功能函数

/* 转换函数 */
// 组合BCD码转换函数
BYTE to_BCD(BYTE _Dat)
{
    return ((_Dat / 10) << 4) | _Dat % 10;
}
// 非组合BCD码 ---> 可显示字符ASCII
BYTE to_hex(BYTE _Dat)
{
    _Dat += _Dat < 10 ? '0' : '7';
    return _Dat;
}

// 返回是否是闰年
bit is_leap(WORD _Year)
{
    return _Year % 4 == 0 && _Year % 100 != 0 || _Year % 400 == 0;
}

/* 延时函数 */
// 低精度毫秒级延时
void delay_ms(WORD _Ms)
{
    BYTE x;
    while (_Ms--)
        for (x = 144; x > 0; x--)
            ;
}
// 定时器0延时
void timer0_delay(WORD _Th)
{
    TMOD = (TMOD & 0xf0) | 0x01;
    TH0 = _Th >> 8;
    TL0 = _Th & 0xff;
    TR0 = 1;
    while (TF0 == 0)
        ;
    TF0 = 0;
}

9.代码段常量

// 星期的英文缩写
char code weekday[7][3] = {
    "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
// 一个月有几天(平年)
BYTE code monthday[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

10.完整代码

#include <reg52.h>
#include <intrins.h>

/* typedef */
typedef unsigned char BYTE;
typedef unsigned short WORD;

/* cast */
BYTE to_BCD(BYTE _Dat)
{
    return ((_Dat / 10) << 4) | _Dat % 10;
}
BYTE to_hex(BYTE _Dat)
{
    _Dat += _Dat < 10 ? '0' : '7';
    return _Dat;
}

char code weekday[7][3] = {
    "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
BYTE code monthday[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bit is_leap(WORD _Year)
{
    return _Year % 4 == 0 && _Year % 100 != 0 || _Year % 400 == 0;
}

/* 时钟模块 */
sbit TSCLK = P1 ^ 0;
sbit TIO = P1 ^ 1;
sbit TEN = P1 ^ 2;
// 读一字节
BYTE DS1302_read_byte(BYTE _Cmd)
{
    BYTE i;
    TEN = 0;
    TSCLK = 0;
    TEN = 1;
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        TIO = _Cmd & 0x01;
        TSCLK = 1;
        _Cmd >>= 1;
    }
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        _Cmd >>= 1;
        if (TIO)
            _Cmd |= 0x80;
        TSCLK = 1;
    }
    return _Cmd;
}
// 写一字节
void DS1302_write_byte(BYTE _Cmd, BYTE _Dat)
{
    BYTE i;
    TEN = 0;
    TSCLK = 0;
    TEN = 1;
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        TIO = _Cmd & 0x01;
        TSCLK = 1;
        _Cmd >>= 1;
    }
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        TIO = _Dat & 0x01;
        TSCLK = 1;
        _Dat >>= 1;
    }
}
// 时钟突发突发模式读
void clock_brust_read(BYTE *_Buf)
{
    BYTE i, j = 0xbf;
    TEN = 0;
    TSCLK = 0;
    TEN = 1;
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        TIO = j & 0x01;
        TSCLK = 1;
        j >>= 1;
    }
    for (i = 0; i < 7; i++)
        for (j = 0; j < 8; j++) {
            TSCLK = 0;
            _Buf[i] >>= 1;
            if (TIO)
                _Buf[i] |= 0x80;
            TSCLK = 1;
        }
}
// 时钟突发突发模式写
void clock_brust_write(const BYTE *_Buf)
{
    BYTE i, j = 0xbe, k;
    TEN = 0;
    TSCLK = 0;
    TEN = 1;
    for (i = 0; i < 8; i++) {
        TSCLK = 0;
        TIO = j & 0x01;
        TSCLK = 1;
        j >>= 1;
    }
    for (i = 0; i < 7; i++) {
        k = _Buf[i];
        for (j = 0; j < 8; j++) {
            TSCLK = 0;
            TIO = k & 0x01;
            TSCLK = 1;
            k >>= 1;
        }
    }
}

/* 延时 */
// 低精度毫秒级延时
void delay_ms(WORD _Ms)
{
    BYTE x;
    while (_Ms--)
        for (x = 144; x > 0; x--)
            ;
}
// 定时器0延时
void timer0_delay(WORD _Th)
{
    TMOD = (TMOD & 0xf0) | 0x01;
    TH0 = _Th >> 8;
    TL0 = _Th & 0xff;
    TR0 = 1;
    while (TF0 == 0)
        ;
    TF0 = 0;
}

/* LCD1802液晶 */
#define LCD_DATA P0
sbit LCD_RS = P3 ^ 5; // 数据/命令选择端
sbit LCD_WR = P3 ^ 6; // 读/写选择端
sbit LCD_EN = P3 ^ 4; // 使能端
// 读状态
BYTE LCD_read_state()
{
    BYTE state;
    LCD_RS = 0;
    LCD_WR = 1;
    LCD_EN = 1;
    state = LCD_DATA;
    LCD_EN = 0;
    return state;
}
// 写指令
void LCD_write_cmd(BYTE _Cmd)
{
    LCD_EN = 0;
    LCD_EN = 1;
    LCD_RS = 0;
    LCD_WR = 0;
    LCD_DATA = _Cmd;
    LCD_EN = 0;
}
// 读数据
BYTE LCD_read_data()
{
    BYTE i;
    LCD_RS = 1;
    LCD_WR = 1;
    LCD_EN = 1;
    i = LCD_DATA;
    LCD_EN = 0;
    return i;
}
// 写数据
void LCD_write_data(BYTE _Dat)
{
    LCD_EN = 0;
    LCD_EN = 1;
    LCD_RS = 1;
    LCD_WR = 0;
    LCD_DATA = _Dat;
    LCD_EN = 0;
}
// 等待写指令
void LCD_wait_cmd(BYTE _Cmd)
{
    while (LCD_read_state() & 0x80)
        ;
    LCD_write_cmd(_Cmd);
}
// 等待写数据
void LCD_wait_write_data(BYTE _Dat)
{
    while (LCD_read_state() & 0x80)
        ;
    LCD_write_data(_Dat);
}
// 等待读数据
BYTE LCD_wait_read_data()
{
    while (LCD_read_state() & 0x80)
        ;
    return LCD_read_data();
}
// 写入字符串
void LCD_write_string(const char *_Str)
{
    BYTE i = 0;
    while (_Str[i])
        LCD_wait_write_data(_Str[i++]);
}
#define _LCD_CLS 0x01 // 显示清屏

/* 1-wire总线 */
sbit DS18B20 = P2 ^ 2;
// 1-wire初始化时序
void init_DS18B20()
{
    do {
        DS18B20 = 1;
        _nop_();
        DS18B20 = 0;
        timer0_delay(65074); // delay 499.45 us
        DS18B20 = 1;
        timer0_delay(65500); // delay 37.95 us
    } while (DS18B20);
    timer0_delay(65404); // delay 141.95 us
    DS18B20 = 1;
    _nop_();
}
// 1-wire写时序
void write_byte_1wire(BYTE _Dat)
{
    BYTE i;
    for (i = 0; i < 8; i++) {
        DS18B20 = 0;
        _nop_();
        DS18B20 = _Dat & 0x01 ? 1 : 0;
        timer0_delay(65464); // delay 76.95 us
        DS18B20 = 1;
        _nop_();
        _Dat >>= 1;
    }
}
// 1-wire读时序
BYTE read_byte_1wire()
{
    BYTE dat = 0, i;
    for (i = 0; i < 8; i++) {
        dat >>= 1;
        DS18B20 = 0;
        _nop_(); // 产生读时序
        DS18B20 = 1;
        _nop_(); // 释放总线
        if (DS18B20)
            dat |= 0x80;
        timer0_delay(65464); // delay 76.95 us
    }
    return dat;
}
// ROM指令
#define _SEARCH_ROM 0xf0 // 搜索 ROM 指令
#define _READ_ROM   0x33 // 读取 ROM 指令
#define _MATH_ROM   0x55 // 匹配 ROM 指令
#define _SIKP_ROM   0xcc // 忽略 ROM 指令
#define _ALARM_ROM  0xec // 报警搜索指令
// DS18B20功能指令
#define _CONVERT_T         0x44 // 温度转换指令
#define _WRITE_SCRATCHPAD  0x4e // 写暂存器指令
#define _READ_SCRATCHPAD   0xbe // 读暂存器指令
#define _COPY_SCRATCHPAD   0x48 // 拷贝暂存器指令
#define _RECALL_E2         0xb8 // 召回 EEPROM 指令
#define _READ_POWER_SUPPLY 0xb4 // 读电源模式指令

/* 红外通讯 */
BYTE IRtime;    // 红外高低电平持续时间
BYTE IRcord[2]; // 8位地址+8位数据
bit IRdone = 0; // 数据接收完成标志位
// 定时器1中断 - 每中断一次需要256个机器周期
void timer1() interrupt 3
{
    IRtime++; // _MACHINE_CYCLE*256=277.76 μs
}
// 外部中断0
void int0() interrupt 0
{
    static BYTE i;            // 32次数据计数
    static bit startflag = 0; // 开始储存脉宽标志位
    static BYTE IRdata[4];    // 数据接收缓冲区
    BYTE j;
    if (startflag) {
        if (IRtime >= 32 && IRtime < 53) { // 起始码判定 8.8ms~14ms
            i = 0;
            IRtime = 0;
            return;
        }
        j = (i++) >> 3;
        IRdata[j] >>= 1;
        if (IRtime > 5) // 数据0=高电平560μs+低电平560μs=1120μs
            IRdata[j] |= 0x80;
        IRtime = 0;    // 计数清零
        if (i == 32) { // 如果已经存入了32次脉宽
            i = 0;     // 数据计数清零准备下次存入
            if (IRdata[0] == ~IRdata[1] && IRdata[2] == ~IRdata[3]) {
                IRdone = 1; // 32位数据接收完成
                IRcord[0] = IRdata[0];
                IRcord[1] = IRdata[2];
            }
        }
    } else {
        IRtime = 0;
        startflag = 1;
    }
}

/* 开机初始化 */
void init()
{
    /* 初始化数码管 */
    NIXIE_TUBE = 0x00;
    DU = 1;
    DU = 0;
    WE = 0;
    // 初始化时钟模块
    DS1302_write_byte(0x8e, 0x80); // 开写保护
    // 初始化LCD1802液晶
    delay_ms(15);
    LCD_write_cmd(0x38);
    delay_ms(5);
    LCD_write_cmd(0x38);
    delay_ms(5);
    LCD_write_cmd(0x38);
    LCD_wait_cmd(0x38);     // 显示模式设置
    LCD_wait_cmd(0x0c);     // 开显示 不显示光标 光标不闪烁
    LCD_wait_cmd(_LCD_CLS); // 显示清屏
    /* 红外通讯初始化 - 使用定时器1 */
    TMOD = (TMOD & 0x0f) | 0x20;
    TH1 = 0;
    TL1 = 0;
    TR1 = 1;
    EA = 1;  // 开总中断
    ET1 = 1; // 开定时器1中断
    EX0 = 1; // 开外部中断0
    IT0 = 1; // 设置外部中断0边沿触发
    TR1 = 1; // 启动定时器0
}

void main()
{
    BYTE i, j, k;
    BYTE buf[7] = {0, 2, 13, 17, 11, 4, 22};
    char line1[17] = "2022/03/11 Wed:3";
    char line2[17] = "21:40:00 PM 37C";
    WORD temp;
    bit IRflag = 0;
    BYTE cursor = 0x00;
    for (i = 0; i < 7; i++)
        buf[i] = to_BCD(buf[i]);
    init();
    DS1302_write_byte(0x8e, 0x00); // 关写保护
    clock_brust_write(buf);
    DS1302_write_byte(0x8e, 0x80); // 开写保护
    while (1) {
        clock_brust_read(buf);
        /* update line1 */
        line1[2] = '0' + (buf[6] >> 4);
        line1[3] = '0' + (buf[6] & 0x0f);
        line1[5] = '0' + (buf[4] >> 4);
        line1[6] = '0' + (buf[4] & 0x0f);
        line1[8] = '0' + (buf[3] >> 4);
        line1[9] = '0' + (buf[3] & 0x0f);
        buf[5]--;
        line1[11] = weekday[buf[5]][0];
        line1[12] = weekday[buf[5]][1];
        line1[13] = weekday[buf[5]][2];
        buf[5]++;
        line1[15] = '0' + buf[5];
        /* update line2 */
        line2[0] = '0' + (buf[2] >> 4);
        line2[1] = '0' + (buf[2] & 0x0f);
        line2[3] = '0' + (buf[1] >> 4);
        line2[4] = '0' + (buf[1] & 0x0f);
        line2[6] = '0' + (buf[0] >> 4);
        line2[7] = '0' + (buf[0] & 0x0f);
        line2[9] = buf[2] >= 0x12 ? 'P' : 'A';
        /* update temperature */
        init_DS18B20();
        write_byte_1wire(_SIKP_ROM);
        write_byte_1wire(_CONVERT_T);
        init_DS18B20();
        write_byte_1wire(_SIKP_ROM);
        write_byte_1wire(_READ_SCRATCHPAD);
        temp = read_byte_1wire();
        temp |= read_byte_1wire() << 8;
        temp >>= 4;
        line2[12] = '0' + temp / 10;
        line2[13] = '0' + temp % 10;
        /* display */
        LCD_wait_cmd(0x80);
        LCD_write_string(line1);
        LCD_write_cmd(0xc0);
        LCD_write_string(line2);
        /* IR receive */
        if (IRdone) {
            if (IRcord[0] == 0x00) {
                if (IRflag == 0)
                    IRflag = 1;
                else
                    switch (IRcord[1]) {
                        case 0x44: // PREV
                            switch (cursor) {
                                case 0x05:
                                case 0x08:
                                case 0x43:
                                case 0x46:
                                    cursor -= 2;
                                    break;
                                case 0x0f:
                                    cursor = 0x09;
                                    break;
                                case 0x40:
                                    cursor = 0x0f;
                                    break;
                                case 0x00:
                                    cursor = 0x47;
                                    break;
                                default:
                                    cursor--;
                            }
                            break;
                        case 0x40: // NEXT
                            switch (cursor) {
                                case 0x03:
                                case 0x06:
                                case 0x41:
                                case 0x44:
                                    cursor += 2;
                                    break;
                                case 0x09:
                                    cursor = 0x0f;
                                    break;
                                case 0x0f:
                                    cursor = 0x40;
                                    break;
                                case 0x47:
                                    cursor = 0x00;
                                    break;
                                default:
                                    cursor++;
                            }
                            break;
                        case 0x07: // VOL-
                        case 0x15: // VOL+
                            j = IRcord[1] == 0x15 ? 0x01 : 0x09;
                            switch (cursor) {
                                case 0x00:
                                case 0x01:
                                    line1[cursor] = (line1[cursor] - '0' + j) % 10 + '0';
                                    LCD_wait_cmd(0x80 | cursor);
                                    LCD_wait_write_data(line1[cursor]);
                                    break;
                                case 0x02:
                                case 0x03:
                                    DS1302_write_byte(0x8e, 0x00); // 关写保护
                                    i = DS1302_read_byte(0x8d);
                                    i += j << ((0x03 - cursor) << 2);
                                    i = (((i >> 4) % 10) << 4) | ((i & 0x0f) % 10);
                                    DS1302_write_byte(0x8c, i);
                                    DS1302_write_byte(0x8e, 0x80); // 开写保护
                                    break;
                                case 0x05:
                                case 0x06:
                                    DS1302_write_byte(0x8e, 0x00); // 关写保护
                                    i = DS1302_read_byte(0x89);
                                    if (cursor == 0x05) {
                                        if (i >> 4)
                                            i &= 0x0f;
                                        else {
                                            i |= 0x10;
                                            if (i > 0x12)
                                                i &= 0x0f;
                                        }
                                    } else {
                                        k = i & 0x0f;
                                        i &= 0xf0;
                                        if (i && j == 0x09)
                                            j = 0x02;
                                        k = (k + j) % (i ? 3 : 10);
                                        i |= k;
                                    }
                                    DS1302_write_byte(0x88, i);
                                    DS1302_write_byte(0x8e, 0x80); // 开写保护
                                    break;
                                case 0x08:
                                case 0x09:
                                    i = buf[3]; // 日
                                    buf[4] = (buf[4] >> 4) * 10 + (buf[4] & 0x0f);
                                    buf[3] = monthday[buf[4] - 1];
                                    if (buf[4] == 2 && is_leap((WORD)(line1[0] - '0') * 1000 + (WORD)(line1[1] - '0') * 100 + (WORD)buf[6]))
                                        buf[3]++;
                                    if (cursor == 0x08) {
                                        buf[0] = buf[3] / 10; // mod
                                        if ((i & 0x0f) <= buf[3] % 10)
                                            buf[0]++;
                                        if (j == 0x09)
                                            j = buf[0] - 1;
                                        k = i >> 4;
                                        i &= 0x0f;
                                        k = (k + j) % buf[0];
                                        i |= k << 4;
                                    } else {
                                        buf[0] = 10; // mod;
                                        if ((i >> 4) == buf[3] / 10)
                                            buf[0] = buf[3] % 10;
                                        if (buf[0]) {
                                            if (j == 0x09)
                                                j = buf[0] - 1;
                                            k = i & 0x0f;
                                            i &= 0xf0;
                                            k = (k + j) % buf[0];
                                            i |= k;
                                        }
                                    }
                                    DS1302_write_byte(0x8e, 0x00); // 关写保护
                                    DS1302_write_byte(0x86, i);
                                    DS1302_write_byte(0x8e, 0x80); // 开写保护
                                    break;
                                case 0x0f:
                                    i = buf[5];
                                    if (j == 0x09)
                                        j = 0x06;
                                    i = (i - 1 + j) % 7 + 1;
                                    DS1302_write_byte(0x8e, 0x00); // 关写保护
                                    DS1302_write_byte(0x8a, i);
                                    DS1302_write_byte(0x8e, 0x80); // 开写保护
                                    break;
                                case 0x40:
                                case 0x41:
                                    i = buf[2];
                                    if (cursor == 0x40) {
                                        buf[0] = 2; // mod
                                        if ((i & 0x0f) < 4)
                                            buf[0]++;
                                        if (j == 0x09)
                                            j = buf[0] - 1;
                                        k = i >> 4;
                                        i &= 0x0f;
                                        k = (k + j) % buf[0];
                                        i |= k << 4;
                                    } else {
                                        buf[0] = i >> 4 < 2 ? 10 : 4; // mod
                                        if (j == 0x09)
                                            j = buf[0] - 1;
                                        k = i & 0x0f;
                                        i &= 0xf0;
                                        k = (k + j) % buf[0];
                                        i |= k;
                                    }
                                    DS1302_write_byte(0x8e, 0x00); // 关写保护
                                    DS1302_write_byte(0x84, i);
                                    DS1302_write_byte(0x8e, 0x80); // 开写保护
                                    break;
                                case 0x43:
                                case 0x44:
                                case 0x46:
                                case 0x47:
                                    i = buf[cursor <= 0x44 ? 1 : 0];
                                    if (cursor == 0x43 || cursor == 0x46) {
                                        if (j == 0x09)
                                            j = 0x05;
                                        k = i >> 4;
                                        i &= 0x0f;
                                        k = (k + j) % 0x06;
                                        i |= k << 4;
                                    } else {
                                        k = i & 0x0f;
                                        i &= 0xf0;
                                        k = (k + j) % 10;
                                        i |= k;
                                    }
                                    DS1302_write_byte(0x8e, 0x00); // 关写保护
                                    DS1302_write_byte(cursor <= 0x44 ? 0x82 : 0x80, i);
                                    DS1302_write_byte(0x8e, 0x80); // 开写保护
                                    break;
                            }
                            break;
                        case 0x09: // EQ
                            IRflag = 0;
                            LCD_wait_cmd(0x0c);
                            break;
                    }
            }
            IRdone = 0;
        }
        /* IR display */
        if (IRflag) {
            LCD_wait_cmd(0x80 | cursor);
            LCD_wait_cmd(0x0e);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/16097.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hybrid app混合开发的一些经验和总结

随着5G技术的发展和移动终端普及&#xff0c;移动设备的便捷性和网络的泛在化&#xff0c;移动应用已广泛应用于电子商务、电子政务、医疗和辅助教学中。 智能手机等移动终端的存储、运算能力不断增强&#xff0c;但其显示、输入等不如PC灵活&#xff0c;对操作界面灵活性有强…

Redis 搭建高可用集群

、单个redis服务搭建请参考&#xff1a;redis服务搭建 2、在/usr/local下创建目录redis-cluster,并在redis-cluster下创建 6379、6380、6381目录以及data、temp目录 # cd /usr/local # mkdir redis-cluster --其他文件创建类似&#xff0c;此处不一一写出 3、复制安装后的re…

[笔记]快乐的Linux命令行《二》文件系统中跳转

系列文章目录 [笔记]快乐的Linux命令行《一》LInux系统简介以及什么是shell [笔记]快乐的Linux命令行《二》文件系统中跳转 文章目录系列文章目录前言一、文件系统中跳转1.1 理解文件系统树Linux基本文件系统树目录介绍与Windows的异同1.2 当前工作目录pwd 显示当前工作目录1.…

CSS基础入门

CSS基础入门 1.官方文档 1.CSS 指的是层叠样式表* (Cascading Style Sheets) 2.地址: https://www.w3school.com.cn/css/index.asp 2.为什么需要 CSS 1.在没有 CSS 之前&#xff0c;我们想要修改 HTML 元素的样式需要为每个 HTML 元素单独定义样式属性&#xff0c;费心费力…

手把手教你如何编写一个Makefile文件

一、概念理解&#xff08;彩蛋藏在某个地方&#xff09; 1.1 什么是Makefile&#xff1f; C语言中&#xff0c;我们使用visual studio开发软件时候&#xff0c;写程序开始时候都会创建一个project项目文件&#xff0c;然后在文件里面编译 .h 和 .c 的文件。在Linux中&#xf…

给大家免费发布几款苹果CMSv10模板影视主题,附带教程和演示截图

苹果CMS是优秀的开源PHP建站系统,在主流建站系统中特色鲜明,以灵活、小巧、兼容性好、负载强等优点而深受许多站长的喜爱。 很多人在运营苹果cms站点都会找模板&#xff0c;下面博主给大家推荐几款免费并且简约的模板&#xff0c;其实个人认为模板这东西不需要买太贵的&#xf…

编译安装LAMP架构搭建wordpress个人博客和discuz论坛——编译安装基于 FASTCGI 模式LAMP架构多虚拟主机WEB应用

文章目录1 实验目标2 环境准备3 实现步骤3.1.1 二进制安装3.1.2为wordprss和discuz应用准备数据库和用户帐号3.2 编译安装 httpd 2.43.3 编译安装 fastcgi 方式的 php 7.43.4 修改配置 httpd 支持 php-fpm3.5 准备wordpress和discuz! 相关文件3.6 测试访问3.7 安装成功1 实验目…

MySQL高级篇知识点——其它数据库日志

目录1.其他数据库日志1.1.日志类型1.2.日志的弊端2.慢查询日志 (slow query log)3.通用查询日志 (general query log)3.1.问题场景3.2.查看当前状态3.3.启动日志3.4.查看日志3.5.停止日志3.6.删除/刷新日志4.错误日志 (error log)4.1.启动日志4.2.查看日志4.3.删除/刷新日志5.二…

Glide图片框架源码解析

一、Glide几个基本概念 Model 表示数据的来源&#xff1b;加载图片的时候需要告诉Glide从哪获取这个图片&#xff0c;可以是url类型、本地文件类型、资源ID类型。不管什么类型&#xff0c;Glide都将其称为Model。 Data 从数据源中获取到model之后&#xff0c;把它加工成原始数…

java.swing 飞机大战小游戏

上午没事刷到网上最近炒热了一些简单的小游戏和爱心代码&#xff0c;单身8个月了&#xff0c;对爱心代码不是很感冒&#xff0c;所以想蹭个热度&#xff0c;写一个飞机大站来玩玩。 首先&#xff0c;分析小游戏需要那些技术与怎么设计&#xff1a; 窗体&#xff0c;因为是jav…

Python如何使用PyMySQL连接数据库

1&#xff1a;为什么要连接数据库呢&#xff1f; 做接口自动化测试的时候&#xff0c;我们需要校验数据是否正常入库&#xff0c;数据是否正确&#xff0c;来做断言处理&#xff1b;有的时候需要修改数据&#xff0c;去执行其他场景的测试用例&#xff1b;有的时候需要删除数据…

DOX-HSA/HGB/FITC/Glu人血清蛋白/血红蛋白/荧光素/葡萄糖修饰阿霉素

小编今天分享给大家的科研知识是DOX-HSA/HGB/FITC/Glu人血清蛋白/血红蛋白/荧光素/葡萄糖修饰阿霉素&#xff0c;来看&#xff01; DOX-HSA人血清蛋白偶联阿霉素相关&#xff1a; 采用阿霉素(Doxorubicin,DOX)与人血清白蛋白(HSA)经化学交联获得的偶联物。本品经过滤,溶于PBS…

Chapter4 利用机器学习解决分类和回归问题

目录 4.1 机器学习和神经网络基本概念 4.1.1 感知器 4.1.2 前向传播 4.1.3 反向传播 4.1.4 过拟合和欠拟合 4.2 利用神经网络解决回归问题 4.2.1 问题介绍 4.2.2 利用pytorch解析数据 4.2.2 利用pytorch定义网络结构 4.2.3 开始训练 4.2.4 将模型进行保存 4.3 利用p…

云中马在A股上市:总市值约为40亿元,叶福忠为实际控制人

11月18日&#xff0c;浙江云中马股份有限公司&#xff08;下称“云中马”&#xff0c;SH:603130&#xff09;在上海证券交易所主板上市。本次上市&#xff0c;云中马的发行价为19.72元/股&#xff0c;发行数量为3500万股&#xff0c;募资总额约为6.90亿元&#xff0c;募资金额约…

码农必备?清华大学开源了一款写代码神器。。。

程序员宝藏库&#xff1a;https://gitee.com/sharetech_lee/CS-Books-Store 提升程序员编码效率&#xff0c;是一个经久不衰的话题&#xff0c;从最初用纯文本编辑器到后来代码自动补全&#xff0c;再到后来基于AI智能补全代码&#xff0c;开发者效率的确在不断提升。 关于新工…

这就是程序员眼中的函数吗?(一)

小叮当的任意门1. 函数是什么&#xff1f;2. C语言中的函数分类1. 库函数2. 自定义函数3. 函数的参数1. 实际参数&#xff08;实参&#xff09;2. 形式参数&#xff08;形参&#xff09;4. 函数的调用1. 传值调用2. 传址调用练习1. 写一个函数可以判断一个数是不是素数三级标题…

5分钟实现「视频检索」:基于内容理解,无需任何标签

Notebook 教程&#xff1a;text-video retrieval 「视频检索」任务就是输入一段文本&#xff0c;检索出最符合文本描述的视频。随着各类视频平台的兴起和火爆&#xff0c;网络上视频的数量呈现井喷式增长&#xff0c;「视频检索」成为人们高效查找视频的一项新需求。传统的视频…

Matlab点云处理及可视化第1期—基于KD树的邻域点搜索(柱状邻域、球状邻域及KNN)

目录 1 概述 2 代码实现 3 可视化验证 数据及完整代码获取方式&#xff1a; 观前提示&#xff1a;本文文字内容请勿直接用于论文写作&#xff0c;否则后果自负。 特别提示&#xff1a;《Matlab点云处理及可视化》系列文章旨在为初入点云处理领域的朋友提供一份较为权威、可…

MR直播(混合现实直播)做一场高品质企业培训

阿酷TONY / 2022-11-18 / 长沙 MR&#xff0c;是英文Mixed Reality两个单词的缩写&#xff0c;中文翻译为混合现实。 MR混合现实直播技术是通过在现实环境中引入虚拟场景信息&#xff0c;增强用户体验的真实感&#xff0c;具有真实性、实时互动性等特点。 MR直播解决方案是深…

基于springboot农产品交易平台的设计与实现

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于特色农产品电商平台 当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了特色农产品电商平台&#xff0c;它彻底…