#include <REG51.H>
#include <INTRINS.H>
#include <STRING.H>
#include <stdio.h>
// ==================== ???? ==================== //
// LCD1602??
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
#define LCD_DATA_PORT P0
// DS1302??
sbit DS1302_SCLK = P3^6;
sbit DS1302_IO = P3^4;
sbit DS1302_RST = P3^5;
// DS18B20??
sbit DS18B20_DQ = P1^0;
// ????
sbit KEY_SET_TIME = P1^1;
sbit KEY_SET_ALARM = P1^2;
sbit KEY_SUB = P1^3;
sbit KEY_ADD = P1^4;
// ?????
sbit BUZZER = P3^7;
// ==================== ???? ==================== //
typedef unsigned char uint8;
typedef unsigned int uint16;
// ==================== ???? ==================== //
uint8 g_setMode = 0; // 0:????, 1:????, 2:????, 3:????
uint8 g_hourSet = 0, g_minSet = 0, g_secSet = 0;
uint8 g_yearSet = 0, g_monSet = 0, g_daySet = 0;
uint8 g_hourAlarm = 0, g_minAlarm = 0;
uint8 g_hour = 0, g_min = 0, g_sec = 0;
uint8 g_year = 0, g_mon = 0, g_day = 0;
int g_temp = 0;
char *weekDays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
// ==================== ????(??11.0592MHz) ==================== //
void DelayMs(uint16 ms) {
uint16 i, j;
for (i = 0; i < ms; i++) {
for (j = 0; j < 113; j++); // 11.0592MHz??1ms
}
}
void DelayUs(uint8 us) {
while (us--) {
_nop_(); _nop_(); _nop_(); // 3?????3.25µs(???)
}
}
// ==================== LCD1602???? ==================== //
void LCD_WriteCmd(uint8 cmd) {
LCD_RS = 0;
LCD_RW = 0;
LCD_DATA_PORT = cmd;
DelayMs(1);
LCD_EN = 1;
DelayMs(1);
LCD_EN = 0;
}
void LCD_WriteData(uint8 dat) {
LCD_RS = 1;
LCD_RW = 0;
LCD_DATA_PORT = dat;
DelayMs(1);
LCD_EN = 1;
DelayMs(1);
LCD_EN = 0;
}
void LCD_Init(void) {
LCD_WriteCmd(0x38);
LCD_WriteCmd(0x0C);
LCD_WriteCmd(0x06);
LCD_WriteCmd(0x01);
DelayMs(2);
}
void LCD_ShowString(uint8 row, uint8 col, char *str) {
uint8 addr = (row == 0 ? 0x80 : 0xC0) + col;
LCD_WriteCmd(addr);
while (*str != '\0') {
LCD_WriteData(*str);
str++;
DelayMs(1);
}
}
// ==================== DS1302???? ==================== //
void DS1302_WriteByte(uint8 addr, uint8 dat) {
uint8 i;
DS1302_RST = 1;
for (i = 0; i < 8; i++) {
DS1302_SCLK = 0;
DS1302_IO = addr & 0x01;
addr >>= 1;
DS1302_SCLK = 1;
DelayUs(2);
}
for (i = 0; i < 8; i++) {
DS1302_SCLK = 0;
DS1302_IO = dat & 0x01;
dat >>= 1;
DS1302_SCLK = 1;
DelayUs(2);
}
DS1302_RST = 0;
}
uint8 DS1302_ReadByte(uint8 addr) {
uint8 i, dat = 0;
DS1302_RST = 1;
addr |= 0x01;
for (i = 0; i < 8; i++) {
DS1302_SCLK = 0;
DS1302_IO = addr & 0x01;
addr >>= 1;
DS1302_SCLK = 1;
DelayUs(2);
}
for (i = 0; i < 8; i++) {
DS1302_SCLK = 0;
DS1302_SCLK = 1;
dat >>= 1;
if (DS1302_IO) {
dat |= 0x80;
}
DelayUs(2);
}
DS1302_RST = 0;
return dat;
}
void DS1302_GetTime(uint8 *hour, uint8 *min, uint8 *sec, uint8 *year, uint8 *mon, uint8 *day) {
uint8 temp;
temp = DS1302_ReadByte(0x00);
*sec = ((temp & 0x70) >> 4) * 10 + (temp & 0x0F);
temp = DS1302_ReadByte(0x02);
*min = ((temp & 0x70) >> 4) * 10 + (temp & 0x0F);
temp = DS1302_ReadByte(0x04);
*hour = ((temp & 0x30) >> 4) * 10 + (temp & 0x0F);
temp = DS1302_ReadByte(0x07);
*day = ((temp & 0x30) >> 4) * 10 + (temp & 0x0F);
temp = DS1302_ReadByte(0x08);
*mon = ((temp & 0x10) >> 4) * 10 + (temp & 0x0F);
temp = DS1302_ReadByte(0x0A);
*year = ((temp & 0xF0) >> 4) * 10 + (temp & 0x0F);
}
void DS1302_SetTime(uint8 hour, uint8 min, uint8 sec, uint8 year, uint8 mon, uint8 day) {
DS1302_WriteByte(0x80, ((sec / 10) << 4) | (sec % 10));
DS1302_WriteByte(0x82, ((min / 10) << 4) | (min % 10));
DS1302_WriteByte(0x84, ((hour / 10) << 4) | (hour % 10));
DS1302_WriteByte(0x86, ((day / 10) << 4) | (day % 10));
DS1302_WriteByte(0x88, ((mon / 10) << 4) | (mon % 10));
DS1302_WriteByte(0x8A, ((year / 10) << 4) | (year % 10));
}
// ==================== DS18B20???? ==================== //
uint8 DS18B20_Init(void) {
uint8 res = 1;
DS18B20_DQ = 0;
DelayUs(750);
DS18B20_DQ = 1;
DelayUs(100);
res = DS18B20_DQ;
DelayMs(5);
return res;
}
uint8 DS18B20_ReadByte(void) {
uint8 i, dat = 0;
for (i = 0; i < 8; i++) {
DS18B20_DQ = 0;
_nop_();
DS18B20_DQ = 1;
dat >>= 1;
if (DS18B20_DQ) {
dat |= 0x80;
}
DelayUs(60);
}
return dat;
}
void DS18B20_WriteByte(uint8 dat) {
uint8 i;
for (i = 0; i < 8; i++) {
DS18B20_DQ = 0;
_nop_();
DS18B20_DQ = dat & 0x01;
dat >>= 1;
DelayUs(60);
DS18B20_DQ = 1;
}
}
int DS18B20_GetTemperature(void) {
uint8 temp_l, temp_h;
int temp = 0;
if (DS18B20_Init() == 0) {
DS18B20_WriteByte(0xCC);
DS18B20_WriteByte(0x44);
DelayMs(750);
DS18B20_Init();
DS18B20_WriteByte(0xCC);
DS18B20_WriteByte(0xBE);
temp_l = DS18B20_ReadByte();
temp_h = DS18B20_ReadByte();
temp = (temp_h << 8) | temp_l;
if (temp < 0) {
temp = ~temp + 1;
temp = -temp;
}
temp = (temp * 0.0625) * 10;
}
return temp;
}
// ==================== ?????? ==================== //
bit IsLeapYear(uint8 year) {
// 2000-2099???????
year += 2000;
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
return 1;
}
return 0;
}
// ==================== ?????? ==================== //
uint8 GetMonthDays(uint8 year, uint8 month) {
uint8 days;
if (month == 2) {
days = IsLeapYear(year) ? 29 : 28;
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
days = 30;
} else {
days = 31;
}
return days;
}
// ==================== ???? ==================== //
uint8 CalculateWeekDay(uint8 year, uint8 month, uint8 day) {
// 2000-2099???Zeller?????
uint8 c, y, m, d, w;
year += 2000;
if (month < 3) {
month += 12;
year--;
}
c = year / 100;
y = year % 100;
m = month;
d = day;
w = y + (y / 4) + (c / 4) - 2 * c + (26 * (m + 1) / 10) + d - 1;
w %= 7;
return w;
}
// ==================== ?????? ==================== //
void KeyScan(void) {
static uint8 keyState = 0;
if (KEY_SET_TIME == 0 || KEY_SET_ALARM == 0 || KEY_SUB == 0 || KEY_ADD == 0) {
DelayMs(10);
if (keyState == 0) {
if (KEY_SET_TIME == 0) {
g_setMode = (g_setMode + 1) % 4; // ??????:0->1->2->3->0
if (g_setMode == 1) { // ??????
DS1302_GetTime(&g_hourSet, &g_minSet, &g_secSet, &g_year, &g_mon, &g_day);
} else if (g_setMode == 2) { // ??????
DS1302_GetTime(&g_hour, &g_min, &g_sec, &g_yearSet, &g_monSet, &g_daySet);
} else if (g_setMode == 3) { // ??????
g_hourAlarm = g_hour;
g_minAlarm = g_min;
}
} else if (KEY_SUB == 0) {
if (g_setMode == 1) { // ??????
if (g_secSet > 0) {
g_secSet--;
} else {
g_secSet = 59;
if (g_minSet > 0) {
g_minSet--;
} else {
g_minSet = 59;
g_hourSet = (g_hourSet > 0) ? g_hourSet - 1 : 23;
}
}
} else if (g_setMode == 2) { // ??????
if (g_daySet > 1) {
g_daySet--;
} else {
if (g_monSet > 1) {
g_monSet--;
} else {
g_monSet = 12;
if (g_yearSet > 0) {
g_yearSet--;
} else {
g_yearSet = 99;
}
}
g_daySet = GetMonthDays(g_yearSet, g_monSet);
}
} else if (g_setMode == 3) { // ??????
if (g_minAlarm > 0) {
g_minAlarm--;
} else {
g_minAlarm = 59;
g_hourAlarm = (g_hourAlarm > 0) ? g_hourAlarm - 1 : 23;
}
}
} else if (KEY_ADD == 0) {
if (g_setMode == 1) { // ??????
g_secSet++;
if (g_secSet >= 60) {
g_secSet = 0;
g_minSet++;
if (g_minSet >= 60) {
g_minSet = 0;
g_hourSet = (g_hourSet + 1) % 24;
}
}
} else if (g_setMode == 2) { // ??????
uint8 maxDays = GetMonthDays(g_yearSet, g_monSet); // ??maxDays??
g_daySet++;
if (g_daySet > maxDays) {
g_daySet = 1;
g_monSet++;
if (g_monSet > 12) {
g_monSet = 1;
g_yearSet = (g_yearSet + 1) % 100;
}
}
} else if (g_setMode == 3) { // ??????
g_minAlarm++;
if (g_minAlarm >= 60) {
g_minAlarm = 0;
g_hourAlarm = (g_hourAlarm + 1) % 24;
}
}
}
keyState = 1;
}
} else {
keyState = 0;
if (g_setMode == 1) { // ?????????????
DS1302_SetTime(g_hourSet, g_minSet, g_secSet, g_year, g_mon, g_day);
} else if (g_setMode == 2) { // ?????????????
DS1302_SetTime(g_hour, g_min, g_sec, g_yearSet, g_monSet, g_daySet);
}
}
}
// ==================== ?????? ==================== //
void UpdateDisplay(void) {
char dispBuf[20] = {0};
uint8 weekDay;
// ?????????
DS1302_GetTime(&g_hour, &g_min, &g_sec, &g_year, &g_mon, &g_day);
g_temp = DS18B20_GetTemperature();
weekDay = CalculateWeekDay(g_year, g_mon, g_day);
// ??????????
if (g_setMode == 2) { // ??????
sprintf(dispBuf, "SET:20%02d-%02d-%02d", g_yearSet, g_monSet, g_daySet);
} else { // ?????????
sprintf(dispBuf, "20%02d-%02d-%02d %3s", g_year, g_mon, g_day, weekDays[weekDay]);
}
LCD_ShowString(0, 0, dispBuf);
// ???????????????
if (g_setMode == 1) { // ??????
sprintf(dispBuf, "SET:%02d:%02d:%02d %2d.%dC", g_hourSet, g_minSet, g_secSet, g_temp / 10, g_temp % 10);
} else if (g_setMode == 3) { // ??????
sprintf(dispBuf, "ALM:%02d:%02d %2d.%dC", g_hourAlarm, g_minAlarm, g_temp / 10, g_temp % 10);
} else { // ????
sprintf(dispBuf, "%02d:%02d:%02d %2d.%dC", g_hour, g_min, g_sec, g_temp / 10, g_temp % 10);
}
LCD_ShowString(1, 0, dispBuf);
}
// ==================== ?????? ==================== //
void CheckAlarm(void) {
static bit alarmOn = 0;
static uint16 alarmTimer = 0;
if (g_setMode != 3 && g_hour == g_hourAlarm && g_min == g_minAlarm && g_sec == 0) {
alarmOn = 1;
alarmTimer = 0;
}
if (alarmOn) {
BUZZER = ~BUZZER; // ?????
DelayMs(100);
alarmTimer++;
// ????10??????
if (alarmTimer >= 100) {
alarmOn = 0;
BUZZER = 0;
}
}
}
// ==================== ?????? ==================== //
void CheckHourMusic(void) {
if (g_min == 0 && g_sec == 0 && g_setMode == 0) {
BUZZER = 1;
DelayMs(500);
BUZZER = 0;
}
}
// ==================== ??? ==================== //
void main() {
LCD_Init();
DS1302_SetTime(12, 0, 0, 24, 8, 1); // ????:2024?8?1?12:00:00
while (1) {
KeyScan();
UpdateDisplay();
CheckAlarm();
CheckHourMusic();
DelayMs(100);
}
}修改这个代码,使这个代码可以正常运行0错误