原创 I2C驱动程序

2009-5-5 10:34 2646 4 6 分类: 软件与OS
今天写了段I2C驱动程序,参考了shjw的i2c程序,http://blog.ednchina.com/shjw/71946/message.aspx。在此对他表示感谢。下来就把我的程序贴出来,供大家交流。

/***********************************************************************
 *                                                                     * 
 *    Author:        ZP                                    *
 *    Company:       Xidian University                                 * 
 *    Filename:      i2c.c                                             *
 *    Date:          2009.05.05                                        *
 *    File Version:  1.0                                               *
 *    Other Files Required: p30f4013.h                          *
 *    Tools Used: MPLAB IDE -> 8.10                                    *
 *                Compiler  -> 3.10                                    *
 *                                                                     *
 *    Devices :     dsPIC30F4013,Zlg7290                              *
 **********************************************************************/
#include <p30f4013.h>

_FOSC(CSW_FSCM_OFF & XT_PLL16);
_FBORPOR(PBOR_ON & BORV_27 & PWRT_16 & MCLR_EN);
_FWDT(WDT_OFF);
_FGS(CODE_PROT_OFF);

#define uint unsigned int
#define  uchar  unsigned char
#define SDA _LATF2
#define SCL _LATF3

uchar keyzhi=88;
uchar ack;

void InitSys()
{
INTCON2bits.INT1EP=1;//INT1下降沿触发
IFS1bits.INT1IF=0;//中断标志位清零

_TRISF2=0;//SDA
_TRISF3=0;//SCL
_TRISD0=0;//RD0输出,led口
_TRISD2=0;//RD2,led
SDA=1;
SCL=1;
}

void delay( uint dex ) //延时函数,形参dex
{
uint i, j;
for(i=0; i<dex; i++ )
for(j=0; j<dex; j++ );
}

void Start()
{
SDA=1;//发送起始条件的数据信号
delay(8);
SCL=1;//起始条件建立时间大于4.7us,延时
delay(9);
SDA=0;//下降沿,启动i2c。起始条件锁定时间大于4us
delay(8);
SCL=0;//钳住SCL,准备发送或接收数据
delay(8);
}

void ReStart()
{
SDA=1;
delay(8);
SCL=1;//
delay(8);
SDA=0;//下降沿,启动i2c。起始条件锁定时间大于4us
delay(8);
SCL=0;
}

void ReceiveAck()
{
delay(8);
SCL=0;
delay(8);
SDA=1;
_TRISF2=1;//改变端口为输入,以接收应答信号
delay(8);
SCL=1;//拉高,锁定应答信号
delay(8);
if(_RF2==0) ack=0;//从器件发送应答为低
else ack=1;
SCL=0;//
delay(8);
_TRISF2=0;//恢复端口为输出
}

void SendByte(uchar k)//先发高位
{
uchar i;
SCL=0;
for(i=0; i<8; i++)
{
if ( (k&0x80)==0x80 ) SDA=1;//数据发送从最高位开始
else SDA=0;
SCL=1;//锁定数据
delay(8);
SCL=0;
delay(8);
k=k<<1;//左移一位
}
}

uchar ReceiveByte()
{
uchar i, j, key=0;
SCL=0;
_TRISF2=1;//改变端口为输入
delay(8);
for(i=0; i<8; i++)
{
SCL=1;
delay(8);
if(_RF2==0) j=0x00;//根据端口电平,对变量最高位赋值
else j=0x80;
j=j>>i;//移位
key=key | j;//
SCL=0;
delay(8);
}
_TRISF2=0;//恢复端口为输出
return (key);
}

void NoAck()//主器件接收到从器件发来的数据,不应答即不连续接收数据
{
SDA=1;//非应答信号
delay(8);
SCL=1;
delay(8);
SCL=0;//清时钟线
}

void Pause()//发送停止位,结束此次发送。此帧数据结束。
{
SDA=0;
delay(8);
SCL=1;
delay(8);
SDA=1;
delay(8);
}

//*****************START OF THE MAIN FUNCTION********************************************
int main()
{
uchar keyzhi=0xff;
InitSys();
while(1)
{
_LATD0=~_LATD0;//主程序正常运行标志灯
delay(0x5ff);
if(IFS1bits.INT1IF==1)
{
IFS1bits.INT1IF=0;//中断标志位清零
Start();
SendByte(0x70);//寻址从器件
ReceiveAck();
while(!(ack==0));
SendByte(0x01);//寻址键值寄存器
ReceiveAck();
while(!(ack==0));
ReStart();
SendByte(0x71);//寻址从器件
ReceiveAck();
while(!(ack==0));
keyzhi=ReceiveByte();
NoAck();

Pause();
SDA=1;
SCL=1;
if(keyzhi==1|| keyzhi==2)//两个按键来测试程序 
_LATD2=~_LATD2;//按键测试灯
}
}
return 0;
}





文章评论2条评论)

登录后参与讨论

用户545094 2009-5-8 21:22

谢谢楼主分享

用户1109524 2009-5-7 16:27

ding!!!

ilove314_323192455 2008-10-12 08:00

很好
相关推荐阅读
EE直播间
更多
我要评论
2
4
关闭 站长推荐上一条 /3 下一条