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

2019-08-15来源: eefocus关键字:51单片机  IIC  EEPROM  驱动程序


#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)

{

}

}


关键字:51单片机  IIC  EEPROM  驱动程序

编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic471219.html
本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:单片机ds18b20的介绍和源码
下一篇:51单片机串口通信的驱动程序

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

51单片机 小车 L298N pwm调速 串口控制 按键控制

难点:1、串口定时器T1,和T0定时器优先级            2、pwm频率与占空比的设置按键控制按键1——前进按键2——后退按键3——加速按键4——减速(板子上只有四个按键)串口控制‘1’——前进‘2’——后退‘3’——加速‘4’——减速‘5’——左转‘6’——右转源码:#include <reg52.h>typedef unsigned char u8;typedef unsigned int u16;//L298N引脚定义sbit ena = P0^0;sbit in1 = P0^1;sbit in2 = P0^2;sbit in3 = P0^3;s
发表于 2019-08-22

51单片机之定时器/计数器应用实例(方式0、1、2、3)

硬件:STC89C52RC开发工具:Keil uVision4     对于刚接触单片机的同学来说可能会对定时器/计数器的应用很蒙圈,特别是初值的计算和各种定时方式的选择。下面希望能给你带来一个清晰的思路。定时器:一般用于软件计时,给定时器设置一个时间,时间到了系统停止当前的工作跳转到事先定义好的定时器中断函数里,函数里可以做一些周期性的事情。计数器:一般用于检测外来脉冲信号,给计数器设置一个次数,次数到了系统停止当前的工作跳转到事先定义好的计数器中断函数里,函数里做相应的事情。先说一下相关的寄存器,也可以直接跳过,看后面的实例分析。配置定时器或者计数器就是对相应的寄存器进行赋值,下面是相关的寄存器
发表于 2019-08-20
51单片机之定时器/计数器应用实例(方式0、1、2、3)

51单片机之外部中断应用实例(电平触发、边沿触发)

硬件:STC89C52RC开发工具:Keil uVision4前言:8051是一款很经典的、历史悠久的单片机,作为一款入门级的单片机8051受到很多初学者的欢迎。89c52是8051系列的成员之一,拥有8K字节程序存储空间,512字节随机数据存储空间;I/O口控制端口、中断功能、定时器及串行接口。下面详细讲述外部中断功能的使用。外部中断:单片机提供的系统紧急事件的输入控制。事件触发的方式包括输入信号的下降沿触发、低电平触发。当触发中断后,单片机会跳到某一个固定的地址去执行中断服务程序。外部中断信号由INT0、INT1引脚传送进来,如图所示:有关中断处理的相关控制寄存器如下:计时计数器控制寄存器 TCON中断允许控制寄存器 IE
发表于 2019-08-20
51单片机之外部中断应用实例(电平触发、边沿触发)

51单片机之串口通讯应用实例(逻辑分析仪调试)

硬件:STC89C52RC开发工具:Keil uVision4前言:8051是一款很经典的、历史悠久的单片机,作为一款入门级的单片机8051受到很多初学者的欢迎。89c52是8051系列的成员之一,拥有8K字节程序存储空间,512字节随机数据存储空间;I/O口控制端口、中断功能、定时器及串行接口。下面详细讲述串行接口功能的使用。不管你用的芯片是不是STC89C52RC,只要你看完这篇文章,就能自行运用到不同的芯片上;因为一种串口通信协议的传输原理在任何芯片上都是统一的;所以它可以作为不同芯片一起协作的通信媒介。目前普遍的单片机都有串行通信的接口,因为它依赖的硬件比较简单,一条串行数据输出线(TX)、一条串行数据接收线(RX)、一条
发表于 2019-08-20
51单片机之串口通讯应用实例(逻辑分析仪调试)

STM32单片机连接HC_SR04超声波模块测距

图。         我们来分析一下这个时序图,先由触发信号启动HC-RS04测距模块,也就是说,主机要先发送至少为10us的高电平,触发HC-RS04,模块内部发出信号是传感器自动回应的,我们不用去管它。输出回响信号是我们需要关注的。信号输出的高电平就是超声波发出到重新返回接收所用的时间。用定时器,可以把这段时间记录下来,算出距离,别忘了结果要除于2,因为总时间是发送和接收的时间总和。下面是亲测可用的驱动程序。芯片型号为STM32F103ZET6,超声波测距后通过串口打印到电脑上面。驱动和测距;//超声波测距   
发表于 2019-08-19
STM32单片机连接HC_SR04超声波模块测距

矩阵键盘扫描原理详解——单片机

键盘扫描方法是:行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动。延时完成后再判断是否有低电平,如果此时读入列线数据还是有低电平,则说明确实有键按下。最后一步确定键值。现在我们以第二行的S5键为例,若按下S5后我们应该怎么得到这个键值呢?当判断确实有键按下之后,行线轮流输出低电平,根据读入列线的数据可以确定键值。首先,单片机将P10输出为低电平,其它P11~P13输出高电平,此时读取列线的数据全为高电平,说明没有在第一行有键按下;其次,单片机将P11输出低电平,其它P10
发表于 2019-08-16

小广播

何立民专栏

单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved