stm8s105调试I2C记录

最近由于AR项目中调试LCOS需要用到STM8S105的mcu,本次主要是使用模拟I2C。

1.IIC协议简介

 IIC协议这里只做简要介绍,详细介绍可以百度了解,协议相对简单,主要有开始位,停止位,应答位,非应答位。

开始位:当时钟为高,数据线由高变低

停止位:当时钟位高,数据线由低变高。

应答位:第9个时钟到来时,数据线为低。(这里第9个时钟,发送完一个字节,紧接着就是第9个时钟到来)

非应答位,第9个时钟到来时,数据线为高。

2.LCOS协议:

1.发送数据:

单数据发送: 开始位:写地址位(8bit):寄存器地址(16bit):数据(8bit):停止位

多字节发送:开始位:写地址(8bit):寄存器地址(16bit):数据(8bit*N):停止位

2.读取数据:

单字节读取:开始位:写地址(8bit):寄存器地址(16bit):开始位,读地址(8bit):读数据(8bit):停止位

单字节读取:开始位:写地址(8bit):寄存器地址(16bit):开始位,读地址(8bit):读数据(8bit*N):停止位

 

LCOS驱动源代码:

头文件

#ifndef OP02223_H_
#define OP02223_H_

#include "stm8s.h"
#include "stm8s_gpio.h"

//lcos driver i2c pin opt
#define LCOS_I2C_SDA_HIGH  GPIO_WriteHigh(GPIOC,GPIO_PIN_7)
#define LCOS_I2C_SDA_LOW   GPIO_WriteLow(GPIOC,GPIO_PIN_7)
#define LCOS_I2C_SCL_HIGH  GPIO_WriteHigh(GPIOC,GPIO_PIN_6)
#define LCOS_I2C_SCL_LOW   GPIO_WriteLow(GPIOC,GPIO_PIN_6)
#define LCOS_I2C_SDA_IN    GPIO_Init(GPIOC,GPIO_PIN_7,GPIO_MODE_IN_PU_NO_IT)
#define LCOS_I2C_SDA_OUT   GPIO_Init(GPIOC,GPIO_PIN_7,GPIO_MODE_OUT_OD_LOW_FAST)
#define LCOS_I2C_SDA_PIN_READ  GPIO_ReadInputPin(GPIOC,GPIO_PIN_7)

//LCOS device address
#define LCOS_L_ADDR (0xC8)
#define LCOS_R_ADDR (0xCA)

#define LCOS_ACK 1
#define LCOS_NO_ACK 0

void LCOS_delay(uint32_t us);
void LCOS_I2C_Start(void);
void LCOS_I2C_Stop(void);
void LCOS_I2C_Ack(void);
void LCOS_I2C_NoAck(void);
uint8_t LCOS_I2C_SendByte(uint8_t data);
uint8_t LCOS_I2C_RecvByte(void);

void OP02223_Init(void);
s32 OP02223_I2C_SingleWrite(uint8_t dev_addr,
                             uint16_t reg_addr,
														 uint8_t data);
s32 OP02223_I2C_BurstWrite(uint8_t dev_addr,
                            uint16_t reg_addr,
														uint8_t *data,
														uint32_t len);
s32 OP02223_I2C_SingleRead(uint8_t dev_addr,
																uint16_t reg_addr,
																uint8_t *readData);
s32 OP02223_I2C_BurstRead(uint8_t dev_addr,
																uint16_t reg_addr,
																uint8_t *readData,
															  uint32_t readMaxLen);

源码:

void LCOS_delay(uint32_t us)
{
	while(us--);
}

void LCOS_I2C_Start(void)
{
	LCOS_I2C_SDA_HIGH;
	LCOS_delay(5);
	LCOS_I2C_SCL_HIGH;
	LCOS_delay(5);
	LCOS_I2C_SDA_LOW;
	LCOS_delay(5);
	LCOS_I2C_SCL_LOW;
	LCOS_delay(5);
}

void LCOS_I2C_Stop(void)
{
	LCOS_I2C_SDA_LOW;
	LCOS_delay(5);
	LCOS_I2C_SCL_HIGH;
	LCOS_delay(5);
	LCOS_I2C_SDA_HIGH;
	LCOS_delay(5);
}

void LCOS_I2C_Ack(void)
{
	LCOS_I2C_SDA_LOW;
	LCOS_delay(5);
	LCOS_I2C_SCL_HIGH;
	LCOS_delay(5);
	LCOS_I2C_SCL_LOW;
	LCOS_delay(5);
	
}

void LCOS_I2C_NoAck(void)
{
	LCOS_I2C_SDA_HIGH;
	LCOS_delay(5);
	LCOS_I2C_SCL_HIGH;
	LCOS_delay(5);
	LCOS_I2C_SCL_LOW;
	LCOS_delay(5);
}

uint8_t LCOS_I2C_SendByte(uint8_t data)
{
	uint8_t status = 0;
	uint8_t i = 0;
	for (i=0; i < 8; i++)
	{
		if (data &0x80){
			LCOS_I2C_SDA_HIGH;
		}
		else{
			LCOS_I2C_SDA_LOW;
		}
		LCOS_I2C_SCL_HIGH;
		LCOS_delay(5);
		LCOS_I2C_SCL_LOW;
		LCOS_delay(5);
		data <<=1;
	}
   LCOS_I2C_SCL_LOW;
	 LCOS_delay(5);
	 LCOS_I2C_SDA_IN;
	 LCOS_delay(5);
	 LCOS_I2C_SCL_HIGH;
	// LCOS_delay(5);
	if (!LCOS_I2C_SDA_PIN_READ){
		status = LCOS_ACK;
	}
	else{
		status = LCOS_NO_ACK;
	}
	LCOS_delay(5);
	LCOS_I2C_SCL_LOW;
	LCOS_delay(5);
	LCOS_I2C_SDA_OUT;
	LCOS_delay(5);
	return status;
}

uint8_t LCOS_I2C_RecvByte(void)
{
	uint8_t i =0;
	uint8_t recvData = 0;
	//LCOS_I2C_SDA_HIGH;
	LCOS_I2C_SDA_IN;
	LCOS_delay(5);
	for (i=0; i < 8; i++)
	{
		recvData <<= 1;
		LCOS_I2C_SCL_HIGH;
		LCOS_delay(2);
		if (LCOS_I2C_SDA_PIN_READ){
			recvData |= 0x01;
		}
	//	else{
	//		recvData &= 0xfe;
	//	}
		LCOS_delay(5);
		LCOS_I2C_SCL_LOW;
		LCOS_delay(5);
	}
	LCOS_I2C_SDA_OUT;
	LCOS_delay(5);
	return recvData;
}

static void OP02223_SetReg(void)
{
    uint16_t addr = 0;
		uint8_t setValue = 0;
		volatile s32 i = 0;
		for (i = 3; i < sizeof(reg_value);i++)
		{
			OP02223_I2C_SingleWrite(LCOS_L_ADDR,i,reg_value[i]);
		//	printf("device_addr:%x,reg_addr:%x,setValue:%x.\r\n"
		//	       ,LCOS_L_ADDR,i,reg_value[i]);
		//	OP02223_I2C_SingleRead(LCOS_L_ADDR,i,&setValue);
		//	printf("device_addr:%x,reg_addr:%x,setValue:%x.\r\n"
		//	       ,LCOS_L_ADDR,i,setValue);
			OP02223_I2C_SingleWrite(LCOS_R_ADDR,i,reg_value[i]);
		//	printf("device_addr:%x,reg_addr:%x,setValue:%x.\r\n"
		//	       ,LCOS_R_ADDR,i,reg_value[i]);
		//	OP02223_I2C_SingleRead(LCOS_R_ADDR,i,&setValue);
		//	printf("device_addr:%x,reg_addr:%x,setValue:%x.\r\n"
		//	       ,LCOS_L_ADDR,i,setValue);
			//printf("------------------------------------------------\r\n");
		}

	  return;
}

static void OP02223_Test_Deal(void)
{
	  LCOS_delay(200);
	 GPIO_Init(GPIOC,GPIO_PIN_6|GPIO_PIN_7,GPIO_MODE_IN_PU_NO_IT);
	  LCOS_delay(200);
}

void OP02223_Init(void)
{
	 GPIO_DeInit(GPIOD); 
   GPIO_DeInit(GPIOC); 	 
	 GPIO_Init(GPIOD,GPIO_PIN_3,GPIO_MODE_IN_PU_NO_IT);//输入
	 GPIO_Init(GPIOC,GPIO_PIN_1|GPIO_PIN_3|GPIO_PIN_6|GPIO_PIN_7,GPIO_MODE_OUT_PP_LOW_FAST);
	//LCOS_delay(100);
	//while (!GPIO_ReadInputPin(GPIOD,GPIO_PIN_3)); //PD3=1
/*	while (1)
	{
		if (GPIO_ReadInputPin(GPIOD,GPIO_PIN_3))
		{
			break;
		}
		else
		{
		  delay(1);
		}
	}*/
	// GPIO_WriteHigh(GPIOC,GPIO_PIN_1);
	 LCOS_delay(200);
	 GPIO_WriteLow(GPIOC,GPIO_PIN_1);
	 GPIO_WriteLow(GPIOC,GPIO_PIN_3);
	 LCOS_delay(200);
	 LCOS_I2C_SDA_HIGH;
	 LCOS_I2C_SCL_HIGH;
	 LCOS_delay(200);
	 
   OP02223_SetReg();
	// OP02223_Test_Deal();
}

s32 OP02223_I2C_SingleWrite(uint8_t dev_addr,
                             uint16_t reg_addr,
														 uint8_t data)
{
	 uint8_t status;
	 uint32_t i = 0;
   uint8_t buf[4] = {0};
	 buf[0] = dev_addr;
	 buf[1] = reg_addr>>8;
	 buf[2] = (uint8_t)(reg_addr&0xFF);
	 buf[3] = data;
	 LCOS_I2C_Start();
	 for (i = 0; i <4; i++)
	 {
	    status = LCOS_I2C_SendByte(buf[i]);
			if (!status)//1error,0ok.
			{
//				I2C_Stop(LCOS_I2C);
				return -1;
			}
	 }
	// status = sendByteNoAck(LCOS_I2C,buf[3]);
	// status = sendByte(LCOS_I2C,buf[3]);
	 LCOS_I2C_Stop();
	 return 0;
}

s32 OP02223_I2C_BurstWrite(uint8_t dev_addr,
                            uint16_t reg_addr,
														uint8_t *data,
														uint32_t len)
{
	 bool status;
	 uint32_t i = 0;
   uint8_t buf[3] = {0};
	 buf[0] = dev_addr;
	 buf[1] = reg_addr>>8;
	 buf[2] = (uint8_t)(reg_addr&0xFF);
	 LCOS_I2C_Start();
	 for (i = 0; i < 3; i++)
	 {
	    status = LCOS_I2C_SendByte(buf[i]);
			if (status)//1error,0ok.
			{
				return -1;
			}
	 }
	 for (i = 0; i < len; i++)
	 {
		 status = LCOS_I2C_SendByte(data[i]);
			if (!status)//1error,0ok.
			{
				return -1;
			}
	 }
//	 I2C_NoAck(LCOS_I2C);
	 LCOS_I2C_Stop();
	 return 0;
}

s32 OP02223_I2C_SingleRead(uint8_t dev_addr,
																uint16_t reg_addr,
																uint8_t *readData)
{
	 bool status;
	 uint32_t i = 0;
   uint8_t buf[3] = {0};
	 buf[0] = dev_addr;
	 buf[1] = reg_addr>>8;
	 buf[2] = (uint8_t)(reg_addr&0xFF);
	 LCOS_I2C_Start();
	 for (i = 0; i < 3; i++)
	 {
	    status = LCOS_I2C_SendByte(buf[i]);
			if (!status)//1error,0ok.
			{
				return -1;
			}
	 }

	 LCOS_I2C_Start();//restart i2c
	 status = LCOS_I2C_SendByte(dev_addr+1);//send read address
	 if (!status)//1error,0ok.
	 {
				return -1;
	 }
	 *readData = LCOS_I2C_RecvByte();
	 LCOS_I2C_NoAck();
	 LCOS_I2C_Stop();
	return 0;
}
s32 OP02223_I2C_BurstRead(uint8_t dev_addr,
																uint16_t reg_addr,
																uint8_t *readData,
																uint32_t readMaxLen)
{
	 bool status;
	 uint32_t i = 0;
   uint8_t buf[3] = {0};
	 buf[0] = dev_addr;
	 buf[1] = reg_addr>>8;
	 buf[2] = (uint8_t)(reg_addr&0xFF);
	 LCOS_I2C_Start();
	 for (i = 0; i < 3; i++)
	 {
	    status = LCOS_I2C_SendByte(buf[i]);
			if (!status)//1error,0ok.
			{
				return -1;
			}
	 }
	 LCOS_I2C_Start();//restart i2c
	 status = LCOS_I2C_SendByte(dev_addr+1);//send read address
	 if (status)//1error,0ok.
	 {
				return -1;
	 }
	 for (i=0; i <readMaxLen-1; i++ )
	 {
	    *(readData+i) = LCOS_I2C_RecvByte();
			LCOS_I2C_Ack();
   }
	 if (i == readMaxLen-1)
	 {  
	    *(readData+i) = LCOS_I2C_RecvByte();
		  LCOS_I2C_NoAck();
   }
	 LCOS_I2C_Stop();
	 return 0;
	
}

相对来说比较简单基础,完毕。

以此开始,记录自己工作中的点滴,加深写作能力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值