历史上的今天
今天是:2024年11月09日(星期六)
2019年11月09日 | stm8s105调试I2C记录
2019-11-09 来源:eefocus
最近由于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.rn"
// ,LCOS_L_ADDR,i,reg_value[i]);
// OP02223_I2C_SingleRead(LCOS_L_ADDR,i,&setValue);
// printf("device_addr:%x,reg_addr:%x,setValue:%x.rn"
// ,LCOS_L_ADDR,i,setValue);
OP02223_I2C_SingleWrite(LCOS_R_ADDR,i,reg_value[i]);
// printf("device_addr:%x,reg_addr:%x,setValue:%x.rn"
// ,LCOS_R_ADDR,i,reg_value[i]);
// OP02223_I2C_SingleRead(LCOS_R_ADDR,i,&setValue);
// printf("device_addr:%x,reg_addr:%x,setValue:%x.rn"
// ,LCOS_L_ADDR,i,setValue);
//printf("------------------------------------------------rn");
}
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 *(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; } 相对来说比较简单基础,完毕。 以此开始,记录自己工作中的点滴,加深写作能力。
上一篇:stm8的I2C库的使用
下一篇:STM8硬件I2C配置
史海拾趣
|
我现在正在调试的系统中用到了RTL8212,是一块千兆双口物理层收发器。现在他能够正常接收数据,但是却不能发送数据,发出的数据在接收方说是错误的数据包。我是用一块FPGA来控制的,现在不知道问题出在哪里,不知道是我的FPGA时序不对还是RTL8212的 ...… 查看全部问答> |
|
目 录 第1章 UNIX操作系统概述 6 1.1 UNIX操作系统简介 6 1.2 UNIX系统组成 6 1.3 与UNIX有关的几个名词 7 第2章 UNIX常用操作 9 2.1 启动终端 9 2.2 登录 9 2.3 UNIX命令 9 2.4 注销(退出UNIX系统) 13 第3章 UNIX文件系统 ...… 查看全部问答> |
|
arm+linux平台 通过 串口发送 数据 write完以后 必须sleep()发送才能成功 否则,发送的就在中间某位产生错误码,数据长的时候,总是在中间顿一下,然后发后半部分,前半部分的最后一个字节就错掉了 这是怎么回事? 太怪了 高手帮忙分析吧 … 查看全部问答> |
|
我用stc12c5608AD自带的AD做一个AD转换的程序 具体的代码如下 void ad_cov() { P1M0=P1M0||0x20; P1M1=P1M1||0x20; //选择P1.5为开漏。(做A/D使用时选择的模式) ADC_CONTR=0xc5; //540个时钟周期转换一次;ADC_FLAG=0;ADC_START=0(设置为1 ...… 查看全部问答> |
|
自己仿着S3C2410a的开发板,根据需要自己做了一个底板(插在上面的核心板没做),画了PCB,只用了电源,串口和液晶屏(其它的没画),做好板之后又焊上器件,当把原来的核心板(系统在flash里)插在我做的板子上时,液晶可以正常开启,但是触摸时只 ...… 查看全部问答> |




