51单片机普通IO口模拟IIC总线的程序实现

发布者:北极星小鹏最新更新时间:2016-05-31 来源: eefocus关键字:51单片机  普通IO口  模拟IIC总线 手机看文章 扫描二维码
随时随地手机看文章
IIC是由Philips公司发明的一种串行数据通信协议,仅使用两根信号线:SerialClock(简称SCL)和SerialData(简称SDA)。

IIC是总线结构,1个Master,1个或多个Slave,各Slave设备以7位地址区分,地址后面再跟1位读写位,表示读(=1)或者写(=0),所以我们有时也可看到8位形式的设备地址,此时每个设备有读、写两个地址,高7位地址其实是相同的。
IIC数据格式如下:
无数据:SCL=1,SDA=1;
开始位(Start):当SCL=1时,SDA由1向0跳变;
停止位(Stop):当SCL=1时,SDA由0向1跳变;
数据位:当SCL由0向1跳变时,由发送方控制SDA,此时SDA为有效数据,不可随意改变SDA;
当SCL保持为0时,SDA上的数据可随意改变;
地址位:定义同数据位,但只由Master发给Slave;
应答位(ACK):当发送方传送完8位时,发送方释放SDA,由接收方控制SDA,且SDA=0;
否应答位(NACK):当发送方传送完8位时,发送方释放SDA,由接收方控制SDA,且SDA=1。
当数据为单字节传送时,格式为:
开始位,8位地址位(含1位读写位),应答,8位数据,应答,停止位。
当数据为一串字节传送时,格式为:
开始位,8位地址位(含1位读写位),应答,8位数据,应答,8位数据,应答,……,8位数据,应答,停止位。
需要注意的是:
1、SCL一直由Master控制,SDA依照数据传送的方向,读数据时由Slave控制SDA,写数据时由Master控制SDA。当8位数据传送完毕之后,应答位或者否应答位的SDA控制权与数据位传送时相反。
2、开始位“Start”和停止位“Stop”,只能由Master来发出。
3、地址的8位传送完毕后,成功配置地址的Slave设备必须发送“ACK”。否则否则一定时间之后Master视为超时,将放弃数据传送,发送“Stop”。
4、当写数据的时候,Master每发送完8个数据位,Slave设备如果还有空间接受下一个字节应该回答“ACK”,Slave设备如果没有空间接受更多的字节应该回答“NACK”,Master当收到“NACK”或者一定时间之后没收到任何数据将视为超时,此时Master放弃数据传送,发送“Stop”。
5、当读数据的时候,Slave设备每发送完8个数据位,如果Master希望继续读下一个字节,Master应该回答“ACK”以提示Slave准备下一个数据,如果Master不希望读取更多字节,Master应该回答“NACK”以提示Slave设备准备接收Stop信号。
6、当Master速度过快Slave端来不及处理时,Slave设备可以拉低SCL不放(SCL=0将发生“线与”)以阻止Master发送更多的数据。此时Master将视情况减慢或结束数据传送。

下面是本人编写的单片机普通IO口模拟IIC总线的程序源代码:

/*

Fuction:GPIO模拟iic bus,实现与AT24C02的数据通信
PS:该源代码是以STC89C52为平台编写的,可通过修改包含的头文件以适用于所有51系列单片机
SD:Jason

*/
#include 
#include 
sbit sda = P2^0;
sbit scl = P2^1;
unsigned char table1[11]={0,1,2,3,4,5,6,7,8,9};
unsigned char table2[11];
void init();
void somenop();
void delay(unsigned char);
void start();
void stop();
void send_ack(unsigned char);
unsigned char rec_ack();
void write_byte(unsigned char);
unsigned char read_byte();
unsigned char write_add(unsigned char,unsigned char *,unsigned char);
unsigned char read_add(unsigned char,unsigned char *,unsigned char);

void main()
{
	init();
	write_add(0x10,table1,10);
	delay(100);
	read_add(0x10,table2,10);
	while(1);
}
//端口初始化
void init()
{
	memset(table2,0,sizeof(table2));
	sda = 1;
	scl = 1;
	somenop();
}
//起始信号
void start()
{
	sda = 1;
	somenop();
	scl = 1;
	somenop();
	sda = 0;
	somenop();
}
//终止信号
void stop()
{
	sda = 0;
	somenop();
	scl = 1;
	somenop();
	sda = 1;
	somenop();
}
//主机发送应答信号
void send_ack(unsigned char ack)
{
	scl = 0;
	somenop();
	sda = ack;
	somenop();
	scl = 1;
	somenop();
	scl = 0;
	somenop();
	sda = 1;
	somenop();
}
//主机接收应答信号
unsigned char rec_ack()
{
	scl = 1;
	somenop();
	if(sda == 1)
	{
		scl = 0;
		delay(1);
		scl = 1;
		if(sda == 1)
			return 1;
	}
	else
		return 0;
}
//写一个字节
void write_byte(unsigned char dat)
{
	unsigned char i,a;
	a = dat;
	for(i=0;i<8;i++)
	{
		a = a<<1;
		scl = 0;
		somenop();
		sda = CY;
		somenop();
		scl = 1;
		somenop();
	}
	scl = 0;
	somenop();
	sda = 1;
	somenop();
}
//读一个字节
unsigned char read_byte()
{
	unsigned char i,a;
	scl = 0;
	somenop();
	sda = 1;
	somenop();
	for(i=0;i<8;i++)
	{
		scl = 1;
		somenop();
		a = (a<<1)|sda;
		scl = 0;
		somenop();
	}
	return a;
}
//向add地址写入len长度的dat数据
unsigned char write_add(unsigned char add,unsigned char *dat,unsigned char len)
{
	unsigned char flag,i;
	start();
	write_byte(0xa0);
	if(rec_ack() == 0)
	{
		write_byte(add);
		if(rec_ack() == 0)
		{
			for(i=0;i0;y--)
		for(z=110;z>0;z--);
}
 
关键字:51单片机  普通IO口  模拟IIC总线 引用地址:51单片机普通IO口模拟IIC总线的程序实现

上一篇:51单片机GPIO口模拟串口通信
下一篇:51单片机的IO口驱动能力、灌电流、拉电流、上拉电阻的选择

推荐阅读最新更新时间:2024-03-16 14:55

51单片机简易计算器程序 实现数字的加减乘除运算
单片机源程序如下: #include reg51.h //头文件 #define uint unsigned int #define uchar unsigned char sbit lcden=P1^1; //LCD1602控制引脚 sbit rs=P1^0; sbit rw=P1^2; sbit busy=P0^7;//LCD忙 char i,j,temp,num,num_1; long a,b,c; //a,第一个数 b,第二个数 c,得数 float a_c,b_c; uchar flag,fuhao;//flag表示是否有运算符键按下,fuhao表征按下的是哪个运算符 //flag=1表示运算符键按
[单片机]
<font color='red'>51单片机</font>简易计算器程序 实现数字的加减乘除运算
51单片机运行过程
注: 1.ROM:只读存储器,单片机的只读存储区大多用于存储程序固又称程序存储器。 51单片机是EPROM,所谓的EPROM是可擦除的只读存储器。可以把原来的程序擦除了,再写一个新的进去。 断电后是可以保存的,数据存储器(RAM)是不能保存的。 RAM只能在程序执行的时候不断地重新存储定义的变量。如int x,int y 可以通过code这个指令来将定义的变量放在ROM,而不是RAM中,节省RAM资源 2.RAM:随机存取存储器,用于存储定义的变量等,速度快 51单片机的RAM存储容量远小于ROM,但是速度非常之快 内部详细图示 内部的结构看似十分复杂,但是大致上可以分为两个部分:运算器(红色框)和控制器(蓝色
[单片机]
<font color='red'>51单片机</font>运行过程
51单片机学习——8.2--定时计数器
定时计数器原理 CPU时序 振荡周期:为单片机提供定时信号的振荡源的周期(晶振周期或外加振荡周期) 状态周期:2个振荡周期为1个状态周期,用S表示。振荡周期又称S周期或时钟周期。 机器周期:1个机器周期含6个状态周期,12个振荡周期。 指令周期:完成1条指令所占用的全部时间,它以机器周期为单位。 例如:外接晶振为12MHz时,51单片机相关周期的具体值为: 振荡周期=1/12us; 状态周期=1/6us; 机器周期=1us; 指令周期=1~4us; 定时计数器介绍 基本特点 51单片机有两组定时器/计数器,因为既可以定时, 又可以计数,故称之为定时器/计数器。 定时器/计数器和单片机的CPU是相互独立的。定时器/
[单片机]
<font color='red'>51单片机</font>学习——8.2--定时计数器
基于51单片机的贪吃蛇小程序(8*8LED点阵实现)
一直很想写一个贪吃蛇的小程序,这两天终于抽空完成了,这里把我的思路分享给大家,仅供参考! 代码如下: 先放段主函数压压惊 void main() { x_s = 2; //初始化三个点 y_s = 3; x_s = 3; y_s = 3; x_s = 4; y_s = 3; Timer0Init(); suijishu(); while(1) { appear(); if(flag_a) //蛇身移动位 { if(!flag_s) //蛇身死亡位 { auto_move(); HC_595(0x00); //消隐 P0 = 0xFF; //消隐
[单片机]
MCS-51单片机中软时钟设计的优化方法
0 引言 随着微电脑应用的普及,以MCS-51单片机为核心的微机测控系统已随处可见。为满足用户要求,这些系统通常都具有数码显示时钟的功能。由于MCS-51内部包含2个定时计数器,通过采用将其中一个定时计数器用于软时钟设计的方法,可以大大节省硬件开销。本文提出了如何提高软时钟的定时精度,以及在软时钟存在的情况下,如何提高以MCS-51单片机为核心的测控系统的设计质量的方法。 1 MCS-51单片机内部定时计数器概述 MCS-51单片机内部包含2个定时计数器T0和T1,它们都是16位的加法计数器,既可用于定时,也可用于计数,在用于定时的情况下,计数脉冲由内部提供,因此计数速率固定为CPU振荡频率的1/12;在用于计数的情
[单片机]
基于AT89S51单片机的冲床控制器设计
系统硬件配置以AT89S51单片机为核心。AT89S51是一个低功耗,高性能CMOS 8位单片机,片内含4Kb ISP(In-system programmable)可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,内置看门狗(WDT)电路。 功能强大的AT89S51可为许多嵌入式控制应用系统提供高性价比的解决方案。采用该单片机设计的冲床控制器,具有以下几个特点: 图1 控制器的硬件结构框图 ● 控制器采用PLC设计的理念,可靠性高,抗干扰能力强。 ● 面板上6位七段 LED 显示,既可以用来调节参数,工
[单片机]
基于AT89S<font color='red'>51单片机</font>的冲床控制器设计
基于51单片机的多普勒血流计系统的设计方案
激光多普勒血流计是微循环研究中用于测定组织、微区血流灌注流量、微循环状态的仪器。利用多普勒移动分量来测定血细胞流量,是一种非损伤、快速、连续、直 接测量组织微区灌流量的新方法,对医学研究有重要意义。本文主要介绍了利用多普勒现象设计的激光多普勒血流计,论述了用51单片机实现的新方法和新措施。 多普勒血流计的出现标志着在微血管灌流方面取得重大进步。本设计采取双通道装置拾取多普勒信号,有效地抑制噪声信号,采用单片机来对信号进行控制及处理,既简化了电路,又有助于信号的处理及读取。运用12位的AD574A不但提高了信号精度,利用其双极性,也省去了以往信号处理中复杂的乘方、开方电路或绝对值电路。通过四位LED显示,直观、准确地读取血细胞灌流量的
[单片机]
基于<font color='red'>51单片机</font>的多普勒血流计系统的设计方案
一文详解80C51单片机的指令集
数据传送类指令 数据传送是单片机最基本的操作。数据传送的一般功能是将源操作数传送到指令所指定的目的操作数,指令执行后,源操作数不变。 数据传送类指令一般不影响标志位。数据传送类指令共29条,可以分为两大类。一是采用MOV操作符,称为一般传送指令,共16条;二是采用非MOV操作符,称为特殊传送指令,共13条。 一般传送指令的 汇编 指令格式为: MOV是传送指令的操作助记符。其功能是将源操作数传送到目的操作数,源操作数内容不变。 该类指令的助记符,操作数,功能,字节数及执行时长(机器周期数),按目的操组数归类如下。 1)内部8位数据传送指令 内部 RAM 区是数据传送最活跃的区域,8位内部数据传送指令共15条,用于 单片机
[单片机]
一文详解80C<font color='red'>51单片机</font>的指令集
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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