可以手动设置初始时间和修改时间,可以设置闹钟时间,响应时蜂鸣器会响,步进电机会转动
#include
#include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
//定义步进电机连接端口
sbit A1=P2^0;
sbit B1=P2^1;
sbit C1=P2^2;
sbit D1=P2^3;
sbit RS = P2 ^ 4; //定义端口
sbit RW = P2 ^ 5;//定义读写端口
sbit EN = P2 ^ 6;//数据读写操作总控位
sbit keystop = P1 ^ 0; //停止输入
sbit keyh = P1 ^ 1;//定义修改小时按键
sbit keym = P1 ^ 2;//定义修改分钟按键
sbit keys = P1 ^ 3;//定义修改秒钟按键
sbit SPK = P1 ^ 4;//设置蜂鸣器端口
sbit en_SPK = P1 ^ 5;//停止蜂鸣器端口
sbit led = P1 ^ 6;//设置小灯端口
#define RS_CLR RS = 0
#define RS_SET RS = 1
#define RW_CLR RW = 0
#define RW_SET RW = 1
#define EN_CLR EN = 0
#define EN_SET EN = 1
#define Coil_A1 {A1=1;B1=0;C1=0;D1=0;}//A相通电,其他相断电
#define Coil_B1 {A1=0;B1=1;C1=0;D1=0;}//B相通电,其他相断电
#define Coil_C1 {A1=0;B1=0;C1=1;D1=0;}//C相通电,其他相断电
#define Coil_D1 {A1=0;B1=0;C1=0;D1=1;}//D相通电,其他相断电
#define Coil_OFF {A1=0;B1=0;C1=0;D1=0;}//全部断电
#define DataPort P0
int year = 2019, month = 6, day = 4;
unsigned char time[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
unsigned char count = 0;
unsigned char hour = 0, min = 0, sec = 0;
unsigned char hour_s_clock = 0;
unsigned char hour_g_clock = 0;
unsigned char min_s_clock = 0;
unsigned char min_g_clock = 0;
unsigned char sec_s_clock = 0;
unsigned char sec_g_clock = 0;
int month_s = 0;
int month_g = 0;
int day_s = 0;
int day_g = 0;
unsigned char flag = 0;
unsigned char flag2 = 0;
unsigned char mon[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};//12个月份的天数
unsigned char hour_alarm = -1;
unsigned char min_alarm = -1;
unsigned char sec_alarm = -1;
unsigned char hour_s_alarm = 0;
unsigned char hour_g_alarm = 0;
unsigned char min_s_alarm = 0;
unsigned char min_g_alarm = 0;
unsigned char sec_s_alarm = 0;
unsigned char sec_g_alarm = 0;
unsigned char Speed;//步进电机转动频率
unsigned char num = 0;//控制LED小灯闪烁频率
//精确延时
void DelayUs2x(unsigned char t) {
while (--t);
}
void DelayMs(unsigned char t) {
while (t--) {
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
//延时程序
void delay(unsigned char z)
{
unsigned char x, y;
for (x = z; x > 0; x--)
for (y = 110; y > 0; y--);
}
//判忙函数
bit LCD_Check_Busy(void) {
DataPort = 0xFF;
RS_CLR;
RW_SET;
EN_CLR;
_nop_();
EN_SET;
return (bit)(DataPort & 0x80);
}
//写入命令函数
void LCD_Write_Com(unsigned char com) {
// while(LCD_Check_Busy()); //忙则等待
DelayMs(5);
RS_CLR;
RW_CLR;
EN_SET;
DataPort = com;
_nop_();
EN_CLR;
}
//写入数据函数
void LCD_Write_Data(unsigned char Data) {
// while(LCD_Check_Busy()); //忙则等待
DelayMs(5);
RS_SET;
RW_CLR;
EN_SET;
DataPort = Data;
_nop_();
EN_CLR;
}
//清屏函数
void LCD_Clear(void) {
LCD_Write_Com(0x01);
DelayMs(5);
}
//写入字符串函数
void LCD_Write_String(unsigned char x, unsigned char y, unsigned char *s) {
if (y == 0) {
LCD_Write_Com(0x80 + x);
} else {
LCD_Write_Com(0xC0 + x);
}
while (*s) {
LCD_Write_Data(*s);
s++;
}
}
//写入字符函数
void LCD_Write_Char(unsigned char x, unsigned char y, unsigned char Data) {
if (y == 0) {
LCD_Write_Com(0x80 + x);
} else {
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data(Data);
}
//LCD初始化函数
void LCD_Init(void) {
LCD_Write_Com(0x38); /*显示模式设置*/
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*显示关闭*/
LCD_Write_Com(0x01); /*显示清屏*/
LCD_Write_Com(0x06); /*显示光标移动设置*/
DelayMs(5);
LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
//中断初始化
void interript_init()
{
count = 0;
hour = 0;
min = 0;
sec = 0;
TMOD = 0x01;//16位定时器
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
TR0 = 1;//定时器T0启动控制位
ET0 = 1;
EA = 1;//中断总控位
EX0 = 1;//外部中断0中断允许位
EX1 = 1;//外部中断1中断允许位
IT0 = 1;
PX0 = 1;//外部中断0中断优先级控制位
PX1 = 1;//外部中断1中断优先级控制位
}
//显示时钟
void display() {
hour_s_clock = hour / 10;
hour_g_clock = hour % 10;
min_s_clock = min / 10;
min_g_clock = min % 10;
sec_s_clock = sec / 10;
sec_g_clock = sec % 10;
LCD_Write_Char(0, 1, 't');
LCD_Write_Char(1, 1, 'i');
LCD_Write_Char(2, 1, 'm');
LCD_Write_Char(3, 1, 'e');
LCD_Write_Char(4, 1, ':');
LCD_Write_Char(5, 1, ' ');
LCD_Write_Char(6, 1, time[hour_s_clock]);
LCD_Write_Char(7, 1, time[hour_g_clock]);
LCD_Write_Char(8, 1, '-');
LCD_Write_Char(9, 1, time[min_s_clock]);
LCD_Write_Char(10, 1, time[min_g_clock]);
LCD_Write_Char(11, 1, '-');
LCD_Write_Char(12, 1, time[sec_s_clock]);
LCD_Write_Char(13, 1, time[sec_g_clock]);
}
//显示闹钟
void display2() {
hour_s_alarm = hour_alarm / 10;
hour_g_alarm = hour_alarm % 10;
min_s_alarm = min_alarm / 10;
min_g_alarm = min_alarm % 10;
sec_s_alarm = sec_alarm / 10;
sec_g_alarm = sec_alarm % 10;
LCD_Write_Char(0, 1, 't');
LCD_Write_Char(1, 1, 'i');
LCD_Write_Char(2, 1, 'm');
LCD_Write_Char(3, 1, 'e');
LCD_Write_Char(4, 1, ':');
LCD_Write_Char(5, 1, ' ');
LCD_Write_Char(6, 1, time[hour_s_alarm]);
LCD_Write_Char(7, 1, time[hour_g_alarm]);
LCD_Write_Char(8, 1, '-');
LCD_Write_Char(9, 1, time[min_s_alarm]);
LCD_Write_Char(10, 1, time[min_g_alarm]);
LCD_Write_Char(11, 1, '-');
LCD_Write_Char(12, 1, time[sec_s_alarm]);
LCD_Write_Char(13, 1, time[sec_g_alarm]);
LCD_Write_Char(14, 1, ' ');
LCD_Write_Char(15, 1, ' ');
}
void clock(void) {
while (1) {
DelayMs(5);
SPK = !SPK;
num++;
if (num >= 50) {
led = ~led;
num = 0;
}
Speed=2; //调整速度
Coil_A1 //遇到Coil_A1 用{A1=1;B1=0;C1=0;D1=0;}代替
DelayMs(Speed); //改变这个参数可以调整电机转速, 数字越小, 转速越大, 力矩越小
Coil_B1
DelayMs(Speed);
Coil_C1
DelayMs(Speed);
Coil_D1
DelayMs(Speed);
if (!en_SPK)
return;
}
}
//主函数
void main(void) {
LCD_Init();
month_s = month / 10;
month_g = month % 10;
day_s = day / 10;
day_g = day % 10;
LCD_Write_Char(2, 0, '2');
LCD_Write_Char(3, 0, '0');
LCD_Write_Char(4, 0, '1');
LCD_Write_Char(5, 0, '9');
LCD_Write_Char(6, 0, '-');
LCD_Write_Char(7, 0, time[month_s]);
LCD_Write_Char(8, 0, time[month_g]);
LCD_Write_Char(9, 0, '-');
LCD_Write_Char(10, 0, time[day_s]);
LCD_Write_Char(11, 0, time[day_g]);
LCD_Write_Char(0, 1, 't');
LCD_Write_Char(1, 1, 'i');
LCD_Write_Char(2, 1, 'm');
LCD_Write_Char(3, 1, 'e');
LCD_Write_Char(4, 1, ':');
LCD_Write_Char(5, 1, ' ');
LCD_Write_String(6, 1, "00-00-00");
interript_init();
while (1) {
if (flag == 1) {
display();
if (hour_alarm == hour && min_alarm == min && sec_alarm == sec) {
display();
hour_alarm = -1;
min_alarm = -1;
sec_alarm = -1;
clock();
}
}
}
}
//随时修改时间
void outer_ser(void) interrupt 0 {
flag = 1;
while (1) {
display();
if (keyh == 0) //实现小时加一
{
delay(5);
if (keyh == 0) {
if (hour != 23)
hour++;
else
hour = 0;
}
while (!keyh);
delay(5);
while (!keyh);
}
if (keym == 0){ //实现分钟加一
delay(5);
if (keym == 0){
if (min != 59){
min++;
}else{
min = 0;
}
}
while (!keym); //松手检测
delay(5);
while (!keym);
}
if (keys == 0){ //实现秒加一
delay(5);
if (keys == 0) {
if (sec != 59) {
sec++;
} else {
sec = 0;
}
}
while (!keys);
delay(5);
while (!keys);
}
if (keystop == 0){
break;
}
}
}
//计时器/定时器0,时钟运行
void count0() interrupt 1 {
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
count++;
if (count == 20){
count = 0;
sec++;
if (sec == 60){
sec = 0;
min++;
if (min == 60){
min = 0;
hour++;
if (hour == 24){
hour = 0;
day++;
if (day == mon[month - 1]){
day = 0;
month++;
}
}
}
}
}
}
//计时器/定时器1,设定闹钟
void outer_ser2(void) interrupt 2 {
flag2 = 1;
hour_alarm = hour;
min_alarm = min;
sec_alarm = sec;
while (1) {
display2();
if (keyh == 0){ //实现小时加一
delay(5);
if (keyh == 0){
if (hour_alarm != 23)
hour_alarm++;
else
hour_alarm = 0;
}
while (!keyh);
delay(5);
while (!keyh);
}
if (keym == 0){ //实现分钟加一
delay(5);
if (keym == 0){
if (min_alarm != 59){
min_alarm++;
}else{
min_alarm = 0;
}
}
while (!keym); //松手检测
delay(5);
while (!keym);
}
if (keys == 0){ //实现秒加一
delay(5);
if (keys == 0){
if (sec_alarm != 59){
sec_alarm++;
} else {
sec_alarm = 0;
}
}
while (!keys);
delay(5);
while (!keys);
}
if (keystop == 0) {
break;
}
}
}