📄 m430iicbus.c
字号:
//模拟IIC,采用P31,32口
//描述:MSP430模拟IIC驱动程序
//编写:微控设计网 DC版主 日期:2008.1.
//编译环境:IAR EW430 V3.42A
//验证平台: www.microcontrol.cn MC430F14+开发板 V1.0
//声明:此程序只供微控用户使用.在未得到DC版主的许可请勿将资料外公开和用于商业用途.
//******************************************************************************
// ACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO = 32 x ACLK = 1048576Hz
// //* An external watch crystal between XIN & XOUT is required for ACLK *//
#include<msp430x14x.h>
//******************************************************************************
//SDA 数据线定义
#define SDAOUT P3DIR |= BIT1
#define SDAIN P3DIR &= ~BIT1
#define SDA1 P3OUT |= BIT1
#define SDA0 P3OUT &= ~BIT1
//SCL 时钟线定义
#define SCLOUT P3DIR |= BIT2
#define SCL1 P3OUT |= BIT2
#define SCL0 P3OUT &= ~BIT2
#define SDA_STATE P3IN & BIT1 //读入SDA状态
//******************************************************************************
#define SDA_MOV_BIT 1 //SDA 数据调整移位
//从器件接收方的应答返回标志
#define OK 0x01 //表示从器件有应答
#define NO 0x00 //表示从器件无应答
//IIC总线操作成失标志
#define error 0x01 //错误
#define right 0x00 //正确
//******************************************************************************
//小延时
nop_()
{_NOP();_NOP();}
SomeNOP()
{nop_();nop_();nop_();nop_();}
//******************************************************************************
//起始信号
void I2CStart(void)
{
_DINT(); //关总中断;
SCLOUT; //SCL口设为输出-------后加
SDAOUT; //SDA口设为输出
SDA1;
//SCLOUT; //SCL口设为输出
SCL1;
SomeNOP(); SomeNOP(); //INI
SDA0;
SomeNOP(); SomeNOP(); //START
SCL0;
}
//******************************************************************************
//结束信号
void I2CStop(void)
{
SCL0;
SDA0;
SomeNOP(); //INI
SCL1;
SomeNOP();
SDA1; //STOP
_EINT(); //EA=1;
}
//******************************************************************************
//等待从器件接收方的应答
unsigned char WaitAck(void)
{
unsigned char errtime=255; //因故障接收方无ACK,超时值为255。
SDA1;
SomeNOP();
SCL1;
SomeNOP();
SDAIN; //SDA口设为输入
while(SDA_STATE) //SDA出现为0时,则为有应答
{ errtime--;
if (!errtime) //errtime是否为0
{I2CStop();
return NO;} //返回为0(失败)
}
SDAOUT; //SDA口设为输出
SCL0;
return OK; //返回为1(成功)
}
//******************************************************************************
//主器件为接收方,从器件为发送方时,单片机发出应答信号
//MCU Send to IC
void SendAck(void)
{
SDA0;
SomeNOP();
SCL1;
SomeNOP();
SCL0;
}
//******************************************************************************
//主器件为接收方,从器件为发送方时,非应答信号
void SendNotAck(void)
{
SDA1;
SomeNOP();
SCL1;
SomeNOP();
SCL0;
}
//******************************************************************************
//发送字节
void I2CSendByte(unsigned char ch)
{
unsigned char i=8;
while (i--)
{
SCL0; //SCL=0;
nop_();
if(ch&0x80)
SDA1; //使SDA为1位
else
SDA0; //使SDA为0位
//---------------
ch<<=1;
SomeNOP();
SCL1;
SomeNOP();
}
SCL0;
}
//******************************************************************************
//接收字节
unsigned char I2CReceiveByte(void)
{
unsigned char i=8; //接收8位
unsigned char ddata,timp;
ddata=0;
SDA1;
SDAIN; //SDA口设为输入
while (i--)
{
ddata<<=1; //将ddata位向高位移,于让位0
SCL0;
SomeNOP();
SCL1;
SomeNOP();
timp = SDA_STATE; //读入SDA,后加
timp>>=SDA_MOV_BIT; //将timp的SDA位数据移到位0
ddata|=timp; //将timp的SDA位数据移到ddata位0
}
SCL0; //SCL=0;
SDAOUT; //(附加)SDA口设回为输出
return ddata;
}
//******************************************************************************
//描述:微控设计网 www.microcontrol.cn MSP430单片机模拟IIC(Inter IC)总线程序
//编写:微控设计网 DC 版主,如有问题,欢迎到微控技术论坛来讨论
//正常操作时返回位值为0,有故障时返回位值为1.
//unsigned char *DataBuff数据缓冲区指针,char ByteQuantity字节数量,
//unsigned int Address IC片内地址,
//unsigned char ControlByte芯片控制字节-IC地址/读写位,
unsigned char IIC(unsigned char *DataBuff,char ByteQuantity,unsigned int Address,
unsigned char ControlByte)
{
unsigned char errorflag=error; //错误标志位,1为错误,0为正确
unsigned char i; //i为允许本次操作的最大次数
i=1;
SCLOUT; //时钟口长设为输出
while(i--)
{
I2CStart();
I2CSendByte(ControlByte&0xfe);//指定芯片,此次必定为写
if(!WaitAck()) //涵数返回一个1为成功
continue; //结束写操作,并i-1后,再来一次
I2CSendByte((unsigned char)Address); //发送片内地址
if(!WaitAck()) //数返回一个1为成功
continue; //结束写操作,并i-1后,再来一次
//------------------------------已经选定好IC
if(!(ControlByte&0x01)) //本次操作是读还是写
{ //写操作
errorflag=right; //清错误标志位为0
while(ByteQuantity--) //操作j个数字节
{
I2CSendByte(*DataBuff++);//发送
if(WaitAck()) //涵数返回一个1为成功,涵数返回一个0为失败
continue; //成功,下一个数据循环(跳while)
errorflag=error; //不应答,失败了. errorflag=1
break; //退出写操作
}
if(errorflag==error) //经过写完后,如果最后errorflag标志为1,则表示有错误
continue; //结束写操作,并i-1后,再来一次
break; //写操作完成
}
else //则为读操作
{ I2CStart(); //开始
I2CSendByte(ControlByte);
if(!WaitAck()) //涵数返回一个1为成功
{continue;} //结束此操作,并i-1后,再来一次
while(--ByteQuantity) //读入ByteQuantity个数字节
{*DataBuff++=I2CReceiveByte();//连续读入ByteQuantity个数据
SendAck();} //主机向从机发出应答,表示主机已接收
*DataBuff=I2CReceiveByte(); //读入最后个数据
SendNotAck(); //最后发出不应答信号(位),表示主机不再读了.
errorflag=right; //向错误标志位写0(right),表示读数据正确.
break;} //读操作完成*/
}
I2CStop(); //停止,结束IIC总线
return(errorflag); //返回操作成败标志
}
//******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -