STM32模拟I2C获取TCS34725光学颜色传感器数据
TCS34725是RGB三色颜色传感器,和TCS34727都属于TCS3472系列,在电气特性上略有差别,TCS34727相比TCS34725在I2C总线的访问电平上可以更低,而在I2C软件访问地址方面则一致。
TCS3472内部有4个PD(光电二极管),一个接收clear light(净光,未做任何处理),另外三个分别接收Red, Green, Blue的三色光,并且会滤除红外光。
TCS3472访问特征
- TCS34725和TCS34727软件方面在Device ID不同(非I2C访问地址),其它方面则相同。
- TCS3472在做寄存器访问时,5位寄存器地址在命令字节里发布:
而在进行有效的命令字节发布时,这个字节最高位要求为1。而命令字节的TYPE则是访问过程的功能指定,为00时说明后面按byte直接访问寄存器,为01则说明后面按照byte连续操作方式操作寄存器(连读),这个时候有个影子寄存器的功能,保证对于两个字节的数据读取,前一个字节读的时候后一个字节被保护,避免前一个字节读完要读后一个字节前,后一个寄存器的数据被新的数据过来改写了,从而产生不一致。10为保留无功能。11则为特殊功能指定,在原本指定地址的位置,可以设置具体的特殊功能,当前只有00110一个功能。
3 通过使能AEN位可以启动光学颜色检测,而WEN位用于控制运行模式,WEN设置为0,则光学检测是循环无间断进行,前一次检测出来马上进行下一次检测(每次检测占用一定的延时);当WEN设置为1,则两次检测之间可以插入等待时间,起到节省功耗的作用。AIEN位则是控制是否使用门限可设置的中断产生。
4. TCS3472的输出寄存器是16位,采用可控制积分时间和放大增益的方式,所以得到的结果可以大于255,更长的积分时间和放大增益用于距离较远或者弱光环境的测试。
积分时间为2.4ms相当于进行了10次ADC采样值的求和。
有4级接收光强放大可选,分别为1倍,4倍,16倍和60倍。
STM32工程配置
这里以STM32F103C6T6芯片及STM32CUBEIDE开发环境,实现访问获取TCS34725传感器的数据。
首先建立工程并配置时钟:
配置PB12和PB13作为模拟I2C的管脚:
采用USB虚拟串口作为输出方式,配置USB虚拟串口:
保存并生成基础工程代码:
STM32模拟I2C协议代码
STM32模拟I2C协议代码需要用到微秒延时函数,这里采用 STM32 HAL us delay(微秒延时)的指令延时实现方式及优化 。
TCS3472访问部分的函数为:
#define us_num 50
#define SCL_OUT_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET)
#define SCL_OUT_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET)
#define SDA_OUT_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET)
#define SDA_OUT_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET)
#define SDA_IN HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13)
void I2C_Init(void)
{
SDA_OUT_H;
SCL_OUT_H;
PY_Delay_us_t(1000000) ;
}
void I2C_Start(void)
{
PY_Delay_us_t(us_num) ;
SDA_OUT_H;
SCL_OUT_H;
PY_Delay_us_t(us_num/2) ;
SDA_OUT_L;
PY_Delay_us_t(us_num/2) ;
SCL_OUT_L;
}
void I2C_Stop(void)
{
SCL_OUT_L;
PY_Delay_us_t(us_num) ;
SDA_OUT_L;
PY_Delay_us_t(us_num) ;
SCL_OUT_H;
PY_Delay_us_t(us_num) ;
SDA_OUT_H;
PY_Delay_us_t(us_num) ;
}
void I2C_Write_Ack(void)
{
PY_Delay_us_t(us_num/2) ;
SDA_OUT_L;
PY_Delay_us_t(us_num/2) ;
SCL_OUT_H;
PY_Delay_us_t(us_num) ;
SCL_OUT_L;
SDA_OUT_H;
}
uint8_t I2C_Read_Ack(void)
{
uint8_t status=0;
SCL_OUT_L;
PY_Delay_us_t(us_num/2) ;
SDA_OUT_H;
PY_Delay_us_t(us_num/2) ;
status = SDA_IN;
SCL_OUT_H;
PY_Delay_us_t(us_num) ;
SCL_OUT_L;
SDA_OUT_L;
return status;
}
void I2C_Send_Byte(uint8_t txd)
{
for(uint8_t i=0;i<8;i++)
{
PY_Delay_us_t(us_num/2) ;
if((txd&0x80)>>7) SDA_OUT_H;
else SDA_OUT_L;
txd<<=1;
PY_Delay_us_t(us_num/2) ;
SCL_OUT_H;
PY_Delay_us_t(us_num) ;
SCL_OUT_L;
}
SDA_OUT_L;
}
uint8_t I2C_Read_Byte(unsigned char rdack)
{
uint8_t rxd=0;
for(uint8_t i=0;i<8;i++ )
{
SCL_OUT_L;
PY_Delay_us_t(us_num/2) ;
SDA_OUT_H;
PY_Delay_us_t(us_num/2) ;
SCL_OUT_H;
rxd<<=1;
if(SDA_IN) rxd++;
PY_Delay_us_t(us_num) ;
}
SCL_OUT_L;
SDA_OUT_H;
if (rdack) I2C_Write_Ack();
return rxd;
}
uint8_t TCS3472_Enable_Status = 0;
void TCS3472_WRITE( uint8_t WrAddr, uint8_t data)
{
uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)
I2C_Start();
I2C_Send_Byte(daddr);
I2C_Read_Ack();
I2C_Send_Byte(WrAddr|0x80);
I2C_Read_Ack();
I2C_Send_Byte(data);
I2C_Read_Ack();
I2C_Stop();
}
uint8_t TCS3472_READ_1Byte( uint8_t RdAddr)
{
uint8_t RegValue = 0;
uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)
I2C_Start();
I2C_Send_Byte(daddr);
I2C_Read_Ack();
I2C_Send_Byte(RdAddr|0x80); //Repeated byte protocol transaction
I2C_Read_Ack();
I2C_Start();
I2C_Send_Byte(daddr+1);
I2C_Read_Ack();
RegValue=I2C_Read_Byte(0);
I2C_Stop();
return RegValue;
}
uint16_t TCS3472_READ_2Byte( uint8_t RdAddr)
{
uint8_t RegValueH = 0, RegValueL = 0;
uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)
I2C_Start();
I2C_Send_Byte(daddr);
I2C_Read_Ack();
I2C_Send_Byte(RdAddr|0xa0); //Auto-increment protocol transaction
I2C_Read_Ack();
I2C_Start();
I2C_Send_Byte(daddr+1);
I2C_Read_Ack();
RegValueL=I2C_Read_Byte(1);
RegValueH=I2C_Read_Byte(0);
I2C_Stop();
return (((uint16_t)RegValueH)<<8)|RegValueL;
}
void TCS3472_PON_Enable(void)
{
TCS3472_Enable_Status |= TCS3472_ENABLE_PON;
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_PON_Disable(void)
{
TCS3472_Enable_Status &= (~TCS3472_ENABLE_PON);
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_AEN_Enable(void)
{
TCS3472_Enable_Status |= TCS3472_ENABLE_AEN;
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_AEN_Disable(void)
{
TCS3472_Enable_Status &= (~TCS3472_ENABLE_AEN);
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_WEN_Enable(void)
{
TCS3472_Enable_Status |= TCS3472_ENABLE_WEN;
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_WEN_Disable(void)
{
TCS3472_Enable_Status &= (~TCS3472_ENABLE_WEN);
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_AIEN_Enable(void)
{
TCS3472_Enable_Status |= TCS3472_ENABLE_AIEN;
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_AIEN_Disable(void)
{
TCS3472_Enable_Status &= (~TCS3472_ENABLE_AIEN);
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
uint8_t TCS3472_ID_Verification(void)
{
uint8_t id;
id = TCS3472_READ_1Byte(TCS3472_ID);
if((id==0x44)||(id==0x4d)) return 1;
else return 0;
}
COLOR_RGBC rgb;
COLOR_HSL hsl;
//Conversion of RGB to HSL
void RGBtoHSL(COLOR_RGBC *Rgb, COLOR_HSL *Hsl)
{
uint8_t maxVal,minVal,difVal;
uint8_t r = Rgb->r*100/Rgb->c; //[0-100]
uint8_t g = Rgb->g*100/Rgb->c;
uint8_t b = Rgb->b*100/Rgb->c;
maxVal = max3v(r,g,b);
minVal = min3v(r,g,b);
difVal = maxVal-minVal;
//Lightness
Hsl->l = (maxVal+minVal)/2; //[0-100]
if(maxVal == minVal)//if r=g=b, grey
{
Hsl->h = 0;
Hsl->s = 0;
}
else
{
//Hue
if(maxVal==r)
{
if(g>=b)
Hsl->h = 60*(g-b)/difVal;
else
Hsl->h = 60*(g-b)/difVal+360;
}
else
{
if(maxVal==g)Hsl->h = 60*(b-r)/difVal+120;
else
if(maxVal==b)Hsl->h = 60*(r-g)/difVal+240;
}
//Saturation
if(Hsl->l<=50)Hsl->s=difVal*100/(maxVal+minVal); //[0-100]
else
Hsl->s=difVal*100/(200-(maxVal+minVal));
}
}
STM32完整工程代码
完整工程代码先读取Device ID以判断基本访问是否正常,再进行积分时间24ms及增益1x的配置,再开始数据采样和读取,读取到的数据是积分后的数据,并进行HSL格式的转换。通过USB虚拟串口将数据打印输出。
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
//Written by Pegasus Yu in 2022
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usb_device.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <math.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
__IO float usDelayBase;
void PY_usDelayTest(void)
{
__IO uint32_t firstms, secondms;
__IO uint32_t counter = 0;
firstms = HAL_GetTick()+1;
secondms = firstms+1;
while(uwTick!=firstms) ;
while(uwTick!=secondms) counter++;
usDelayBase = ((float)counter)/1000;
}
void PY_Delay_us_t(uint32_t Delay)
{
__IO uint32_t delayReg;
__IO uint32_t usNum = (uint32_t)(Delay*usDelayBase);
delayReg = 0;
while(delayReg!=usNum) delayReg++;
}
void PY_usDelayOptimize(void)
{
__IO uint32_t firstms, secondms;
__IO float coe = 1.0;
firstms = HAL_GetTick();
PY_Delay_us_t(1000000) ;
secondms = HAL_GetTick();
coe = ((float)1000)/(secondms-firstms);
usDelayBase = coe*usDelayBase;
}
void PY_Delay_us(uint32_t Delay)
{
__IO uint32_t delayReg;
__IO uint32_t msNum = Delay/1000;
__IO uint32_t usNum = (uint32_t)((Delay%1000)*usDelayBase);
if(msNum>0) HAL_Delay(msNum);
delayReg = 0;
while(delayReg!=usNum) delayReg++;
}
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define us_num 50
#define SCL_OUT_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET)
#define SCL_OUT_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET)
#define SDA_OUT_H HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET)
#define SDA_OUT_L HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET)
#define SDA_IN HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13)
void I2C_Init(void)
{
SDA_OUT_H;
SCL_OUT_H;
PY_Delay_us_t(1000000) ;
}
void I2C_Start(void)
{
PY_Delay_us_t(us_num) ;
SDA_OUT_H;
SCL_OUT_H;
PY_Delay_us_t(us_num/2) ;
SDA_OUT_L;
PY_Delay_us_t(us_num/2) ;
SCL_OUT_L;
}
void I2C_Stop(void)
{
SCL_OUT_L;
PY_Delay_us_t(us_num) ;
SDA_OUT_L;
PY_Delay_us_t(us_num) ;
SCL_OUT_H;
PY_Delay_us_t(us_num) ;
SDA_OUT_H;
PY_Delay_us_t(us_num) ;
}
void I2C_Write_Ack(void)
{
PY_Delay_us_t(us_num/2) ;
SDA_OUT_L;
PY_Delay_us_t(us_num/2) ;
SCL_OUT_H;
PY_Delay_us_t(us_num) ;
SCL_OUT_L;
SDA_OUT_H;
}
uint8_t I2C_Read_Ack(void)
{
uint8_t status=0;
SCL_OUT_L;
PY_Delay_us_t(us_num/2) ;
SDA_OUT_H;
PY_Delay_us_t(us_num/2) ;
status = SDA_IN;
SCL_OUT_H;
PY_Delay_us_t(us_num) ;
SCL_OUT_L;
SDA_OUT_L;
return status;
}
void I2C_Send_Byte(uint8_t txd)
{
for(uint8_t i=0;i<8;i++)
{
PY_Delay_us_t(us_num/2) ;
if((txd&0x80)>>7) SDA_OUT_H;
else SDA_OUT_L;
txd<<=1;
PY_Delay_us_t(us_num/2) ;
SCL_OUT_H;
PY_Delay_us_t(us_num) ;
SCL_OUT_L;
}
SDA_OUT_L;
}
uint8_t I2C_Read_Byte(unsigned char rdack)
{
uint8_t rxd=0;
for(uint8_t i=0;i<8;i++ )
{
SCL_OUT_L;
PY_Delay_us_t(us_num/2) ;
SDA_OUT_H;
PY_Delay_us_t(us_num/2) ;
SCL_OUT_H;
rxd<<=1;
if(SDA_IN) rxd++;
PY_Delay_us_t(us_num) ;
}
SCL_OUT_L;
SDA_OUT_H;
if (rdack) I2C_Write_Ack();
return rxd;
}
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
uint8_t TCS3472_Enable_Status = 0;
void TCS3472_WRITE( uint8_t WrAddr, uint8_t data)
{
uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)
I2C_Start();
I2C_Send_Byte(daddr);
I2C_Read_Ack();
I2C_Send_Byte(WrAddr|0x80);
I2C_Read_Ack();
I2C_Send_Byte(data);
I2C_Read_Ack();
I2C_Stop();
}
uint8_t TCS3472_READ_1Byte( uint8_t RdAddr)
{
uint8_t RegValue = 0;
uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)
I2C_Start();
I2C_Send_Byte(daddr);
I2C_Read_Ack();
I2C_Send_Byte(RdAddr|0x80); //Repeated byte protocol transaction
I2C_Read_Ack();
I2C_Start();
I2C_Send_Byte(daddr+1);
I2C_Read_Ack();
RegValue=I2C_Read_Byte(0);
I2C_Stop();
return RegValue;
}
uint16_t TCS3472_READ_2Byte( uint8_t RdAddr)
{
uint8_t RegValueH = 0, RegValueL = 0;
uint8_t daddr = 0x52; //TCS3472 device address (0x29<<1)
I2C_Start();
I2C_Send_Byte(daddr);
I2C_Read_Ack();
I2C_Send_Byte(RdAddr|0xa0); //Auto-increment protocol transaction
I2C_Read_Ack();
I2C_Start();
I2C_Send_Byte(daddr+1);
I2C_Read_Ack();
RegValueL=I2C_Read_Byte(1);
RegValueH=I2C_Read_Byte(0);
I2C_Stop();
return (((uint16_t)RegValueH)<<8)|RegValueL;
}
void TCS3472_PON_Enable(void)
{
TCS3472_Enable_Status |= TCS3472_ENABLE_PON;
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_PON_Disable(void)
{
TCS3472_Enable_Status &= (~TCS3472_ENABLE_PON);
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_AEN_Enable(void)
{
TCS3472_Enable_Status |= TCS3472_ENABLE_AEN;
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_AEN_Disable(void)
{
TCS3472_Enable_Status &= (~TCS3472_ENABLE_AEN);
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_WEN_Enable(void)
{
TCS3472_Enable_Status |= TCS3472_ENABLE_WEN;
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_WEN_Disable(void)
{
TCS3472_Enable_Status &= (~TCS3472_ENABLE_WEN);
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_AIEN_Enable(void)
{
TCS3472_Enable_Status |= TCS3472_ENABLE_AIEN;
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
void TCS3472_AIEN_Disable(void)
{
TCS3472_Enable_Status &= (~TCS3472_ENABLE_AIEN);
TCS3472_WRITE(TCS3472_ENABLE, TCS3472_Enable_Status);
}
uint8_t TCS3472_ID_Verification(void)
{
uint8_t id;
id = TCS3472_READ_1Byte(TCS3472_ID);
if((id==0x44)||(id==0x4d)) return 1;
else return 0;
}
COLOR_RGBC rgb;
COLOR_HSL hsl;
//Conversion of RGB to HSL
void RGBtoHSL(COLOR_RGBC *Rgb, COLOR_HSL *Hsl)
{
uint8_t maxVal,minVal,difVal;
uint8_t r = Rgb->r*100/Rgb->c; //[0-100]
uint8_t g = Rgb->g*100/Rgb->c;
uint8_t b = Rgb->b*100/Rgb->c;
maxVal = max3v(r,g,b);
minVal = min3v(r,g,b);
difVal = maxVal-minVal;
//Lightness
Hsl->l = (maxVal+minVal)/2; //[0-100]
if(maxVal == minVal)//if r=g=b, grey
{
Hsl->h = 0;
Hsl->s = 0;
}
else
{
//Hue
if(maxVal==r)
{
if(g>=b)
Hsl->h = 60*(g-b)/difVal;
else
Hsl->h = 60*(g-b)/difVal+360;
}
else
{
if(maxVal==g)Hsl->h = 60*(b-r)/difVal+120;
else
if(maxVal==b)Hsl->h = 60*(r-g)/difVal+240;
}
//Saturation
if(Hsl->l<=50)Hsl->s=difVal*100/(maxVal+minVal); //[0-100]
else
Hsl->s=difVal*100/(200-(maxVal+minVal));
}
}
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
char PY_Str[512];
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USB_DEVICE_Init();
/* USER CODE BEGIN 2 */
PY_usDelayTest();
PY_usDelayOptimize();
if (!TCS3472_ID_Verification()) //For communication error verification
{
while(1)
{
CDC_Transmit_FS("ID READ ERROR!\r\n", strlen("ID READ ERROR!\r\n"));
PY_Delay_us(2000000);
}
}
else //Initial config
{
TCS3472_PON_Enable(); //Other register config must be after TCS3472_PON_Enable().
TCS3472_WRITE(TCS3472_ATIME, TCS3472_INTEGRATIONTIME_24MS);
TCS3472_WRITE(TCS3472_CONTROL, TCS3472_GAIN_1X);
TCS3472_AEN_Enable();
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(TCS3472_READ_1Byte(TCS3472_STATUS) & TCS3472_STATUS_AVALID)
{
(&rgb)->c = TCS3472_READ_2Byte(TCS3472_CDATAL);
(&rgb)->r = TCS3472_READ_2Byte(TCS3472_RDATAL);
(&rgb)->g = TCS3472_READ_2Byte(TCS3472_GDATAL);
(&rgb)->b = TCS3472_READ_2Byte(TCS3472_BDATAL);
sprintf( PY_Str, "Clear light value: %d\r\nRed light value: %d\r\nGreen light value: %d\r\nBlue light value: %d\r\n\r\n", (&rgb)->c, (&rgb)->r, (&rgb)->g, (&rgb)->b );
CDC_Transmit_FS(PY_Str, strlen(PY_Str));
PY_Delay_us(1000000);
RGBtoHSL(&rgb,&hsl);
sprintf( PY_Str, "Hue value: %d\r\nSaturation value: %d\r\nLightness value: %d\r\n\r\n", (&hsl)->h, (&hsl)->s, (&hsl)->l );
CDC_Transmit_FS(PY_Str, strlen(PY_Str));
PY_Delay_us(1000000);
}
else PY_Delay_us(1);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_13, GPIO_PIN_SET);
/*Configure GPIO pins : PB12 PB13 */
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
代码执行输出效果
代码执行输出效果如下:
例程下载
STM32F103C6T6获取TCS34725光学颜色传感器数据范例下载(STM32CUBEIDE工程):
可以调整光照强度,颜色物体厚度及背景反光情况进行效果优化。也可以将数据通过全彩显示屏显示以对比颜色及做校准,参考 STM32驱动0.96寸TFT 彩色LCD模块显示 。
–End –