51单片机——I2C总线驱动程序

发布者:Ziyu2022最新更新时间:2020-04-23 来源: eefocus关键字:51单片机  I2C总线  驱动程序 手机看文章 扫描二维码
随时随地手机看文章

为方便移植,采用多文件工程的方式。


void Delay10us()//延时10us

{

unsigned char a,b;

for(b=1;b>0;b--)

for(a=2;a>0;a--);

 

}

起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿


void I2cStart()//为方便与其他函数衔接,起始之后SDA和SCL都为0,虽然这与I2C总线空闲状态不符,但并不影响程序运行

{

SDA=1;

Delay10us();

SCL=1;

Delay10us();//建立时间是SDA保持时间>4.7us

SDA=0;

Delay10us();//保持时间是>4us

SCL=0;

Delay10us();

}

终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿


void I2cStop()//结束之后保持SDA和SCL都为1;表示总线空闲

{

SDA=0;

Delay10us();

SCL=1;

Delay10us();//建立时间大于4.7us

SDA=1;

Delay10us();

}

I2cSendByte(unsigned char dat) : 通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定


unsigned char I2cSendByte(unsigned char dat)//发送成功返回1,发送失败返回0

{

unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。

for(a=0;a<8;a++)//要发送8位,从最高位开始

{

SDA=dat>>7; //起始信号之后SCL=0,所以可以直接改变SDA信号

dat=dat<<1;

Delay10us();

SCL=1;

Delay10us();//建立时间>4.7us

SCL=0;

Delay10us();//时间大于4us

}

SDA=1;//¥¥¥

Delay10us();

SCL=1;

while(SDA)//等待应答,也就是等待从设备把SDA拉低

{

b++;

if(b>200) //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束

{

SCL=0;

Delay10us();

return 0;

}

}

SCL=0;

Delay10us();

  return 1;

}

I2cReadByte() :使用I2c读取一个字节


unsigned char I2cReadByte()

{

unsigned char a=0,dat=0;

SDA=1; //¥¥¥

Delay10us();

for(a=0;a<8;a++)//接收8个字节

{

SCL=1;

Delay10us();

dat<<=1;

dat|=SDA;

Delay10us();

SCL=0;

Delay10us();

}

return dat;

}

在以上两个函数中,在“¥¥¥”处,都将SDA置为1,这是将SDA线释放。原因如下:


I2C的数据和时钟线上都有一个上拉电阻,电阻的另一端接一个高电平。当I2C工作时,SDA上的电平取决于SDA上的数据。当I2C不工作时,因为集成电路的输入端为高阻状态,SDA上的电压就取决于电阻另一端的高电平了,因此I2C在释放总线后,SDA就等于1了。


对于I2C总线的解释:https://blog.csdn.net/cax1165/article/details/86755169


void At24c02Write(unsigned char addr,unsigned char dat) :往24c02的一个地址写入一个数据


void At24c02Write(unsigned char addr,unsigned char dat)

{

I2cStart();

I2cSendByte(0xa0);//发送写器件地址

I2cSendByte(addr);//发送要写入内存地址

I2cSendByte(dat); //发送数据

I2cStop();

}

unsigned char At24c02Read(unsigned char addr) :读取24c02的一个地址的一个数据


unsigned char At24c02Read(unsigned char addr)

{

unsigned char num;

I2cStart();

I2cSendByte(0xa0); //发送写器件地址

I2cSendByte(addr); //发送要读取的地址

I2cStart();

I2cSendByte(0xa1); //发送读器件地址

num=I2cReadByte(); //读取数据

I2cStop();

return num;

}

多文件工程 头文件


#ifndef __I2C_H_

#define __I2C_H_

 

#include

 

sbit SCL=P2^1;

sbit SDA=P2^0;

 

void I2cStart();

void I2cStop();

unsigned char I2cSendByte(unsigned char dat);

unsigned char I2cReadByte();

void At24c02Write(unsigned char addr,unsigned char dat);

unsigned char At24c02Read(unsigned char addr);

 

#endif

关键字:51单片机  I2C总线  驱动程序 引用地址:51单片机——I2C总线驱动程序

上一篇:51单片机实验18:蜂鸣器
下一篇:51单片机实验1:点亮第一盏led

推荐阅读最新更新时间:2024-11-13 04:48

一文详解MCS-51单片机的中断系统
MCS-51中断系统:5个中断源(两个外部中断, 两个定时器, 一个串口),2个优先级 中断相关概念 中断:当CPU正在处理某件事情时,单片机外部或内部发生的某一紧急事件请求CPU立即去处理,于是,CPU暂时中止当前的工作,转去处理这个紧急事件,待处理完毕后,再回到原来被中止的地方,继续原来的工作。 中断过程 中断发生:CPU在处理某一事件A时,发生了另一事件B请求CPU迅速去处理; 中断响应和中断服务:CPU暂时中断当前的工作,转去处理事件B(B的优先级要高于A); 中断返回:待CPU将事件B处理完毕后,再回到原来事件A被中断的地方继续处理事件A ; 中断源(中断请求源):能够向CPU发出中断申请的部件。 中断系统结
[单片机]
一文详解MCS-<font color='red'>51单片机</font>的中断系统
51单片机的延时子程序
延时程序在单片机编程中使用非常广泛,但一些读者在学习中不知道延时程序怎么编程,不知道机器周期和指令周期的区别,不知道延时程序指令的用法, ,本文就此问题从延时程序的基本概念、机器周期和指令周期的区别和联系、相关指令的用法等用图解法的形式详尽的回答读者 我们知道程序设计是单片机开发最重要的工作,而程序在执行过程中常常需要完成延时的功能。例如 在交通灯的控制程序中,需要控制红灯亮的时间持续30秒,就可以通过延时程序来完成。延时程序是如何实现的呢?下面让我们先来了解一些相关的概念。 一、机器周期和指令周期 1.机器周期是指单片机完成一个基本操作所花费的时间,一般使用微秒来计量单片机的运行速度,51 单片机的一个机器周期包
[单片机]
基于MCS-51单片机的流水灯功能设计与实现
今天,小编带大家一起来继续从基础做起,轻松玩转MCS-51单片机。这次主要实现的功能是:基于STC89C51单片机的流水灯功能设计与实现。如下图所示:下图为跑马灯电路(与单片机接口设置)。电路:1个LED光管点亮的电流值约为3~10mA,电阻值为1K。   电路通过编程后,可实现可以LED灯单个点亮或者实现流水灯功能、跑马灯功能等;(具体程序的话,可以自己是写一下)这里小编就写了一个实现流水灯的C源代码。大家也可以自己发散思维,让灯想怎么亮就怎么亮...有过自己动手的童鞋,肯定有过这样的感受:自己买的板板,用过一遍又一遍,但是每次都会变出点新花样出来,每次都是乐此不疲的写这代码,完全沉浸其中不可自拔....下图是具体功能实现时板
[单片机]
基于MCS-<font color='red'>51单片机</font>的流水灯功能设计与实现
51单片机c语言---延时
1,_nop_() 适用于us级的少量延时 标准的C语言中没有空语句。但在单片机的C语言编程中,经常需要用几个空指令产生短延时的效果。 这在汇编语言中很容易实现,写几个nop就行了。 在keil C51中,直接调用库函数: #include intrins.h // 声明了void _nop_(void); _nop_(); // 产生一条NOP指令 作用:对于延时很短的,要求在us级的,采用 _nop_ 函数,这个函数相当汇编NOP指令,延时几微秒。 NOP指令为单周期指令,可由晶振频率算出延时时间,对于12M晶振,延时1uS。 2,一般延时大于10us 一,定义的C51中循环变量,尽量采用无符号字符型变量。 二,
[单片机]
MSP430矩阵式按钮驱动程序
#include msp430x14x.h unsigned char LineScan ={0xef,0xdf,0xbf,0x7f}; //列值列举 void ADD() { P4OUT+=1; } void SUB() { P4OUT-=1; } unsigned int key_check(void) //检测是否有按键按下 { unsigned char temp; P1DIR=0xf0; //定义P1.4~P1.7为输出 temp=P1IN & 0x0f; if(temp!=0x0f) return 1; else return 0; } unsig
[单片机]
IMX257实现GPIO-IRQ中断按键驱动程序
昨天我们已经实现了中断查询的方式实现GPIO按键驱动程序,但是,有一个缺点就是,当我们把应用程序放在后台执行时,即便没有按键,应用程序while循环中的read函数也不断的在运行,严重的导致了CPU资源的浪费。 本文中,我们在前面按键查询驱动程序的基础上来修改。 大概介绍一下设计思路吧: 和前面的差不多,当我们加载驱动时,首先在init函数中,对GPIO功能进行模式设置,都设置为GPIO模式,然后申请GPIO引脚的内存, 接着,当我们应用程序使用ioctl函数的gpio_input命令时,将所有的GPIO引脚设置为输入,并且22K上拉模式,当应用程序使用read函数读取时,如果按键没有按下,则会在r
[单片机]
IMX257实现GPIO-IRQ中断按键<font color='red'>驱动程序</font>
VM7.1 下Ubuntu10.10 与 51单片机的串口通信实验
在VM7.1下给虚拟机增加一个串口(使用物理串口),注意此时在虚拟机中是串口1。 linux端程序(接收): #include stdio.h /*标准输入输出定义*/ #include stdlib.h /*标准函数库定义*/ #include unistd.h /*Unix 标准函数定义*/ #include sys/types.h #include sys/stat.h #include fcntl.h /*文件控制定义*/ #include termios.h /*PPSIX 终端控制定义*/ #include errno.h /*错误号定义*/ #d
[单片机]
51单片机学习之路(三)-按键
写在前面:以下涉及到的程序及电路图不保证为最优方案,会存在很多不足之处,望谅解。另外,C51的内容是在整理很久之前所学的知识,可能会存在错误,欢迎指正。 正文 学习目标:使用51单片机实现按键控制 。 学习内容: 用按键控制LED灯的亮灭 通过按键实现数码管数字加减 程序一:控制LED灯 功能要求:按下按键灯亮,再次按下灯灭。 源程序 #include reg52.h sbit led = P2^0; //定义LED端口 sbit key = P1^0; //定义按键端口 bit temp = 1; //让按键按下时只生效一次 int x = 0; //控制LED灯的亮灭 void delay(unsign
[单片机]
<font color='red'>51单片机</font>学习之路(三)-按键
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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