STM32模拟IIC+颜色识别TCS34725

您所在的位置:网站首页 颜色识别测试机怎么使用 STM32模拟IIC+颜色识别TCS34725

STM32模拟IIC+颜色识别TCS34725

2024-07-07 18:27:40| 来源: 网络整理| 查看: 265

STM32模拟IIC+颜色识别TCS34725 一、硬件参数 1.参数及接口 VCC3.3/5V 电源正GND电源地SDAI2C 数据输入SCLI2C 时钟输入 二、通信协议 1.IIC时序图

[Alt] 从I2C时序图的得知使用的是 I2C 通信,I2C 通信,一条数据线,一条时钟线。 I2C 总线在传送数据 过程中共有三种类型信号:开始信号、结束信号和应答信号。

开始信号:SCL 为高电平时, SDA 由高电平向低电平跳变,开始传送数据。

结束信号:SCL 为高电平时, SDA 由低电平向高电平跳变,结束传送数据。

应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低 电平脉冲,表示已收到数据。

2.读写时序

在这里插入图片描述 这是一个标准的IIC通信时序

1、写命令寄存器时序:开始信号—写7位IIC地址—写1位读写标识—等待从机ACK—写命令寄存器地址—等待从机ACK—写数据—等待从机ACK–……–停止信号。

2、读命令寄存器时序:开始信号—写7位IIC地址—写1位读写标识—等待从机ACK—写命令寄存器地址—等待从机ACK—开始信号—写7位IIC地址—写1位读写标识—等待从机ACK—等待从机数据—写应答ACK—等待从机数据—写应答ACK–……–停止信号。

链接:https://www.waveshare.net/w/upload/3/3c/TCS34725_Color_Sensro_user_manual_cn.pdf

微雪电子的用户手册都有详细说明,里面也有驱动例程。

三、模拟IIC驱动

了解IIC的通信后,就可以着手写IIC的驱动的程序了,我也搜了一些网上其他的一些模拟IIC的通信,程序都大同小异,基本上都差不多。但有些毕竟具体的细节的和一些IO口设置并不是很明确。所以IIC的驱动程序我也就不详细说了(程序在下面也会附上),主要重点说一些我自己总节的一些细节。

1、IO口的配置

在这里插入图片描述

我看的网上的文章基本大部分用的都是推挽输出,然后用GPIO的内部寄存器(如上图)去调换IO的输入输出模式。这样确实是可行的,但对于刚刚学习的小白,去理解寄存器操作可以并不是很明白,并且这种是适用不了51这种单片机的。51单片机的IO是作为标准双向IO口,也就是既可以做输出,也可以做输入,同理开漏输出模式也是双向IO口,所以我个人觉得这里把IO引脚设为开漏输出模式更方便实用。

在这里插入图片描述 我这里用的是单片机STMF030RCT6的PC4和PCB口,我是用MXCube直接配置的开漏浮空,也可以用代码直接实现在程序运行前初始化GPIO口就行。

GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; //开漏输出 GPIO_InitStruct.Pull = GPIO_NOPULL; //浮空 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

GPIO_InitStruct是一个结构体,名字是GPIO_InitStructure,结构体原型由GPIO_InitTypeDef 确定,STM32里面初始化GPIO用的。

HAL_GPIO_Init(GPIOC, &GPIO_InitStructure),括号里后面那个就是你问题里面声明的那个结构体,这个函数是HAL库已经帮我们封装好的函数。

2、us延时

IIC的延时都是微秒级而且是要求精确的,一般STM的系统延时都是毫秒级的,明显是无法使用的,所以这里得用定时器。我这里用的是定时器14。 在这里插入图片描述

使用定时器就得了解单片机的时钟频率和定时器的预分频系数,STMF030RCT6单片机是时钟频率是48MHz,我要得到1us的计时也就是要得到1MHz的频率,也就是要分频48-1,预分频系数就是47,自动重装载值为1,向上计数模式。

同样可以用代码实现

static void MX_TIM14_Init(void) { /* USER CODE BEGIN TIM14_Init 0 */ /* USER CODE END TIM14_Init 0 */ /* USER CODE BEGIN TIM14_Init 1 */ /* USER CODE END TIM14_Init 1 */ htim14.Instance = TIM14; htim14.Init.Prescaler = 47; htim14.Init.CounterMode = TIM_COUNTERMODE_UP; htim14.Init.Period = 65535; htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim14) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN TIM14_Init 2 */ /* USER CODE END TIM14_Init 2 */ } HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

定时器开启之后,就要编写延时函数

extern TIM_HandleTypeDef htim14; void delay_s(uint32_t i) { uint16_t differ = 0xffff- i - 5;//65535-5-i,计数初值,由这个数计数到65535刚好计数us次, //也就实现了n us延时 __HAL_TIM_SET_COUNTER(&htim14, differ); //设置计数值 HAL_TIM_Base_Start(&htim14); //开启定时器 while(differ TCS_SDA_H; TCS_SCL_H; delay_s(40);//delay_us(4); TCS_SDA_L; delay_s(40);//delay_us(4); TCS_SCL_L; } /*********************************************/ void TCS34725_I2C_Stop() { //TCS_SDA_OUT(); TCS_SCL_L; TCS_SDA_L; delay_s(40);//delay_us(4); TCS_SCL_H; TCS_SDA_H; delay_s(40);//delay_us(4); } /*********************************************/ //返回值:1,接收应答失败 // 0,接收应答成功 uint8_t TCS34725_I2C_Wait_ACK() { uint32_t t=0; TCS_SDA_H; delay_s(10);//delay_us(1); TCS_SCL_H; delay_s(10);//delay_us(1); while(TCS_SDA_READ) { t++; if(t > 250) { TCS34725_I2C_Stop(); return 1; } } TCS_SCL_L; return 0; } /*********************************************/ //产生ACK应答 void TCS34725_I2C_ACK() { TCS_SCL_L; TCS_SDA_L; delay_s(20);//delay_us(2); TCS_SCL_H; delay_s(20);//delay_us(2); TCS_SCL_L; } /*********************************************/ //不产生ACK应答 void TCS34725_I2C_NACK() { TCS_SCL_L; TCS_SDA_H; delay_s(20);//delay_us(2); TCS_SCL_H; delay_s(20);//delay_us(2); TCS_SCL_L; } /*********************************************/ //I2C发送一个字节 void TCS34725_I2C_Send_Byte(uint8_t byte) { uint8_t i; TCS_SCL_L;//拉低时钟开始数据传输 for(i = 0; i uint8_t i,receive = 0; //TCS_SDA_IN(); for(i = 0; i unsigned short c; //[0-65536] unsigned short r; unsigned short g; unsigned short b; }COLOR_RGBC;//RGBC /******************************************************************************* * @brief Writes data to a slave device. * * @param slaveAddress - Adress of the slave device. * @param dataBuffer - Pointer to a buffer storing the transmission data. * @param bytesNumber - Number of bytes to write. * @param stopBit - Stop condition control. * Example: 0 - A stop condition will not be sent; * 1 - A stop condition will be sent. *******************************************************************************/ void TCS34725_I2C_Write(uint8_t slaveAddress, uint8_t* dataBuffer,uint8_t bytesNumber, uint8_t stopBit) { uint8_t i = 0; TCS34725_I2C_Start(); TCS34725_I2C_Send_Byte((slaveAddress uint8_t i = 0; TCS34725_I2C_Start(); TCS34725_I2C_Send_Byte((slaveAddress *(dataBuffer + i) = TCS34725_I2C_Read_Byte(0);//读取的最后一个字节发送NACK } else { *(dataBuffer + i) = TCS34725_I2C_Read_Byte(1); } } if(stopBit == 1) TCS34725_I2C_Stop(); } /******************************************************************************* * @brief Writes data into TCS34725 registers, starting from the selected * register address pointer. * * @param subAddr - The selected register address pointer. * @param dataBuffer - Pointer to a buffer storing the transmission data. * @param bytesNumber - Number of bytes that will be sent. * * @return None. *******************************************************************************/ void TCS34725_Write(uint8_t subAddr, uint8_t* dataBuffer, uint8_t bytesNumber) { uint8_t sendBuffer[10] = {0, }; uint8_t byte = 0; sendBuffer[0] = subAddr | TCS34725_COMMAND_BIT; for(byte = 1; byte subAddr |= TCS34725_COMMAND_BIT; TCS34725_I2C_Write(TCS34725_ADDRESS, (uint8_t*)&subAddr, 1, 0); TCS34725_I2C_Read(TCS34725_ADDRESS, dataBuffer, bytesNumber, 1); } /******************************************************************************* * @brief TCS34725设置积分时间 * * @return None *******************************************************************************/ void TCS34725_SetIntegrationTime(uint8_t time) { TCS34725_Write(TCS34725_ATIME, &time, 1); } /******************************************************************************* * @brief TCS34725设置增益 * * @return None *******************************************************************************/ void TCS34725_SetGain(uint8_t gain) { TCS34725_Write(TCS34725_CONTROL, &gain, 1); } /******************************************************************************* * @brief TCS34725使能 * * @return None *******************************************************************************/ void TCS34725_Enable(void) { uint8_t cmd = TCS34725_ENABLE_PON; TCS34725_Write(TCS34725_ENABLE, &cmd, 1); cmd = TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN; TCS34725_Write(TCS34725_ENABLE, &cmd, 1); //delay_s(600000);//delay_ms(3);//延时应该放在设置AEN之后 } /******************************************************************************* * @brief TCS34725失能 * * @return None *******************************************************************************/ void TCS34725_Disable(void) { uint8_t cmd = 0; TCS34725_Read(TCS34725_ENABLE, &cmd, 1); cmd = cmd & ~(TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN); TCS34725_Write(TCS34725_ENABLE, &cmd, 1); } /******************************************************************************* * @brief TCS34725初始化 * * @return ID - ID寄存器中的值 *******************************************************************************/ uint8_t TCS34725_Init(void) { uint8_t id=0; //TCS34725_I2C_Init(); TCS34725_Read(TCS34725_ID, &id, 1); //TCS34725 的 ID 是 0x44 可以根据这个来判断是否成功连接 if(id==0x44) { TCS34725_SetIntegrationTime(TCS34725_INTEGRATIONTIME_240MS); TCS34725_SetGain(TCS34725_GAIN_1X); TCS34725_Enable(); return 1; } return 0; } /******************************************************************************* * @brief TCS34725获取单个通道数据 * * @return data - 该通道的转换值 *******************************************************************************/ uint16_t TCS34725_GetChannelData(uint8_t reg) { uint8_t tmp[2] = {0,0}; uint16_t data; TCS34725_Read(reg, tmp, 2); data = (tmp[1] rgbc->c = TCS34725_GetChannelData(TCS34725_CDATAL); rgbc->r = TCS34725_GetChannelData(TCS34725_RDATAL); rgbc->g = TCS34725_GetChannelData(TCS34725_GDATAL); rgbc->b = TCS34725_GetChannelData(TCS34725_BDATAL); return 1; } return 0; }

到这里TSC34725的驱动程序就完成了,这里读出来的数据是未处理的数据,如果要转化成能使用的RGB转化一下即可。



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭