📄 key_s_i2c.c
字号:
//本例子用于测试组合按键、虚拟I2C协议与串口通信的综合应用
//操作说明:按下任意键,键值写入AT24C01,同时通过串口发送出去,延时一定时间后,从AT24C01读出,如果为9以内的数字,在数码管上显示 ,ok
#include <REG51.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define AddWr 0xA0 //器件地址选择及写标志
#define AddRd 0xA1 //器件地址选择及读标志
void WrToRom(uchar device,uchar Addr,uchar datevalue); //写入24C01函数
void ReFromRom(uchar device, uchar Addr); //读取24C01函数
uchar rd_24c01(char addr);
void wr_24c01(char a,char b);
uchar ReadByte(); //读取字节函数
void SendByte(uchar Data); //字节数据传送函数
// void I2C_wait(); //锁定时间函数
void Start(); //启动总线函数
void Stop(); //结束总线函数
void ack(); //应答函数
void C_send(uchar number); //串口发送函数
char scan_key(void);
// void voice(void); //蜂鸣器鸣叫函数
uchar code SEG7[17]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x40,0x5e,0x09,0x71,0};
uchar code ACT[4]={0xfe,0xfd,0xfb,0xf7};
uchar code SKEY[16]={7,8,9,10,4,5,6,11,1,2,3,12,15,0,14,13};
/***********************************************************/
sbit Sda=P3^7 ; //数据总线
sbit Scl=P3^6 ; //时钟总线
sbit BUZZER=P3^2; //接蜂鸣器
uchar distemp;
uchar cnt;
bit outflag;
/****************************************/
void delay(uint k)
{
uint x,y;
for(x=0;x<k;x++)
for(y=0;y<120;y++){;}
}
/****************************************/
void voice(void)
{
BUZZER=0;
delay(200);
BUZZER=1;
}
/*********************************************/
void test(void)
{
P2=ACT[0];
P0=SEG7[1];
WrToRom(AddWr,8,5);
BUZZER=0;
delay(500);
BUZZER=1;
ReFromRom(AddRd,8);
if(distemp<10 && distemp>=0)
P0=SEG7[distemp];
}
//***********************
void ack()
{
Scl=1;_nop_();_nop_();_nop_();_nop_();
Scl=0;_nop_();_nop_();_nop_();_nop_();
}
/*******************************************************************
发送串口数据,与B单片机进行握手
********************************************************************/
void C_send(uchar number) //串口发送程序
{
SBUF=number;
while(TI==0);
TI=0;
}
/**************************************/
void init(void)
{
TMOD=0x21;
TH0=-(10000/256);
TL0=-(10000%256);
TH1=0xfd;
TL1=0xfd;
SCON=0x50;
TR0=1;
TR1=1;
ET0=0;
EA=1;
}
/****************************************/
void main(void)
{
init();
test();
ET0=1;
while(1)
{
if(outflag==1)
{
outflag=0;
EA=0;
WrToRom(AddWr,8,cnt);
BUZZER=0;
delay(500);
ReFromRom(AddRd,8);
delay(2);
if(distemp<10 && distemp>=0)
P0=SEG7[distemp];
EA=1;
}
}
}
/******************************************/
void int_t0(void) interrupt 1 using 2
{
char data key_value;
TH0=-(10000/256);
TL0=-(10000%256);
TR0=0;
EA=0;
key_value=scan_key();
if(key_value!=-1) {
cnt=SKEY[key_value];
outflag=1;
C_send(cnt);
}
TR0=1;
EA=1;
}
/**********************************************************************
该函数为锁定时间函数,使起始条件或者停止时间大于4.7s
**********************************************************************/
void I2C_wait()
{
_nop_();
_nop_();
_nop_();
_nop_();
}
/**********************************************************************
启动总线函数,功能是启动I2C总线
***********************************************************************/
void Start()
{
Sda=1; I2C_wait();
Scl=1; I2C_wait();
Sda=0; I2C_wait();
Scl=0; I2C_wait();
}
/**********************************************************************
结束I2C总线函数,功能是结束I2C总线
***********************************************************************/
void Stop()
{
Sda=0; I2C_wait();
Scl=1; I2C_wait();
Sda=1; I2C_wait();
}
/*******************************************************************
读取AT24C01函数,功能是执行从AT24C01读数据的完整操作
********************************************************************/
void ReFromRom(uchar device, uchar Addr)
{
Start();
SendByte(AddWr);
ack();
SendByte(Addr);
ack();
Start();
SendByte(device);
ack();
distemp=ReadByte();
ack();
Stop();
}
/*******************************************************************
读取字节函数,功能是从AT24C01读取一个字节数据
********************************************************************/
uchar ReadByte()
{
uchar j, temp2=0;
Sda=1;
_nop_();
for(j=0;j<8;j++)
{
Scl=1;
I2C_wait();
temp2=temp2<<1;
if(Sda==1) temp2=temp2+1;
Scl=0;
I2C_wait();
}
return(temp2);
}
/****************************************************************
发送字节数据函数,功能是将数据DATA发送出去,可以是地址,也可以是数据
*****************************************************************/
void SendByte(uchar DATA)
{
uchar BitCounter=8; //位控制
do
{
if((DATA&0x80)==0x80)
Sda=1;
else
Sda=0;
_nop_();
_nop_();
Scl=1;
_nop_();
_nop_();
_nop_();
_nop_();
Scl=0; //数据改变
DATA=DATA<<1;
BitCounter--;
}while(BitCounter);
}
//===========================
char scan_key(void)
{
uchar i,j,in,ini,inj;
bit find=0;
for(i=0;i<4;i++)
{
P1=ACT[i];
delay(10);
in=P1;
in=in>>4;
in=in|0xf0;
for(j=0;j<4;j++)
{
if(ACT[j]==in)
{
find=1;
while((P1|0x0f)!=0xff);
delay(5);
inj=j; ini=i;
return(ini*4+inj);
}
}
}
if(find==0)return -1;
}
/*******************************************************************
写入AT24C01函数,功能是将数据写入AT24C01中
********************************************************************/
void WrToRom(uchar device,uchar Addr,uchar datevalue)
{
Start();
SendByte(device); //发送SLA+W
ack();
SendByte(Addr);
ack();
SendByte(datevalue);
ack();
Stop();
delay(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -