C51单片机_LCD电子时钟

C51单片机_LCD电子时钟

可以手动设置初始时间和修改时间,可以设置闹钟时间,响应时蜂鸣器会响,步进电机会转动

#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;
    }
  }
}

你可能感兴趣的:(C51单片机)