欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

蓝桥杯CT107D之AT24C02(EEPROM)

程序员文章站 2022-04-01 09:57:31
...

IIC驱动程序

#include "reg52.h"
#include "intrins.h"
#include "iic.h"





//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
		IIC_Delay(DELAY_TIME);
		da <<= 1;
		if(SDA) da |= 1;
		SCL = 0;
		IIC_Delay(DELAY_TIME);
    }
    return da;    
}

AT24C02驱动程序

//向AT24C02指定地址写入单字节数据
void Write_EEPROM(unsigned char address,unsigned char Data)
{
	IIC_Start();
	IIC_SendByte(AT24C02_AddrW);
	if(!IIC_WaitAck())
	IIC_SendByte(address);
	if(!IIC_WaitAck())
	IIC_SendByte(Data);
	if(!IIC_WaitAck());
	IIC_Stop();	
}

//读取AT24C02指定地址的单字节数据
unsigned char Read_EEPROM(unsigned char address)
{
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(AT24C02_AddrW);
	if(!IIC_WaitAck())
	IIC_SendByte(address);
	if(!IIC_WaitAck())
	IIC_Start();
	IIC_SendByte(AT24C02_AddrR);
	if(!IIC_WaitAck())
	temp = 	IIC_RecByte();
	if(!IIC_WaitAck())
	IIC_Stop();
	return temp;
}

数码管用拆数函数

#include "reg52.h"
#include "smg.h"

unsigned char c[N];
unsigned char SMG_chai(unsigned int t)
{
	unsigned char i=0;
 	if(t<10)
	c[i]=t;
	else
	{
		while(1)
	    {
		  	c[i]=t%10;
		    t=t/10;
		    i++;
		    if(t<10)
		    break; 
	    }
	    c[i]=t;
	}
	return i;	
}

主函数

#include "reg52.h"
#include "iic.h"
#include "smg.h"

#define FOSC 11059200L
#define T1MS (65536-FOSC/1000)      //1T模式

sfr AUXR = 0x8e;
sfr P4   = 0xC0;					//定义P4口

sbit LED_1 = P0^0;
sbit N_RELAY = P0^4;
sbit N_BUZZ = P0^6;

unsigned char code Duan[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共阴极段选0~9
unsigned char code Wei[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //共阴极位选 1--8
unsigned char temp=0,s=0,i1=0;

void T0Init();

void main()
{
	P2 = 0xa0; N_BUZZ=0; N_RELAY=0; P2 = 0x00;
	P2 = 0x80; P0=0xff;  P2 = 0x00;	//关灯	
	temp = Read_EEPROM(0x00);
	Write_EEPROM(0x00,++temp); 
	T0Init();
	while(1)
	{
		i1 = SMG_chai(temp);
	}
}

void T0Init()
{
	AUXR |= 0x80;                   //定时器0为1T模式
//  AUXR &= 0x7f;                   //定时器0为12T模式

    TMOD = 0x00;                    //设置定时器为模式0(16位自动重装载)
    TL0 = T1MS;                     //初始化计时值
    TH0 = T1MS >> 8;
    TR0 = 1;                        //定时器0开始计时
    ET0 = 1;                        //使能定时器0中断
    EA = 1;
}

/* Timer0 interrupt routine */
void tm0_isr() interrupt 1 
{
	static int count = 5;

	P0=0xff;    									//关闭下段选,达到消隐的目的。
	P2 = 0xe0;	P0=~Duan[c[s]];  P2 = 0x00; 
	P0=0x00;							    		//进入位选前先把P0清零,禁止选通数码管。	  
	P2 = 0xc0;	P0=~Wei[7-s];	 P2 = 0x00;
	P0=0xff;
	
	if(s<i1)
	{
		s++;
	}
	else
	s=0;	

	if(count-- == 0)
	{
		count = 5;		
	}		
}
相关标签: CT107D