最近由于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;
}
相对来说比较简单基础,完毕。
以此开始,记录自己工作中的点滴,加深写作能力。