⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 msp430单片机I2C总线读写程序,
💻 C
字号:
#include "I2C.h"

void I2C_Initial( void )
{
    P1DIR |= BIT2;		//将SCL管脚(P1.2)设置为输出管脚
    I2C_Set_sck_low();
    I2C_STOP();
    Delay_ms(10);
    return;
}
void I2C_Set_sda_high( void )
{
    P1DIR |= SDA;		//将SDA设置为输出模式
    P1OUT |= SDA;		//SDA管脚输出为高电平
    
    _NOP();
    _NOP();
    return;
}
void I2C_Set_sda_low ( void )
{
    P1DIR |= SDA;		//将SDA设置为输出模式
    P1OUT &= ~(SDA);		//SDA管脚输出为低电平
    
    _NOP();
    _NOP();
    return;
}
void I2C_Set_sck_high( void )
{
    P1DIR |= SCL;		//将SCL设置为输出模式
    P1OUT |= SCL;		//SCL管脚输出为高电平
    
    _NOP();
    _NOP();
    return;
}
void I2C_Set_sck_low ( void )
{
    P1DIR |= SCL;		//将SCL设置为输出模式
    P1OUT &= ~(SCL);		//SCL管脚输出为低电平
    
    _NOP();
    _NOP();
    return;
}
int  I2C_GetACK(void)
{
    int nTemp = 0;
    int j;
    
    _NOP();
    _NOP();
    I2C_Set_sck_low();
    for(j = 30;j > 0;j--);
    P1DIR &= ~(SDA);		//将SDA设置为输入方向
    //I2C_Set_sda_high();
    I2C_Set_sck_high();
    
    for(j = 30;j > 0;j--);
    nTemp = (int)(P1IN & SDA);	//获得数据
    
    I2C_Set_sck_low();
    
    return (nTemp & SDA);
}
void I2C_SetACK(void)
{   
    I2C_Set_sck_low();
    I2C_Set_sda_low();
    I2C_Set_sck_high();
    I2C_Set_sck_low();
    return;
}
void I2C_SetNAk(void)
{
    I2C_Set_sck_low();
    I2C_Set_sda_high();
    I2C_Set_sck_high();
    I2C_Set_sck_low();
    return;
}
void I2C_START(void)
{
    int i;
    
    I2C_Set_sda_high();
    for(i = 5;i > 0;i--);
    I2C_Set_sck_high();
    for(i = 5;i > 0;i--);
    I2C_Set_sda_low();
    for(i = 5;i > 0;i--);
    I2C_Set_sck_low();
    return;
}
void I2C_STOP(void)
{
    int i;
    
    I2C_Set_sda_low();
    for(i = 5;i > 0;i--);
    I2C_Set_sck_low();
    for(i = 5;i > 0;i--);
    I2C_Set_sck_high();
    for(i = 5;i > 0;i--);
    I2C_Set_sda_high();
    for(i = 5;i > 0;i--);
    I2C_Set_sck_low();
    Delay_ms(10);		//延迟一点时间
    
    return;
}
void I2C_TxByte(int nValue)
{
    int i;
    int j;
    
    for(i = 0;i < 8;i++)
    {
    	if(nValue & 0x80)
    	    I2C_Set_sda_high();
    	else
    	    I2C_Set_sda_low();
    	for(j = 30;j > 0;j--);
    	I2C_Set_sck_high();
    	nValue <<= 1;
    	for(j = 30;j > 0;j--);
    	I2C_Set_sck_low();
    }
    
    return;
}
/////////////////////////////////////////////
// 接收是从 LSB 到 MSB 的顺序
int  I2C_RxByte(void)
{
    int nTemp = 0;
    int i;
    int j;
    
    I2C_Set_sda_high();
    
    P1DIR &= ~(SDA);			//将SDA管脚设置为输入方向
    _NOP();
    _NOP();
    _NOP();
    _NOP();
    for(i = 0;i < 8;i++)
    {
    	I2C_Set_sck_high();
    	
    	if(P1IN & SDA)
    	{
    	    nTemp |= (0x01 << i);
    	}
    	for(j = 30;j > 0;j--);
    	I2C_Set_sck_low();
    }
    
    return nTemp;
}
/////////////////////////////////////////////
// 接收是从 MSB 到 LSB 的顺序
int  I2C_RxByteHiToLow(void)
{
    int nTemp = 0;
    int i;
    int j;
    
    I2C_Set_sda_high();
    
    P1DIR &= ~(SDA);			//将SDA管脚设置为输入方向
    _NOP();
    _NOP();
    _NOP();
    _NOP();
    for(i = 0;i < 8;i++)
    {
    	I2C_Set_sck_high();
    	
    	if(P1IN & SDA)
    	{
    	    nTemp |= (0x01 << (8-i));
    	}
    	for(j = 30;j > 0;j--);
    	I2C_Set_sck_low();
    }
    
    return nTemp;
}
int WriteSingleByte(char nAddr,char nValue)
{
	int nTemp = 0xA0;//写命令
	// 启动数据总线
	I2C_START();
	// 发送控制字节
	I2C_TxByte(nTemp);
	// 等待 ACK
	nTemp = I2C_GetACK();
	if(nTemp & BIT3) return 0;

	// 发送地址字节
	I2C_TxByte(nAddr);
	// 等待 ACK
	nTemp = I2C_GetACK();
	if(nTemp & BIT3) return 0;

	// 发送数据字节
	I2C_TxByte(nValue);
	// 等待 ACK
	nTemp = I2C_GetACK();
	if(nTemp & BIT3) return 0;

	// 停止总线
	I2C_STOP();				
    return (nTemp & SDA);
}
int PageWrite(char nAddr,char pBuf[])
{
	int i;
	int nTemp = 0xA0;//写命令
	// 启动数据总线
	I2C_START();
	// 发送控制字节
	I2C_TxByte(nTemp);
	// 等待 ACK
	nTemp = I2C_GetACK();
	if(nTemp & BIT3) return 0;

	// 发送地址字节
	I2C_TxByte(nAddr);
	// 等待 ACK
	nTemp = I2C_GetACK();
	if(nTemp & BIT3) return 0;

	// 发送数据字节
	for(i = 0; i < 8;i++)
	{
		I2C_TxByte(pBuf[0]);
		// 等待 ACK
		nTemp = I2C_GetACK();
		if(nTemp & BIT3) return 0;
	}
	
	// 停止总线
	I2C_STOP();				
    return (nTemp & SDA);
}
int ReadRandom(char nAddr, char *nValue)
{
	//写命令
	int nTemp = 0xA0;
	// 启动数据总线
	I2C_START();
	// 发送控制字节
	I2C_TxByte(nTemp);
	// 等待 ACK
	nTemp = I2C_GetACK();
	if(nTemp & BIT3) return 0;

	// 发送地址字节
	I2C_TxByte(nAddr);
	// 等待 ACK
	nTemp = I2C_GetACK();
	if(nTemp & BIT3) return 0;

	// 启动数据总线
	I2C_START();
	// 发送控制字节
	nTemp = 0xA1;
	I2C_TxByte(nTemp);
	// 等待 ACK
	nTemp = I2C_GetACK();
	if(nTemp & BIT3) return 0;

	//读取数据
    *nValue = I2C_RxByte();

	// 停止总线
	I2C_STOP();
	//成功返回
	return 1;
}
int ReadSeq(char nAddr, char nValue[], int nLen)
{
	int i;
	//写命令
	int nTemp = 0xA0;
	// 启动数据总线
	I2C_START();
	// 发送控制字节
	I2C_TxByte(nTemp);
	// 等待 ACK
	nTemp = I2C_GetACK();
	if(nTemp & BIT3) return 0;

	// 发送地址字节
	I2C_TxByte(nAddr);
	// 等待 ACK
	nTemp = I2C_GetACK();
	if(nTemp & BIT3) return 0;

	// 启动数据总线
	I2C_START();
	// 发送控制字节
	nTemp = 0xA1;
	I2C_TxByte(nTemp);
	// 等待 ACK
	nTemp = I2C_GetACK();
	if(nTemp & BIT3) return 0;

	//读取数据
	for(i = 0; i < nLen; i++)
	{
		//读一个字节数据
		nValue[i] = I2C_RxByte();
		//发送ACK
		I2C_SetACK();
	}    

	// 停止总线
	I2C_STOP();
	//成功返回
	return 1;
}
void Delay_ms(unsigned long nValue)//毫秒为单位,8MHz为主时钟
{
    unsigned long nCount;
    int i;
    unsigned long j;
    nCount = 2667;
    for(i = nValue;i > 0;i--)
    {
    	for(j = nCount;j > 0;j--);
    }
    return;
}
void Delay_us(unsigned long nValue)//微秒为单位,8MHz为主时钟
{
    int nCount;
    int i;
    int j;
    nCount = 3;
    for(i = nValue;i > 0;i--)
    {
    	for(j = nCount;j > 0;j--);
    }
    return;
}
void Init_CLK(void)
{
    unsigned int i;
    BCSCTL1 = 0X00;	//将寄存器的内容清零
					//XT2震荡器开启
					//LFTX1工作在低频模式
					//ACLK的分频因子为1
					
    do 
    {
		// 清除OSCFault标志
	    IFG1 &= ~OFIFG;    
	    for (i = 0x20; i > 0; i--);                
    }
    while ((IFG1 & OFIFG) == OFIFG);// 如果OSCFault =1   
					
	//将寄存器的内容清零
    BCSCTL2 = 0X00;		
	//MCLK的时钟源为TX2CLK,分频因子为1
    BCSCTL2 += SELM1;	
	//SMCLK的时钟源为TX2CLK,分频因子为1
    BCSCTL2 += SELS;	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -