×
单片机 > 单片机程序设计 > 详情

51单片机之IIC&EEPROM的驱动程序

发布时间:2020-07-08 发布时间:
|


#include

#include "./delay/delay.h"

sbit SCL = P2^0;

sbit SDA = P2^1;

bit ack = 0;

 

unsigned char flag = 1;

#define LCDPORT P0

#define LCD_WRITE_DATA 1

#define LCD_WRITE_COM 0

sbit RS = P2^4;

sbit RW = P2^5;

sbit E = P2^6;

 

#define SUCC 0

#define ERR 1

 

void iic_start()

{

SDA = 1;  //先操作SDA,在操作SCL

  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;   //与上为非0时,SDA = 1; 与上为0时,SDA = 0;

SCL = 1;

delay_us(1);         //延时1us

  SCL = 0;

  byte <<= 1;

}

SCL = 1;

SDA = 1;

delay_us(2);

if(0 == SDA)

{

ack = 1;

}

else

{

ack = 0;

}

SCL = 0;


return ack;

}

unsigned char iic_rcv_byte()       //接收数据

{

unsigned char i;

unsigned char temp = 0;

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 AT24c02_send_byte(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 ERR;

}

iic_send_byte(romaddr);         //写物理地址

if(0 == ack) //等待响应

{

return ERR;

}

for(i = 0; i < num; i++)       //发送num个字符

{

iic_send_byte(*s);       //逐个字节发送

if(0 == ack)

{

return ERR;

}

s++;

}

iic_stop();


return SUCC;

}

unsigned char AT24c02_rcv_byte(unsigned char devaddr, unsigned char romaddr, unsigned char *s, unsigned char num)

{

unsigned char i;

iic_start();

delay_us(10);

iic_send_byte(devaddr);             //写硬件地址

if(0 == ack)                        //等待响应

{

return ERR;

}

iic_send_byte(romaddr);         //写物理地址

if(0 == ack) //等待响应

{

return ERR;

}

iic_start();

iic_send_byte(devaddr + 1);

if(0 == ack) //等待响应

{

return ERR;

}

for(i = 0; i < num -1; i++)     //开始读数据

{

*s = iic_rcv_byte();

iic_ack();

s++;

}

*s = iic_rcv_byte();

iic_noack();

  delay_us(10);

iic_stop();

return SUCC;

}

void lcd1602_write(unsigned char byte, unsigned char flag)

{

if(flag)

{

RS = 1; 

}

else

{

RS = 0;     

}

RW = 0;     

E = 1;      

LCDPORT = byte;

delay_ms(5);

E = 0;   


}

void lcd_init()

{

delay_ms(15);

  lcd1602_write(0x38,LCD_WRITE_COM);

  delay_ms(5);

  lcd1602_write(0x38,LCD_WRITE_COM);

  delay_ms(5);

  lcd1602_write(0x38,LCD_WRITE_COM);

  delay_ms(5);

  lcd1602_write(0x38,LCD_WRITE_COM);

  delay_ms(5);

  lcd1602_write(0x08,LCD_WRITE_COM);

  delay_ms(5);

  lcd1602_write(0x01,LCD_WRITE_COM);

  delay_ms(5);

  lcd1602_write(0x06,LCD_WRITE_COM);

  delay_ms(5);

  lcd1602_write(0x0c,LCD_WRITE_COM);

  delay_ms(5);

}

void lcd_dis_char(unsigned char x, unsigned char y, unsigned char *str)

{

if((x > 15) || (y > 1))

{

return ;

 

}

if(0 == y)

{

lcd1602_write(0x80 + x, LCD_WRITE_COM);

}

else 

{

lcd1602_write(x + 0xc0,LCD_WRITE_COM);

}

while(*str != '')

{

  

lcd1602_write(*str , LCD_WRITE_DATA);

str++;

}

}

 

 

void main()

{

//unsigned char i;

unsigned char test[10] = {'0','1','2','3','4','5','6','7','8','9'};

unsigned char temp[11];

lcd_init();

AT24c02_send_byte(0xae,100,test,10);

delay_s(1);

AT24c02_rcv_byte(0xae,100,temp,10);

temp[10] = '';

lcd_dis_char(0,0,temp);

lcd_dis_char(0,1,temp);

 

while(1)

{



}

}



『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
C51 特殊功能寄存器SFR的名称和地址