使用51单片机作为主控芯片,制作可调万年历
主控芯片 STC89C52
时钟芯片 DS1302
温度传感器 DS18B20
1602液晶 LCD12864
任意红外遥控器
晶振 11.0952M x1,32.768K x1
电阻、电容若干(详见实验原理图)
1602液晶屏显示:
年/月/日 星期
时:分:秒 AM/PM 温度

图1 1602液晶屏显示效果
红外遥控器任意按键进入调节模式
图2 调节模式显示效果
调节模式被选中的数值下方出现光标,按 < 键和 > 键移动光标,按 + 键和 - 键改变光标选中数值,按 = 键退出调节模式(键值需要自行设置)。
图3 调节模式中将星期四改变为星期五
LCD12864液晶屏VO端接电位器R21,调节R21,使液晶对比度最佳。

图4 可调万年历实验原理图
#include
#include
定义字节型变量BYTE和字变量WORD
typedef unsigned char BYTE;
typedef unsigned short WORD;
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;}}
}
#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 // 显示清屏
sbit DS18B20 = P2 ^ 2; // 温度传感器1-wire线
// 1-wire初始化时序
void init_DS18B20()
{do {DS18B20 = 1;_nop_();DS18B20 = 0;timer0_delay(65074); // delay 499.45 usDS18B20 = 1;timer0_delay(65500); // delay 37.95 us} while (DS18B20);timer0_delay(65404); // delay 141.95 usDS18B20 = 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 usDS18B20 = 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~14msi = 0;IRtime = 0;return;}j = (i++) >> 3;IRdata[j] >>= 1;if (IRtime > 5) // 数据0=高电平560μs+低电平560μs=1120μsIRdata[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()
{// 初始化时钟模块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; // 开外部中断0IT0 = 1; // 设置外部中断0边沿触发TR1 = 1; // 启动定时器0
}
/* 转换函数 */
// 组合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;
}
// 星期的英文缩写
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};
#include
#include /* 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 usDS18B20 = 1;timer0_delay(65500); // delay 37.95 us} while (DS18B20);timer0_delay(65404); // delay 141.95 usDS18B20 = 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 usDS18B20 = 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~14msi = 0;IRtime = 0;return;}j = (i++) >> 3;IRdata[j] >>= 1;if (IRtime > 5) // 数据0=高电平560μs+低电平560μs=1120μsIRdata[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; // 开外部中断0IT0 = 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;elseswitch (IRcord[1]) {case 0x44: // PREVswitch (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: // NEXTswitch (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; // modif ((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; // modif ((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; // modif (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: // EQIRflag = 0;LCD_wait_cmd(0x0c);break;}}IRdone = 0;}/* IR display */if (IRflag) {LCD_wait_cmd(0x80 | cursor);LCD_wait_cmd(0x0e);}}
}
上一篇:描写西双版纳的美句