IIC总线
核心思想:主机与从机之间的信息交换。
主机发送消息,从机要回应一下。
从机发送消息,主机也要回应。
注意点:SDA线和SCL线都是默认高电平。即高电平为释放状态。
- IIC总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
- 传送的四种状态
代码如下:
作用: - K1写入
- K2读入
- K3加一
- K4清零
- 补:数码管是从左往右开始亮的。
#include <REGX52.H>
#include <i2c.h>
typedef unsigned char u8;
typedef unsigned int u16;
void delay10ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
void delay1ms(void) //误差 0us
{
unsigned char a,b,c;
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3; //定义按键端口
u8 sj=0;
u8 disp[8];
u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值
void keyjud()
{
if(k1==0)
{
delay10ms();
if(k1==0)
{
write(sj,1);
}
while(!k1);
}
if(k2==0)
{
delay10ms();
if(k2==0)
{
sj=read(1);
}
while(!k2);
}
if(k3==0)
{
delay10ms();
if(k3==0)
{
sj++;
if(sj==100)
sj=0;
}
while(!k3);
}
if(k4==0)
{
delay10ms();
if(k4==0)
{
sj=0;
}
while(!k4);
}
}
void sjpros()
{
u8 i,fake_sj=sj;
for(i=0;i<8;i++)
{
disp[i]=fake_sj%10;
fake_sj/=10;
}
}
void DigDisplay()
{
u8 i;
for(i=0;i<8;i++)
{
switch(i) //位选,选择点亮的数码管,
{
case(0):
LSA=0;LSB=0;LSC=0; break;//显示第0位
case(1):
LSA=1;LSB=0;LSC=0; break;//显示第1位
case(2):
LSA=0;LSB=1;LSC=0; break;//显示第2位
case(3):
LSA=1;LSB=1;LSC=0; break;//显示第3位
case(4):
LSA=0;LSB=0;LSC=1; break;//显示第4位
case(5):
LSA=1;LSB=0;LSC=1; break;//显示第5位
case(6):
LSA=0;LSB=1;LSC=1; break;//显示第6位
case(7):
LSA=1;LSB=1;LSC=1; break;//显示第7位
}
P0=smgduan[disp[7-i]];//发送段码
delay1ms(); //间隔一段时间扫描
P0=0x00;//消隐
}
}
void main()
{
while(1)
{
keyjud();
sjpros();
DigDisplay();
}
}```
#include <i2c.h>
void delay10us(void) //误差 0us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
void IICstart()
{
SDA=1;
delay10us();
SCL=1;
delay10us();
SDA=0;
delay10us();
SCL=0; //???
delay10us();
}
void IICstop()
{
SDA=0;
delay10us();
SCL=1;
delay10us();
SDA=1;
delay10us();
}
unsigned char IICSEND_BYTE(unsigned char date)
{
unsigned char a,b=0;
for(a=0;a<8;a++)
{
SDA=date>>7;
date<<=1;
delay10us();
SCL=1;
delay10us();
SCL=0;
delay10us();
}
SDA=1;
delay10us();
SCL=1;
delay10us();
while(SDA)
{
b++;
if(b>200)
{
// SDA=0;
// delay10us();
SCL=0;
delay10us();
return 0;
}
}
SCL=0;
delay10us();
return 1;
}
unsigned char IICREAD_BYTE()
{
unsigned char date=0,a;
SDA=1; //?
delay10us();
for(a=0;a<8;a++)
{
SCL=1;
delay10us();
date<<=1;
date|=SDA;
SCL=0;
delay10us();
}
return date;
}
void write(unsigned char date,unsigned char addr)
{
IICstart();
IICSEND_BYTE(0xa0);
IICSEND_BYTE(addr);
IICSEND_BYTE(date);
IICstop();
}
unsigned char read(unsigned char addr)
{
unsigned char num;
IICstart();
IICSEND_BYTE(0xa0);
IICSEND_BYTE(addr);
IICstart();
IICSEND_BYTE(0xa1);
num=IICREAD_BYTE();
IICstop();
return num;
}
#ifndef __i2c_h__
#define __i2c_h__
#include <REGX52.H>
sbit SCL=P2^1;
sbit SDA=P2^0;
void IICstart();
void IICstop();
unsigned char IICSEND_BYTE(unsigned char date);
unsigned char IICREAD_BYTE();
void write(unsigned char date,unsigned char addr);
unsigned char read(unsigned char addr);
#endif