stm8s105调试I2C记录

2019-11-09来源: eefocus关键字:stm8s105  调试I2C  AR项目

最近由于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;

}

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


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


关键字:stm8s105  调试I2C  AR项目 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic479527.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:stm8的I2C库的使用
下一篇:STM8硬件I2C配置

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

stm8s 低功耗模式
因为用干电池供电,又需要超长待机了,成本又限制不能使用stm8l,所以开启低功耗之旅1.元器件选型挑选低功耗的元器件,一定要关注工作电流led 一定要高电平导通,不然的话,默认状态拉高很费电元器件尽量选择共阴解法,更省电2.主时钟频率频率和功耗是成正比的,选择试用的最低晶振能不开的功能尽量不开下面是对应的功耗表ADC最费电3.合理使用低功耗模式主要有一下几种等待模式活跃停机模式停机模式下面是对比等待模式使用asm(“WFI”)进入会被各种中断激活活跃停机模式AWU是用来当MCU进入低功耗的活跃停机(Active Halt)模式时提供一个内部的唤醒时间基准。该时间基准的时钟是由内部的低速RC振荡器时钟(LSI)或者通过预分频的HSE
发表于 2019-11-20
stm8s 低功耗模式
简单介绍下关于STM8S的几种低功耗模式
STM8S105的低功耗模式总的来说有四种:分别是等待模式,停机模式,快速活跃停机模式和慢速活跃停机模式1、等待模式:可执行指令wif()进入等待模式,该模式下主CPU停止工作,但其外设不停,严格来说只能算是降低功耗而不能算低功耗,该模式可由AMU或外部中断唤醒2、停机模式:可执行指令half()进入停机模式,该模式下主cpu和外设全部停止,达到最低功耗,只能由外部中断进行唤醒。3、快速活跃停机模式:在执行指令half()之前,如果你使能了AMU功能,则进入快速活跃停机模式,该模式下由于主电压调节器打开,在受到AMU或外部中断触发时,可快速唤醒。4、慢速活跃停机模式:在快速活跃停机模式下,如果设置内部时钟寄存器CLK_ICKR
发表于 2019-11-20
简单介绍下关于STM8S的几种低功耗模式
Atomthreads关于STM8S低功耗的思考
;              idle_thread_stack_top,                 idle_thread_stack_size);     /* Return status */    return (status); }针对STM8我们最自然想到的是在其中加一个wfi,STM8进入wfi模式几乎不会影响任何外设的运行。以STM8S105K4为例,其进入该模式的典型电流是1.8mA。这个电流,用一节
发表于 2019-11-20
Atomthreads关于STM8S低功耗的思考
STM8S 自动唤醒AWU配置
(AWU_TIMEBASE_12S);//12s后唤醒}主函数void main(void){ CLK_Config(); AWU_Config(); enableInterrupts(); halt(); //运行到此语句后会自动唤醒AWU,唤醒后不会复位, 而是进入了中断, 如果没有写复位语句, 那么就一直在中断了,不会唤醒系统 while(1);中断函数:INTERRUPT_HANDLER(AWU_IRQHandler, 1){  /*Clear AWU peripheral pending bit */ AWU_GetFlagStatus();//复位函数(用以跳出中断,很重要!!!)}
发表于 2019-11-20
STM8S EEPROM 操作
STM8S 内置EEPROM,对于很大需要带记忆的产品来说,是个很好的资源,以下是我个人摸索出来的,并且验证OK,大家如需要可放心使用。 #define EEPROMADDR0X000  ((u32)(FLASH_DATA_START_PHYSICAL_ADDRESS)) #define EEPROMADDR0X001  ((u32)(FLASH_DATA_START_PHYSICAL_ADDRESS+1)) #define EEPROMADDR0X002  ((u32)(FLASH_DATA_START_PHYSICAL_ADDRESS+2)) #define
发表于 2019-11-19
stm8s eeprom读写
stm8s有自带的eeprom,起始地址是0x4000,终止到哪看手册,因为我用的时候只写一个4字节数据,配置如下:入参:eeprom偏移地址,写入的数据   void eeprom_write(const unsigned char addr,unsigned long date){   asm("sim");   FLASH_CR1_FIX = 1;//编程时间固定为标准编程时间   FLASH_CR2_WPRG = 1;//使能字编程   FLASH_NCR2_NWPRG = 0;/使能字编程 
发表于 2019-11-19
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved