基于C251内核的ISP(SPCA2688A)下的IIC(400KHz)

主机:SPCA2688A
从机:MCP9808、SHT3XA
通信速率:400KHz

1. 状态定义

/*SCL,SDA状态定义*/
#define SCL_OUT_HIGH	NBYTE[0x2043] |= 0x04	//SCL输出高电平
#define SCL_OUT_LOW		NBYTE[0x2043] &= ~0x04	//SCL输出低电平
#define SDA_OUT_HIGH	NBYTE[0x2043] |= 0x08	//SDA输出高电平
#define SDA_OUT_LOW		NBYTE[0x2043] &= ~0x08	//SDA输出低电平

2. 设备地址

/*定义设备地址(7位地址)*/
#define ADDR1_SHT3XA	0x44
#define ADDR2_SHT3XA	0x45
#define ADDR_MCP9808	0x18

3. 延时时间

/*定义延时时间*/
void iicDelay(void)
{
	_nop_();	//基于C251的空指令延时
	_nop_();
	_nop_();
	_nop_();
}

4. 初始化

/*IIC初始化*/
void iicInit(void)
{
	NBYTE[0x20E8] |= 0x18;	//使能GPIO下拉功能
	NBYTE[0x2041] |= 0x0C;	//配置SDA,SCL为输出
	NBYTE[0x2043] |= 0x0C;	//默认输出高电平
	NBYTE[0x2074] &= ~0x0C;	//失能相关中断
	pcaDelayUsec_ROM(2);	//延时2ms
}

5. 起始条件

/*起始条件*/
void iicStart(void)
{
	NBYTE[0x2041] |= 0x0C;	//配置SDA,SCL为输出模式
	
	SDA_OUT_HIGH;
	SCL_OUT_HIGH;
	iicDelay();
	SDA_OUT_LOW;
	iicDelay();
	SCL_OUT_LOW;
}

6. 停止条件

/*停止条件*/
void iicStop(void)
{
	NBYTE[0x2041] |= 0x0C;	//配置SDA,SCL为输出模式
	
	SDA_OUT_LOW;
	SCL_OUT_LOW;
	iicDelay();
	SCL_OUT_HIGH;
	iicDelay();
	SDA_OUT_HIGH;
}

7. 接收应答

/*接收应答ACK*/
uint8_t getACK(void)
{
	uint8_t errTime = 10;
	
	NBYTE[0x2041] &= ~0x08;	//配置SDA为输入模式
	
	SDA_OUT_HIGH;
	iicDelay();
	SCL_OUT_HIGH;
	iicDelay();
	
	while(NBYTE[0x2045] & 0x08)
	{
		errTime--;
		if(!errTime)
			return 0;
	}
	
	SCL_OUT_LOW;
	return 1;
}

8. 发送应答

/*发送应答ACK*/
void sendACK(void)
{
	NBYTE[0x2041] |= 0x0C;	//配置SCL,SDA为输出模式
	
	SDA_OUT_LOW;
	iicDelay();
	SCL_OUT_HIGH;
	iicDelay();
	SCL_OUT_LOW;
}

9. 发送非应答

/*发送非应答NAK*/
void sendNAK(void)
{
	NBYTE[0x2041] |= 0x0C;	//配置SCL,SDA为输出模式
	
	SDA_OUT_HIGH;
	iicDelay();
	SCL_OUT_HIGH;
	iicDelay();
	SCL_OUT_LOW;
}

10. 发送数据

/*发送1字节数据*/
void iicSendData(uint8_t paraData)
{
	uint8_t j = 8;
	
	NBYTE[0x2041] |= 0x08;	//配置SDA为输出模式
	
	while(j--)
	{
		SCL_OUT_LOW;
		_nop_();
		
		if(paraData & 0x80)
			SDA_OUT_HIGH;
		else
			SDA_OUT_LOW;
			
		paraData <<= 1;
		iicDelay();
		SCL_OUT_HIGH;
		iicDelay();
	}
	
	SCL_OUT_LOW;
	SDA_OUT_HIGH;
	NBYTE[0x2041] &= ~0x08;			//配置SDA为输入模式
}

11. 接收数据

/*接收1字节数据并返回接收到的数据*/
uint8_t iicRecvData(void)
{
    uint8_t i=8;
    uint8_t ddata=0;

	NBYTE[0x2041] &= ~0x08;			//配置SDA为输入模式
	SDA_OUT_HIGH;
	
    while(i--)
    {
        ddata <<= 1;
		SCL_OUT_LOW;
        iicDelay();
		SCL_OUT_HIGH;
        iicDelay();
        
		if(NBYTE[0x2045] & 0x08)	//读取SDA输入电平状态
			ddata |= 0x01;
    }
    
	SCL_OUT_LOW;
    return ddata;
}

12. 测试代码I

/*以温度传感器MCP9808作代码测试*/
/*buffer:保存MCP9808返回的16bit温度数据*/
void getMCP9808(uint8_t buffer[])
{
	uint8_t ret, *pBuffer = buffer;
	uint8_t num = 0;
	
	iicInit();		//初始化
	iicStart();		//起始条件

	iicSendData((ADDR_MCP9808 << 1) & 0xFE);	//发送地址和写操作
	NBYTE[0x2108] = getACK();					//等待从机应答

	iicSendData(0x05);							//发送命令
	getACK();									//等待从机应答
	
	iicStart();									//IIC重启条件
	iicSendData((ADDR_MCP9808 << 1) | 0x01);	//发送地址和读操作
	getACK();									//等待从机应答
	
	num = 0;
	
	*pBuffer = iicRecvData();					//接收从机发送的数据高字节
	pBuffer++;
	sendACK();

	*pBuffer = iicRecvData();					//接收从机发送的数据低字节
	sendNAK();
	iicStop();
}

13. 测试代码II

/*以温湿度传感器SHT3XA作代码测试*/
/**********************************
buffer:保存SHT3XA返回的16bit温度数据 +
8bit CRC校验 + 16bit湿度数据 + 8bit CRC
**********************************/
void getSHT3XA(uint8_t * buffer)
{
	uint8_t ret,i = 0;
	uint8_t *pBuffer = buffer;
	static unsigned char count = 0;
	
	iicInit();
	iicStart();

	iicSendData(ADDR1_SHT3XA << 1);
	getACK();

	iicSendData(0x27);
	getACK();

	iicSendData(0x37);
	getACK();

	iicStop();
	
	if(count)
	{
		iicStart();
		
		iicSendData((ADDR1_SHT3XA << 1) | 0x01);
		getACK();

		for(i = 0, pBuffer = buffer; i < 6; i++, pBuffer++)
		{
			*pBuffer = iicRecvData();
			if(i < 5)
				sendACK();
			else
				sendNAK();
		}
		
		iicStop();
		count = 0;
	}
	else
		count++;
}

引用

iic标准代码(真正的万能代码1161)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值