您的位置:首页 > 其它

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

2016-09-22 20:32 302 查看
#include <reg52.h>
#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 != '\0')
{

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] = '\0';
lcd_dis_char(0,0,temp);
lcd_dis_char(0,1,temp);

while(1)
{

}
}
delay()延时函数之前的程序中有.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  单片机