用I2C总线传输数据控制继电器工作
2007-09-11 16:56
423 查看
用I2C总线传输数据控制继电器工作
#include <reg52.h>#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define dig_num P2
#define dig_seg P0
#define ADD_t1 0x10
#define ADD_t2 0x20
#define somenop(); _nop_();_nop_();_nop_();_nop_();_nop_();
bit ACK; /*应答标志位*/
sbit jdq=P3^7;
sbit key=P3^3;
sbit led3=P1^2;
sbit led1=P1^0;
sbit sw1=P2^7;
sbit sw2=P2^6;
sbit sw3=P2^5;
sbit sw5=P2^3;
sbit sw6=P2^2;
sbit beep=P2^0;
bit f_run,f_run_t;
sbit SDA=P3^4;
sbit SCL=P3^2;
uchar code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
uchar data count_1s;
uchar data buff_t1,buff_t2,t1,t2;
uchar data buff_led1,buff_led2,buff_led5,buff_led6,buff;
uchar dig_num0;
uchar data SLA _at_ 0x2e;
uchar data MTD _at_ 0x2f;
uchar data MRD _at_ 0x30;
void INT_0(void);
void delay(uint t);
void key_down(void);
void Input_I2C(uchar add,uchar add_t,uchar dat);
void Start_I2c();
void Stop_I2c();
void SendByte(uchar c);
void Ack_I2c(bit a);
uchar RcvByte(void);
//***********************************************************
void main(void)
{
sw1=0;sw2=0;sw3=0;sw5=0;sw6=0;key=1;
TMOD=0x01;
TH0=0xf0;TL0=0x60;
TCON=0x10; //TR0=1,IE0=0;
IE=0x82; //EA=1,EX0=1,ET0=1;
Start_I2c();
SLA=0xAE;
SendByte(SLA);
while(!ACK)SendByte(SLA);
SendByte(ADD_t1);
while(!ACK)SendByte(ADD_t1);
Start_I2c();
SLA=0xAF;
SendByte(SLA);
while(!ACK)SendByte(SLA);
t1=RcvByte();
Ack_I2c(ACK);
Stop_I2c();
buff_t1=t1;
Start_I2c();
SLA=0xAE;
SendByte(SLA);
while(!ACK)SendByte(SLA);
SendByte(ADD_t2);
while(!ACK)SendByte(ADD_t2);
Start_I2c();
SLA=0xAF;
SendByte(SLA);
while(!ACK)SendByte(SLA);
t2=RcvByte();
Ack_I2c(ACK);
Stop_I2c();
buff_t2=t2;
while(1)
{
if(!key)key_down();
if(f_run_t==0){f_run=0;buff_t1=t1;buff_t2=t2;}
}
}
//***************************************************************
//***************************************************************
void key_down(void)
{
if(sw1==0) //加1
{if(t1>=99){t1=0;
beep=0;
delay(30000);
beep=1;}
else{t1++;
beep=0;
delay(30000);
beep=1;}
buff_t1=t1;
Input_I2C(0xae,ADD_t1,t1);
delay(30000);
}
else if(sw2==0) //减1
{if(t1==0){t1=99;
beep=0;
delay(30000);
beep=1;}
else{t1--;
beep=0;
delay(30000);
beep=1;}
buff_t1=t1;
Input_I2C(0xae,ADD_t1,t1);
}
else if(sw3==0)
{f_run=1;f_run_t=1;beep=0;delay(30000);beep=1;led1=0;}
else if(sw5==0)
{if(t2>=10){t2=0; //加1
beep=0;
delay(30000);
beep=1;}
else{t2++; //减1
beep=0;
delay(30000);
beep=1;}
buff_t2=t2;
Input_I2C(0xae,ADD_t2,t2);
}
else if(sw6==0)
{if(t2==0){t2=10;
beep=0;
delay(30000);
beep=1;}
else{t2--;
beep=0;
delay(30000);
beep=1;}
buff_t2=t2;
Input_I2C(0xae,ADD_t2,t2);
}
}
//**************************************************************
void Input_I2C(uchar add,uchar add_t,uchar dat)
{
Start_I2c();
SLA=add;
SendByte(SLA);
while(!ACK)SendByte(SLA);
SendByte(add_t);
while(!ACK)SendByte(add_t);
SendByte(dat);
while(!ACK)SendByte(dat);
Stop_I2c();
}
/**********************************************************************************/
/**********************************************************************************/
void INT_0(void)interrupt 1
{TH0=0xf0;TL0=0x60;
if(f_run){ //有按键3按下,灯1亮,t1秒后,灯3亮?
if(count_1s==250){count_1s=0; //三秒后全部灭掉,数码管显示变化的时间
if(buff_t1==0){led3=0;jdq=1;
if(buff_t2==0){led1=1;led3=1;jdq=0;f_run_t=0;}
else buff_t2--;
}
else buff_t1--;
}
else count_1s++;
buff_led1=buff_t1/10;buff_led2=buff_t1%10;
buff_led5=buff_t2/10;buff_led6=buff_t2%10;
dig_num0=count_1s%4;
switch(dig_num0)
{case 0:dig_num=0x7f;
dig_seg=table[buff_led1];
break;
case 1:dig_num=0xbf;
dig_seg=table[buff_led2];
break;
case 2:dig_num=0xf7;
dig_seg=table[buff_led5];
break;
case 3:dig_num=0xfb;
dig_seg=table[buff_led6];
break;
default:break;
}
}
else {led3=1;led1=1; //未按键,灯不亮,数码管显示初始值1
if(count_1s==250)count_1s=0;
else count_1s++;
buff_led1=buff_t1/10;
buff_led2=buff_t1%10;
buff_led5=buff_t2/10;
buff_led6=buff_t2%10;
dig_num0=count_1s%4;
switch(dig_num0)
{case 0:dig_num=0x7f;
dig_seg=table[buff_led1];
break;
case 1:dig_num=0xbf;
dig_seg=table[buff_led2];
break;
case 2:dig_num=0xf7;
dig_seg=table[buff_led5];
break;
case 3:dig_num=0xfb;
dig_seg=table[buff_led6];
break;
default:break;
}
}
}
void delay(uint t)
{
while(--t);
}
/*************************I2C FUNCTION*******************************/
/*******************************************************************
起动总线函数
函数原型: void Start_I2c();
功能: 启动I2C总线,即发送I2C起始条件.
********************************************************************/
void Start_I2c()
{
SDA=1; /*发送起始条件的数据信号*/
_nop_();
SCL=1;
somenop(); /*起始条件建立时间大于4.7us,延时*/
SDA=0; /*发送起始信号*/
somenop(); /* 起始条件锁定时间大于4μs*/
SCL=0; /*钳住I2C总线,准备发送或接收数据 */
_nop_();
_nop_();
}
/*******************************************************************
结束总线函数
函数原型: void Stop_I2c();
功能: 结束I2C总线,即发送I2C结束条件.
********************************************************************/
void Stop_I2c()
{
SDA=0; /*发送结束条件的数据信号*/
_nop_(); /*发送结束条件的时钟信号*/
SCL=1; /*结束条件建立时间大于4μs*/
somenop();
SDA=1; /*发送I2C总线结束信号*/
somenop();
}
/*******************************************************************
字节数据传送函数
函数原型: void SendByte(uchar c);
功能: 将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
此状态位进行操作.(不应答或非应答都使ack=0 假)
发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8位*/
{
if((c<<BitCnt)&0x80)SDA=1; /*判断发送位*/
else SDA=0;
_nop_();
SCL=1; /*置时钟线为高,通知被控器开始接收数据位*/
somenop(); /*保证时钟高电平周期大于4μs*/
SCL=0;
}
_nop_();
_nop_();
SDA=1; /*8位发送完后释放数据线,准备接收应答位*/
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
if(SDA==1)ACK=0;
else ACK=1; /*判断是否接收到应答信号*/
SCL=0;
_nop_();
_nop_();
}
/********************************************************************
应答子函数
原型: void Ack_I2c(bit a);
功能:主控器进行应答信号,(可以是应答或非应答信号)
********************************************************************/
void Ack_I2c(bit a)
{
if(a==0)SDA=0; /*在此发出应答或非应答信号 */
else SDA=1;
_nop_();
_nop_();
_nop_();
SCL=1;
somenop(); /*时钟低电平周期大于4μs*/
SCL=0; /*清时钟线,钳住I2C总线以便继续接收*/
_nop_();
_nop_();
}
/*******************************************************************
字节数据传送函数
函数原型: uchar RcvByte();
功能: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数。
********************************************************************/
uchar RcvByte(void)
{
uchar BitCnt;
uchar retc;
retc=0;
SDA=1; /*置数据线为输入方式*/
_nop_();
_nop_();
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_nop_();
SCL=0; /*置时钟线为低,准备接收数据位*/
somenop(); /*时钟低电平周期大于4.7μs*/
SCL=1; /*置时钟线为高使数据线上数据有效*/
_nop_();
_nop_();
retc=retc<<1;
if(SDA==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
_nop_();
_nop_();
}
SCL=0;
_nop_();
_nop_();
return (retc);
}
相关文章推荐
- 7.STM32中对DMA_Config()函数的理解(自定义)测试DMA传输数据时CPU还可继续工作其他的事
- 远程控制编写之屏幕传输 MFC实现 屏幕截图 发送bmp数据 显示bmp图像
- 2017-02-14 面向连接的运输:TCP、TCP链接、TCP报文段结构、往返时间的估计与超时、可靠数据传输、流量控制、TCP链接管理
- 设备管理的数据传输控制方式
- 总线通信控制之异步串行通信的数据传输
- 与下位机通信时最好不要做其他工作 否则容易导致数据传输异常
- 工作笔记-数据验证和数据传输
- HUB工作特性及数据传输机制
- 数据在OSI七层模型中的各层传输的数据和控制信息的格式总结
- mini2440裸机试炼之——IIC控制EEPROM数据传输
- UDP传输(三):数据来自于键盘录入,键盘录入数据要自己控制录入结束。
- SWITCH工作特性及数据传输机制
- rsync的配置和以rsync的daemon工作模式传输数据
- rsync的配置和以rsync的daemon工作模式传输数据
- 远程控制编写之屏幕传输 MFC实现 屏幕截图 发送bmp数据 显示bmp图像
- 通过直接控制DNS进程进行数据传输
- C++实现线程同步的几种方式 线程同步是指同一进程中的多个线程互相协调工作从而达到一致性。之所以需要线程同步,是因为多个线程同时对一个数据对象进行修改操作时,可能会对数据造成破坏,下面是多
- Oracle中使用可传输表空间备份数据
- Junit测试Controller(MockMVC使用),传输@RequestBody数据解决办法
- COM原理及应用----统一数据传输