单片机——EEPROM

该程序使用单片机通过IIC总线与EEPROM交互,实现掉电后仍能保存时钟数据的功能。程序初始化LCD并显示从EEPROM读取的时间,同时具备按键重置时间的选项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

该程序的功能是使用EEPROM实现掉电时钟的功能,EEPROM是使用iic总线来驱动的
#include <reg52.h>
#include "./delay/delay.h"
#define ERROR 1
#define SUCCESS 0
sbit SCL = P2^0;
sbit SDA = P2^1;
bit ack = 0;
sbit RS = P2^4;
sbit RW = P2^5;
sbit E = P2^6;
sbit key1 = P2^2;
#define LCDPORT  P0
#define LCD_WRITE_DATA 1
#define LCD_WRITE_COM 0
unsigned char clock[10] = {0x30,0x30,':',0x30,0x30,':',0x30,0x30,'\0'};
unsigned char result[10];
unsigned char shi = 0;
unsigned char fen = 0;
unsigned char miao = 0;
unsigned char ms = 0;
void lcd_write(unsigned char byte, unsigned char flag)
{
   if(flag)
  {
     RS = LCD_WRITE_DATA;
  }
  else
  {
     RS = LCD_WRITE_COM;
  }
  RW = 0;
  E = 1;
  LCDPORT = byte;
  delay_us(7);
  E = 0;
}
void lcd_init()
{
   delay_ms(5);
   lcd_write(0x38,LCD_WRITE_COM);
   delay_ms(5);
   lcd_write(0x38,LCD_WRITE_COM);
   delay_ms(5);
   lcd_write(0x38,LCD_WRITE_COM);
   delay_ms(5);
   lcd_write(0x08,LCD_WRITE_COM);
   delay_ms(5);
   lcd_write(0x01,LCD_WRITE_COM);
   delay_ms(5);
   lcd_write(0x06,LCD_WRITE_COM);
   delay_ms(5);
   lcd_write(0x0C,LCD_WRITE_COM);
}
void lcd_display(unsigned char x,unsigned char y,unsigned byte)
{
   if(y == 0)
  {
       lcd_write(0x80 + (unsigned int)x*0x01,LCD_WRITE_COM);
       lcd_write(byte,LCD_WRITE_DATA);
  }
  else
  {
     lcd_write(0x80 + 0x40 + (unsigned int)x*0x01,LCD_WRITE_COM);
       lcd_write(byte,LCD_WRITE_DATA);
  }
}
void lcd_str_display(unsigned char x,unsigned char y,unsigned char *s)
{
   while(*s != '\0')
  {
     lcd_display(x++,y,*s);
     s++;
  }
}
// void lcd_dis_time()
// {
//    lcd_write(0x80 + 4,LCD_WRITE_COM);
//    lcd_write((shi / 10) + 0x30,LCD_WRITE_DATA);
//    lcd_write((shi % 10) + 0x30,LCD_WRITE_DATA);
//    lcd_write(':',LCD_WRITE_DATA);
//    lcd_write((fen / 10) + 0x30,LCD_WRITE_DATA);
//    lcd_write((fen % 10) + 0x30,LCD_WRITE_DATA);
//    lcd_write(':',LCD_WRITE_DATA);
//    lcd_write((miao / 10) + 0x30,LCD_WRITE_DATA);
//    lcd_write((miao % 10) + 0x30,LCD_WRITE_DATA);
// }
void iic_start()
{
   SDA = 1;
   SCL = 1;
    delay_us(1);
   SDA = 0;
   delay_us(1);
   SCL = 0;
}
void iic_stop()
{
   SDA = 0;
   SCL = 1;
   delay_us(1);
   SDA = 1;
   delay_us(1);
   SCL = 0;
}
bit iic_send_byte(unsigned char byte)
{
   unsigned char i;
   for(i = 0; i < 8; i++)
   {
     SDA = byte & 0x80;
     SCL = 1;
     delay_us(1);
     SCL = 0;
     byte <<= 1;
  }
  SCL = 1;
  SDA = 1;
  delay_us(1);
  if(0 == SDA)
  {
     ack = 1;
  }
  else
  {
     ack = 0;
  }
  SCL = 0;
  
  return ack;
}
unsigned char iic_recv_byte()
{
   unsigned char temp = 0;
   unsigned char i;
   unsigned char a;
  
    SDA = 1;
 
   for(i = 0; i < 8; i++)
   {
     SCL = 0;
     delay_us(1);
     SCL = 1;
     if(SDA)
    {
       a = 0x01;
    }
    else
    {
       a = 0;
    }
     temp |= (a << (7 - i));
    delay_us(1);
  }
  
  SCL = 0;
  return temp;
}
void iic_ack()
{
   SDA = 0;
   SCL = 1;
   delay_us(1);
   SCL = 0;
}
void iic_noack()
{
   SDA = 1;
   SCL = 1;
   delay_us(1);
   SCL = 0;
}
unsigned char iic_AT2402_send_str(unsigned char devaddr, unsigned char romaddr, unsigned char *s, unsigned char num)
{
   unsigned char i;
   iic_start();
   iic_send_byte(devaddr);
   if(0 == ack)
  {
     return ERROR;
  }
   iic_send_byte(romaddr);
  if(0 == ack)
  {
     return ERROR;
  }
  
  for(i = 0; i < num; i++)
  {
       iic_send_byte(*s);
     if(0 == ack)
      {
         return ERROR;
      }
    s++;
  }
  
   iic_stop();
  return SUCCESS;
}
unsigned char iic_AT2402_recv_str(unsigned char devaddr, unsigned char romaddr, unsigned char *s, unsigned char num)
{
   unsigned char i;
   iic_start();
   iic_send_byte(devaddr);
   if(0 == ack)
  {
     return ERROR;
  }
   iic_send_byte(romaddr);
  if(0 == ack)
  {
     return ERROR;
  }
  
  iic_start();
  iic_send_byte(devaddr + 1);
  
  for(i = 0; i < num-1; i++)
  {
       *s = iic_recv_byte();
     iic_ack();
    
    s++;
    
//     delay_s(1);
  }
  *s = iic_recv_byte();
   iic_noack();
   iic_stop();
  return SUCCESS;
}
void timer0_init()
{
   EA = 1;
   TMOD |= 0x01;
   TH0 = (65536 - 20000) / 256;
   TL0 = (65536 - 20000) % 256;
   ET0 = 1;
   TR0 = 1;
}

void timer0_isr() interrupt 1
{
   //static unsigned char i = 0;
 
   TH0 = (65536 - 20000) / 256;
   TL0 = (65536 - 20000) % 256;
   ms++;
   if(50 == ms)
  {
     ms = 0;
     miao++;
     if(60 == miao || miao > 60)
    {
       miao = 0;
       fen++;
       if(60 == fen || fen > 60)
      {
         fen = 0;
         shi++;
         if(24 == shi || shi > 24)
        {
           shi = 0;
        }
      }
    }
    }
  
  clock[0] = (shi/10) + 0x30;
  clock[1] = (shi%10) + 0x30;
  clock[3] = (fen/10) + 0x30;
  clock[4] = (fen%10) + 0x30;
  clock[6] = (miao/10) + 0x30;
  clock[7] = (miao%10) + 0x30;
//   clock[8] = '\0';
}
// void timer1_init()
// {
//    EA = 1;
//    TH1 = (65536 - 1000)/256;
//    TL1 = (65536 - 1000)%256;
//    TMOD |= 0x10;
//    ET1 = 1;
//    TR1 = 1;
// }
// void timer1_isr() interrupt 3
// {
//  
//    TH1 = (65536 - 1000)/256;
//    TL1 = (65536 - 1000)%256;
//  
//    lcd_str_display(4,0,result);
// }
 
void main()
{
//     unsigned char i;
   timer0_init();
//    timer1_init();
    lcd_init();
    iic_AT2402_recv_str(0xae,100,result,8);
  
   shi = (result[0]-0x30)*10 + (result[1]-0x30);
    fen = (result[3]-0x30)*10 + (result[4]-0x30);
    miao = (result[6]-0x30)*10 + (result[7]-0x30); 
//     delay_ms(20);
  
   while(1)
  {
     iic_AT2402_send_str(0xae,100,clock,9);
   
     delay_ms(200);
   
      iic_AT2402_recv_str(0xae,100,result,9);
    result[8] = '\0';
     lcd_str_display(4,0,result);
     delay_ms(20);
   
     if(key1 == 0)
    {
       delay_ms(10);
       if(0 == key1)
      {
         while(!key1);
         delay_ms(10);
         while(!key1);
        
         shi = 0;
         fen = 0;
         miao = 0;
      }
        }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值