⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 基于51单片机
💻 C
字号:
/***************************************************************
*此程序是以51单片机为控制核心,通过IIC记录,以数码管显示的数字钟*
*数码管驱动芯片:595,两片  									*
*定时单元通过单片机内部定时器完成,定时存在一定误差 			*
*按键调整模块还未加上											*
*作者:王发修													*
*时间:2008年8月29日											*
*此程序与勤奋的人分享,愿大家共同进步							*
***************************************************************/
#include <AT89X52.H>
#include<intrins.h>
#include <absacc.h> 

unsigned char sec,minite=30,hour=12;        //定义计数值,每过1秒,sec加1 
unsigned int tcnt;        //定时中断次数
unsigned char extint0_count=0;
bit  write=0;             //写24C08的标志;

sbit MPX_DAT=P1^4;
sbit MPX_CLK=P1^5;
sbit MPX_OE =P1^6;

sbit IIC_SCL = P3^6;   // 24c08 IIC_SCL
sbit IIC_SDA = P3^5;  // 24c08 IIC_SDA

code unsigned char MPX[]={0x20,0x40,0x80,0x01,0x02,0x04,0x08,0x10};//位选信号
//                           1    2   3    4    5    6    7     8	 
code unsigned char Seg7Code[] =
{//定义数码管字型数据
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,  //0123456789
//    0x77,0x7C,0x39,0x5E,0x79,0x71,  //AbCdEF
    0x40,   //-
    0x00    //空白
};

unsigned char data buffer[8]={0,0,10,0,0,10,0,0};

void delay_ms(unsigned int n)
{
    unsigned char i;
    while(n--)
        for(i=0;i<125;i++);
}
void MPX_Clear()//清除显示
{  
    unsigned char i;
    for(i=25;i>0;i--)
    {
        MPX_CLK=0;
        _nop_();	
        MPX_CLK=1;
        _nop_();
        MPX_DAT=1;
        _nop_();
    }
    MPX_CLK=0;
}

void MPX_WriteData(unsigned char j)//向595写入8位数据
{   
    unsigned char c=8;
    while(c--)
    {
        MPX_DAT=j&0x80;
        MPX_CLK=0;
        j=j<<1;
        _nop_();	
        MPX_CLK=1; 
        _nop_();
    }
}

void MPX_Display(unsigned char mybit,unsigned char mydata)
{
    MPX_WriteData(~MPX[mybit]);
    if(mybit>3)
    {
        MPX_WriteData(0x00);
        MPX_WriteData(Seg7Code[mydata]);
    }
    else if(mybit<4)
    {
        MPX_WriteData(Seg7Code[mydata]);
        MPX_WriteData(0x00);
    }
    MPX_CLK=0;
    _nop_();	
    MPX_CLK=1;
    _nop_();
}


/////////24C08读写驱动程序////////////////////

void shortdelay(unsigned char x)
{  unsigned int i;
  for(i=0;i<x;i++);
}
void flash() 
{  ;  ; }

void IIC_Init()  //24c08初始化子程序
 {IIC_SCL = 1; flash(); IIC_SDA = 1; flash();}

void IIC_Start()        //启动I2C总线
{IIC_SDA = 1; flash(); IIC_SCL = 1; flash(); IIC_SDA = 0; flash(); IIC_SCL = 0; flash();}

void IIC_Stop()         //停止I2C总线
{IIC_SDA = 0; flash(); IIC_SCL = 1; flash(); IIC_SDA = 1; flash();}

void IIC_WriteByte(unsigned char dat)  //写一个字节
{  unsigned char i,uc_tmp;
   uc_tmp=dat;
   for (i=0;i<8;i++)
   {uc_tmp=uc_tmp<<1; IIC_SCL=0; flash(); IIC_SDA=CY; flash(); IIC_SCL=1; flash();}
   IIC_SCL=0; flash(); IIC_SDA=1; flash();
}
unsigned char IIC_ReadByte()   //读一个字节
{
    unsigned char i,j,uc_tmp=0;
    IIC_SCL=0;  flash();  IIC_SDA=1;
    for (i=0;i<8;i++)
    {  
        flash();  IIC_SCL=1;  flash();
        if (IIC_SDA==1) j=1;
        else j=0;
        uc_tmp=(uc_tmp<<1)|j; 
        IIC_SCL=0;
    }
    flash();
    return(uc_tmp);
}
void IIC_Clock()         // I2C总线时钟
{
   unsigned char i=0;
   IIC_SCL = 1;  flash();
   while ((IIC_SDA==1)&&(i<255))i++;
   IIC_SCL = 0; flash();
}
////////从24c02的地址address中读取一个字节数据/////
unsigned char X24C08_ReadByte(unsigned char address)
{
   unsigned char uc_tmp;
   IIC_Start(); IIC_WriteByte(0xa0);
   IIC_Clock(); IIC_WriteByte(address);
   IIC_Clock(); IIC_Start();
   IIC_WriteByte(0xa1); IIC_Clock();
   uc_tmp=IIC_ReadByte(); IIC_Stop();
   shortdelay(10);
   return(uc_tmp);
}
//////向24c02的address地址中写入一字节数据info/////
void X24C08_WriteByte(unsigned char address,unsigned char info)
{
   EA=0;
   IIC_Start(); IIC_WriteByte(0xa0);
   IIC_Clock(); IIC_WriteByte(address);
   IIC_Clock(); IIC_WriteByte(info);
   IIC_Clock(); IIC_Stop();
   EA=1;
   shortdelay(50);
}
/////////////24C08读写驱动程序完/////////////////////

/*****************以上是IIC的底层协议*******************/

void t0(void) interrupt 1 using 0  //定时中断服务函数
{ 
TH0=(65536-50000)/256; //对TH0 TL0赋值
TL0=(65536-50000)%256; //重装计数初值
tcnt++;        //每过250ust tcnt加一
if(tcnt==20)  //计满20次(1秒)时
   { 
    tcnt=0;   //重新再计
    sec++;
    write=1;  //1秒写一次24C08
    if(sec==60) //定时100秒,在从零开始计时
      {
	  	{
			sec=0;
			minite++;
			if(minite==60)
			{
				minite=0;
				hour++;
				if(hour==24)
					hour=0;
			}
		}
	  } 
   } 
}
void Timer0_Display()
{
    unsigned char i;
	buffer[0]=hour/10;buffer[1]=hour%10;
	buffer[3]=minite/10;buffer[4]=minite%10;
	buffer[6]=sec/10;buffer[7]=sec%10;
	for(i=0;i<8;i++)
	{
		MPX_OE =1;
   	 	MPX_Display(i,buffer[i]);
   	 	MPX_OE=0;
    	delay_ms(1);
	}
 /*   
 	MPX_OE =1;
    MPX_Display(0,sec/100);
    MPX_OE=0;
    delay_ms(5);
    MPX_OE =1;
    MPX_Display(1,sec/10%10);
    MPX_OE=0;
    delay_ms(5);
    MPX_OE =1;
    MPX_Display(2,sec%10);
    MPX_OE=0;
    delay_ms(5);
*/
}
void main(void) 
{ 
    TMOD=0x01;  //定时器工作在方式1
    ET0=1;  EA=1; 
    MPX_Clear();
    IIC_Init();        //初始化24C08
 /*
	X24C08_WriteByte(6,12);
	delay_ms(11);
	X24C08_WriteByte(4,30);
    delay_ms(11);
    X24C08_WriteByte(2,30);  //在24c08的地址2中写入数据sec
	delay_ms(11);
   */
    sec=X24C08_ReadByte(2);//读出保存的数据赋于sec
	minite=X24C08_ReadByte(4);
	hour=X24C08_ReadByte(6);
	delay_ms(500);
    TH0=(65536-50000)/256; //对TH0 TL0赋值
    TL0=(65536-50000)%256; //使定时器0.05秒中断一次
    TR0=1;           //开始计时
    while(1) 
    {
        Timer0_Display();
        if(write==1) //判断计时器是否计时一秒
        {
             write=0;              //清零 
			 X24C08_WriteByte(6,hour);
			 delay_ms(11);
			 X24C08_WriteByte(4,minite);
			 delay_ms(11);
             X24C08_WriteByte(2,sec);  //在24c08的地址2中写入数据sec
    	}
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -