|
|
楼主 |
发表于 2026-8-24 10:57:32
|
显示全部楼层
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/*---------------------------------------------------------------------*/
#include "STC32G.h"
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
#define MAIN_Fosc 22118400L
#define Baudrate2 (65536 - MAIN_Fosc / 115200 / 4)
#define UART2_BUF_LENGTH 128
/************* 本地变量声明 **************/
u8 TX2_Cnt;
u8 RX2_Cnt;
bit B_TX2_Busy;
u8 RX2_Buffer[UART2_BUF_LENGTH];
//OPT4048变量 全局edata,避免C172段溢出
unsigned int rawX,rawY,rawZ,rawW;
float cie_x,cie_y,lux,cct;
//======== OPT4048 I2C引脚 P2.4 SDA P2.5 SCL ========
sbit I2C_SDA = P2^4;
sbit I2C_SCL = P2^5;
#define OPT4048_ADDR 0x44
#define OPT4048_REG_RESULT0 0x00
#define OPT4048_REG_RESULT1 0x01
#define OPT4048_REG_RESULT2 0x02
#define OPT4048_REG_RESULT3 0x03
#define OPT4048_REG_CONFIG 0x04
#define CONV_TIME_100MS (0x0B << 4)
#define MODE_CONTINUOUS (0x02 << 1)
#define RANGE_0 (0x00 << 8) //满量程 440lux
/************* 本地函数声明 **************/
void UART2_config(u8 brt);
void PrintString2(u8 *puts);
void GPIO_I2C_Init(void);
void I2C_Delay(void);
void I2C_Start(void);
void I2C_Stop(void);
bit I2C_WriteByte(unsigned char dat);
unsigned char I2C_ReadByte(bit ack_en);
bit OPT4048_WriteReg(unsigned char reg, unsigned int val);
bit OPT4048_ReadXYZ(unsigned int *X, unsigned int *Y, unsigned int *Z, unsigned int *W);
bit OPT4048_Init(void);
void OPT4048_Calc(unsigned int rawX,unsigned int rawY,unsigned int rawZ,
float *out_x, float *out_y, float *out_lux, float *out_cct);
void UART2_SendFloat(float val, unsigned char dec);
void Delay_ms(unsigned int ms);
/******************** 主函数 **************************/
void main(void)
{
WTST = 0;
EAXFR = 1;
CKCON = 0;
P0M1 = 0x30; P0M0 = 0x30;
P1M1 = 0x30; P1M0 = 0x30;
P2M0 &= ~0x31; P2M1 &= ~0x31;
P3M1 = 0x50; P3M0 = 0x50;
P4M1 = 0x3c; P4M0 = 0x3c;
P5M1 = 0x0c; P5M0 = 0x0c;
P6M1 = 0xff; P6M0 = 0xff;
P7M1 = 0x00; P7M0 = 0x00;
GPIO_I2C_Init();
UART2_config(2);
EA = 1;
PrintString2((u8*)"OPT4048 ready, send any byte to trigger read!\r\n");
if(OPT4048_Init() != 0)
{
PrintString2((u8*)"OPT4048 init FAIL!\r\n");
while(1);
}
PrintString2((u8*)"OPT4048 init OK\r\n");
while (1)
{
if(RX2_Cnt != TX2_Cnt)
{
TX2_Cnt = RX2_Cnt;
//读取,失败重试一次
if(OPT4048_ReadXYZ(&rawX,&rawY,&rawZ,&rawW) != 0)
{
PrintString2((u8*)"I2C read error!\r\n");
}
// 如果全部为0,再等110ms重读一次
else if(rawX == 0 && rawY ==0 && rawZ ==0)
{
Delay_ms(110);
OPT4048_ReadXYZ(&rawX,&rawY,&rawZ,&rawW);
}
PrintString2((u8*)"--------DATA--------\r\n");
//打印原始寄存器值,方便定位
PrintString2((u8*)"RAW X,Y,Z,W:");
UART2_SendFloat((float)rawX,0); PrintString2((u8*)",");
UART2_SendFloat((float)rawY,0); PrintString2((u8*)",");
UART2_SendFloat((float)rawZ,0); PrintString2((u8*)",");
UART2_SendFloat((float)rawW,0); PrintString2((u8*)"\r\n");
OPT4048_Calc(rawX,rawY,rawZ,&cie_x,&cie_y,&lux,&cct);
PrintString2((u8*)"CIE-x:");
UART2_SendFloat(cie_x,4);
PrintString2((u8*)"\r\n");
PrintString2((u8*)"CIE-y:");
UART2_SendFloat(cie_y,4);
PrintString2((u8*)"\r\n");
PrintString2((u8*)"Lux(亮度):");
UART2_SendFloat(lux,2);
PrintString2((u8*)" lx\r\n");
PrintString2((u8*)"CCT(色温):");
UART2_SendFloat(cct,1);
PrintString2((u8*)" K\r\n");
PrintString2((u8*)"--------------------\r\n\r\n");
}
}
}
//========================================================================
// 函数: void PrintString2(u8 *puts) 原厂原样
//========================================================================
void PrintString2(u8 *puts)
{
for (; *puts != 0; puts++)
{
S2BUF = *puts;
B_TX2_Busy = 1;
while(B_TX2_Busy);
}
}
//========================================================================
// 函数: SetTimer2Baudraye(u32 dat) 原厂原样
//========================================================================
void SetTimer2Baudraye(u32 dat)
{
T2R = 0;
T2_CT = 0;
T2x12 = 1;
T2H = (u8)(dat / 256);
T2L = (u8)(dat % 256);
ET2 = 0;
T2R = 1;
}
//========================================================================
// 函数: void UART2_config(u8 brt) 原厂原样
//========================================================================
void UART2_config(u8 brt)
{
if(brt == 2)
{
SetTimer2Baudraye(Baudrate2);
S2CFG |= 0x01;
S2CON = (S2CON & 0x3f) | 0x40;
ES2 = 1;
S2REN = 1;
S2_S = 1; //UART2映射 P4.6(TX2), P4.7(RX2)
B_TX2_Busy = 0;
TX2_Cnt = 0;
RX2_Cnt = 0;
}
}
//========================================================================
// 函数: void UART2_int (void) interrupt UART2_VECTOR 原厂中断原样
//========================================================================
void UART2_int (void) interrupt 8
{
if(S2RI)
{
S2RI = 0;
RX2_Buffer[RX2_Cnt] = S2BUF;
if(++RX2_Cnt >= UART2_BUF_LENGTH) RX2_Cnt = 0;
}
if(S2TI)
{
S2TI = 0;
B_TX2_Busy = 0;
}
}
//==================== I2C OPT4048 部分 ====================
void GPIO_I2C_Init(void)
{
I2C_SDA = 1;
I2C_SCL = 1;
}
void I2C_Delay(void)
{
unsigned char i;
for(i = 0; i < 150; i++) _nop_();
}
void I2C_Start(void)
{
I2C_SDA = 1;
I2C_Delay();
I2C_SCL = 1;
I2C_Delay();
I2C_SDA= 0;
I2C_Delay();
I2C_SCL= 0;
I2C_Delay();
}
void I2C_Stop(void)
{
I2C_SDA = 0;
I2C_Delay();
I2C_SCL= 1;
I2C_Delay();
I2C_SDA = 1;
I2C_Delay();
}
bit I2C_WriteByte(unsigned char dat)
{
unsigned char i;
bit ack;
for(i = 0; i < 8; i++)
{
if(dat & 0x80) I2C_SDA = 1;
else I2C_SDA= 0;
dat <<= 1;
I2C_Delay();
I2C_SCL = 1;
I2C_Delay();
I2C_SCL = 0;
I2C_Delay();
}
I2C_SDA = 1;
I2C_Delay();
I2C_SCL = 1;
I2C_Delay();
ack = I2C_SDA;
I2C_SCL = 0;
return ack;
}
unsigned char I2C_ReadByte(bit ack_en)
{
unsigned char i, dat = 0;
I2C_SDA = 1;
for(i = 0; i < 8; i++)
{
dat <<= 1;
I2C_SCL = 1; I2C_Delay();
if(I2C_SDA) dat |= 0x01;
I2C_SCL = 0; I2C_Delay();
}
I2C_SDA = !ack_en;
I2C_Delay();
I2C_SCL = 1; I2C_Delay();
I2C_SCL = 0;
I2C_SDA = 1;
return dat;
}
bit OPT4048_WriteReg(unsigned char reg, unsigned int val)
{
I2C_Start();
if(I2C_WriteByte(OPT4048_ADDR << 1)) {I2C_Stop(); return 1;}
if(I2C_WriteByte(reg)) {I2C_Stop(); return 1;}
if(I2C_WriteByte((val >> 8) & 0xFF)){I2C_Stop(); return 1;}
if(I2C_WriteByte(val & 0xFF)) {I2C_Stop(); return 1;}
I2C_Stop();
return 0;
}
bit OPT4048_ReadXYZ(unsigned int *X, unsigned int *Y, unsigned int *Z, unsigned int *W)
{
I2C_Start();
if(I2C_WriteByte(OPT4048_ADDR << 1)) {I2C_Stop(); return 1;}
if(I2C_WriteByte(OPT4048_REG_RESULT0)) {I2C_Stop(); return 1;}
I2C_Start();
if(I2C_WriteByte((OPT4048_ADDR <<1)|0x01)) {I2C_Stop(); return 1;}
*X = (I2C_ReadByte(1) << 8) | I2C_ReadByte(1);
*Y = (I2C_ReadByte(1) << 8) | I2C_ReadByte(1);
*Z = (I2C_ReadByte(1) << 8) | I2C_ReadByte(1);
*W = (I2C_ReadByte(0) << 8) | I2C_ReadByte(0);
I2C_Stop();
return 0;
}
bit OPT4048_Init(void)
{
unsigned int cfg;
cfg = RANGE_0 | CONV_TIME_100MS | MODE_CONTINUOUS;
if(OPT4048_WriteReg(OPT4048_REG_CONFIG, cfg))
{
return 1;
}
// 关键!配置完成,等待第一次100ms转换完成
Delay_ms(120);
return 0;
}
void OPT4048_Calc(unsigned int rawX,unsigned int rawY,unsigned int rawZ,
float *out_x, float *out_y, float *out_lux, float *out_cct)
{
float X,Y,Z,sum,n;
X = (float)rawX;
Y = (float)rawY;
Z = (float)rawZ;
sum = X + Y + Z;
if(sum < 1.0f)
{
*out_x = 0.0f; *out_y =0.0f; *out_lux=0.0f; *out_cct=0.0f;
return;
}
*out_x = X / sum;
*out_y = Y / sum;
*out_lux = Y / 65535.0f * 144000.0f;
n = (*out_x - 0.3320f) / (0.1858f - *out_y);
*out_cct = -449.0f * n*n*n + 3525.0f * n*n - 6823.3f * n + 5520.33f;
if(*out_cct < 1000.0f) *out_cct = 1000.0f;
if(*out_cct > 10000.0f) *out_cct = 10000.0f;
}
//浮点数发送
void UART2_SendFloat(float val, unsigned char dec)
{
unsigned long int_part;
unsigned char i;
if(val < 0.0f)
{
S2BUF = '-'; B_TX2_Busy=1; while(B_TX2_Busy);
val = -val;
}
if(val > 4294967295.0f)
val = 4294967295.0f;
int_part = (unsigned long)(val + 0.0001f);
if(int_part == 0U)
{
S2BUF = '0'; B_TX2_Busy=1; while(B_TX2_Busy);
}
else
{
unsigned long temp = int_part;
unsigned char buf[12], p = 0U;
while(temp > 0U)
{
buf[p++] = (unsigned char)((temp % 10UL) + '0');
temp /= 10UL;
}
for(i = p; i > 0U; i--)
{
S2BUF = buf[i - 1U];
B_TX2_Busy = 1;
while(B_TX2_Busy);
}
}
S2BUF = '.'; B_TX2_Busy=1; while(B_TX2_Busy);
for(i = 0U; i < dec; i++)
{
val = (val - (float)int_part) * 10.0f;
int_part = (unsigned long)(val + 0.0001f);
S2BUF = (unsigned char)((int_part % 10UL) + '0');
B_TX2_Busy = 1;
while(B_TX2_Busy);
}
}
void Delay_ms(unsigned int ms)
{
unsigned int i,j;
for(i = ms; i>0; i--)
for(j = 360; j>0; j--);
}
|
|