项目介绍
项目功能介绍
本项目实现了通过板上集成的环境亮度传感器,与屏幕搭配实现亮度测量与控制,并能够根据当前亮度,并依照人眼对亮度的感知曲线,自动调整屏幕亮度。
设计思路
该项目主要有三部分组成:
- 环境光采集部分:用于采集外部环境亮度,并处理该数据得到有效亮度,使用模拟IIC进行驱动,移植方便,驱动简单。
- 屏幕显示部分:用于显示采集到的亮度值,由于本次任务对显示画面没要求,只需简单显示个白色背景(便于观察背光亮度)以及采集到的光照强度即可,所以使用模拟SPI进行驱动。
- PWM背光控制:用于控制背光pwm输出,控制屏幕亮度,为减少代码处理的麻烦程度,这里使用硬件pwm进行驱动。
本次题目核心就是实现上面的三个驱动,此外就是实现采集数据与显示亮度的一个对应关系,首先要了解一个事情,就是光照传感器可以采集到一个很强亮度的数值,但屏幕亮度不可能达到那个地步(屏幕背光没有这么强),因此不可能使用光照传感器采集的最大数值与屏幕最大亮度相对应,现实中,手机对背光的处理就是在一定地步达到最高就行,也就是根据人眼对光照强度的感知进行一个换算关系,得到一个较好的变化就行,此外由于亮度传感器可能采集到光照强度为0的数值,但如果背光为0就完全看不到了,所以代码中我设置了亮度的最小值,防止出现上面的问题。
硬件框图
软件流程图
硬件介绍
RT1021核心板
RT1021核心板是基于恩智浦i.MX RT1020系列MIMXRT1021CAG4A芯片设计的综合开发板,i.MX RT1020跨界MCU基于Arm®Cortex®-M7内核,运行频率高达500MHz,内置256KB片上RAM,该MCU系列提供各种存储器接口和丰富的连接接口,包括UART、SPI、I2C、USB、10/100M以太网和CAN,具有实时性能和高集成功能,该适用于工业和物联网应用。
本次活动采用的是144pin脚的MIMXRT1021DAG5A芯片,外扩8MB FLASH用于存储程序,核心板上集成了四个按键,一个电源指示灯,一个用户LED灯,两组2x20 Pin的排针将调试接口和可用IO口基本全部引出。核心板采用TYPE-C接口进行供电和数据传输,此外该接口还支持480M高速通信模式。核心板卡上预留有Micro SD卡槽,可用作数据存储与回放。
扩展板
扩展板依据MCU丰富的引脚资源,搭配了多种类型的传感器和输入输出外设,包括温湿度传感器、三轴磁场传感器、加速度角速度传感器、环境光传感器,一个RGB彩灯、一块128*160分辨率的电阻式触摸屏,一个旋钮,一个双轴电位计摇杆。将调试和一组UART接口引出,可使用搭配的DAPlink进行调试和通信。
搭载传感器:
- NSHT30温湿度传感器
- LSM6DS3TR-C加速度角速度传感器
- LIS2MDL三轴磁力传感器
- BH1730FVC-TR环境光传感器
实现的功能及图片展示
高亮度模式
低亮度模式
主要代码片段及说明
光照传感器部分
void Multiple_read_BH1730(void)
{
uint8_t i;
MyI2C_Start(); //起始信号
MyI2C_SendByte(SlaveAddress+1); //发送设备地址+读信号
MyI2C_ReceiveAck();
for(i=0; i<3; i++) //连续读取2个地址数据,存储中BUF
{
BH1730_BUF[i] = MyI2C_ReceiveByte(); //BUF[0]存储0x32地址中的数据
if (i == 2)
{
MyI2C_SendAck(1); //最后一个数据需要回NOACK
}
else
{
MyI2C_SendAck(0); //回应ACK
}
}
MyI2C_Stop(); //停止信号
SysTick_DelayTicks(5);//Delay_ms(5);
}
void BH1730_init(void)
{
MyI2C_Init();
BH1730_BUF[0] = 0;
Single_Write_BH1730(0x80+0x12);
MyI2C_Start(); //起始信号
MyI2C_SendByte(SlaveAddress+1); //发送设备地址+读信号
MyI2C_ReceiveAck();
BH1730_BUF[0] = MyI2C_ReceiveByte(); //BUF[0]存储0x32地址中的数据
MyI2C_SendAck(1); //最后一个数据需要回NOACK
MyI2C_Stop(); //停止信号
PRINTF("ID:%02X",BH1730_BUF[0]);
SysTick_DelayTicks(5);//Delay_ms(5);
Single_Write_BH1730(0x80+0x00);
Single_Write_BH1730(0x07);
SysTick_DelayTicks(10);//Delay_ms(5);
}
uint16_t BH1730_ReadData(void)
{
uint16_t dis_data;
Single_Write_BH1730(0x80+0x14);
Multiple_read_BH1730(); //连续读出数据,存储在BUF中
dis_data=BH1730_BUF[1];
dis_data=(dis_data<<8)+BH1730_BUF[0];//合成数据,即光照数据
return dis_data;
}
LCD初始化
void LCD_init()
{
// LCD_BL_H;
LCD_RES_H;
SysTick_DelayTicks(1); // Delay 1ms
LCD_RES_L;
SysTick_DelayTicks(10); // Delay 10ms // This delay time is
LCD_RES_H;
SysTick_DelayTicks(120); // Delay 50 ms
LCD_WriteCommand(0x11); //Sleep out
SysTick_DelayTicks(120); //Delay 120ms
//------------------------------------ST7735S Frame Rate-----------------------------------------//
LCD_WriteCommand(0xB1);
LCD_WriteData(0x05);
LCD_WriteData(0x3C);
LCD_WriteData(0x3C);
LCD_WriteCommand(0xB2);
LCD_WriteData(0x05);
LCD_WriteData(0x3C);
LCD_WriteData(0x3C);
LCD_WriteCommand(0xB3);
LCD_WriteData(0x05);
LCD_WriteData(0x3C);
LCD_WriteData(0x3C);
LCD_WriteData(0x05);
LCD_WriteData(0x3C);
LCD_WriteData(0x3C);
//------------------------------------End ST7735S Frame Rate---------------------------------//
LCD_WriteCommand(0xB4); //Dot inversion
LCD_WriteData(0x03);
//------------------------------------ST7735S Power Sequence---------------------------------//
LCD_WriteCommand(0xC0);
LCD_WriteData(0x28);
LCD_WriteData(0x08);
LCD_WriteData(0x04);
LCD_WriteCommand(0xC1);
LCD_WriteData(0XC0);
LCD_WriteCommand(0xC2);
LCD_WriteData(0x0D);
LCD_WriteData(0x00);
LCD_WriteCommand(0xC3);
LCD_WriteData(0x8D);
LCD_WriteData(0x2A);
LCD_WriteCommand(0xC4);
LCD_WriteData(0x8D);
LCD_WriteData(0xEE);
//---------------------------------End ST7735S Power Sequence-------------------------------------//
LCD_WriteCommand(0xC5); //VCOM
LCD_WriteData(0x18); //1a
LCD_WriteCommand(0x36); //MX, MY, RGB mode
LCD_WriteData(0xC0);
//------------------------------------ST7735S Gamma Sequence---------------------------------//
LCD_WriteCommand(0xE0);
LCD_WriteData(0x04);
LCD_WriteData(0x22);
LCD_WriteData(0x07);
LCD_WriteData(0x0A);
LCD_WriteData(0x2E);
LCD_WriteData(0x30);
LCD_WriteData(0x25);
LCD_WriteData(0x2A);
LCD_WriteData(0x28);
LCD_WriteData(0x26);
LCD_WriteData(0x2E);
LCD_WriteData(0x3A);
LCD_WriteData(0x00);
LCD_WriteData(0x01);
LCD_WriteData(0x03);
LCD_WriteData(0x13);
LCD_WriteCommand(0xE1);
LCD_WriteData(0x04);
LCD_WriteData(0x16);
LCD_WriteData(0x06);
LCD_WriteData(0x0D);
LCD_WriteData(0x2D);
LCD_WriteData(0x26);
LCD_WriteData(0x23);
LCD_WriteData(0x27);
LCD_WriteData(0x27);
LCD_WriteData(0x25);
LCD_WriteData(0x2D);
LCD_WriteData(0x3B);
LCD_WriteData(0x00);
LCD_WriteData(0x01);
LCD_WriteData(0x04);
LCD_WriteData(0x13);
//------------------------------------End ST7735S Gamma Sequence-----------------------------//
LCD_WriteCommand(0x3A); //65k mode
LCD_WriteData(0x05);
LCD_WriteCommand(0x29); //Display on
}
主代码
int main(void)
{
char ch;
/* Init board hardware. */
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
XBARA_Init(XBARA);
/* 设置 pwm错误输入为高电平,表示没有错误 */
XBARA_SetSignalsConnection(XBARA, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm2Fault0);
XBARA_SetSignalsConnection(XBARA, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm2Fault1);
XBARA_SetSignalsConnection(XBARA, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm12Fault2);
XBARA_SetSignalsConnection(XBARA, kXBARA1_InputLogicHigh, kXBARA1_OutputFlexpwm12Fault3);
BOARD_InitBootPeripherals();
BOARD_InitDebugConsole();
SystemCoreClockUpdate();
CLOCK_EnableClock(kCLOCK_Trace);
if (SysTick_Config(SystemCoreClock / 1000U))
{
while (1)
{
}
}
LCD_init();
BH1730_init();
LCD_Fill(0,0,128,160,WHITE);
while (1)
{
uint8_t pwmVal;
uint16_t brightness;
brightness = BH1730_ReadData();
LCD_ShowIntNum(10,100,pwmVal,5,RED,WHITE,24);
if (brightness > 100)
pwmVal = 100;
else if (brightness <= 0)
pwmVal = 1;
else
pwmVal = brightness;
PWM_UpdatePwmDutycycle(PWM2, kPWM_Module_2, kPWM_PwmB, kPWM_SignedCenterAligned, pwmVal);
PWM_SetPwmLdok(PWM2, kPWM_Control_Module_2, true);
SysTick_DelayTicks(10);
}
}
遇到的主要难题及解决方法
问题:十二指神探DAP无法在keil环境下使用。
办法:使用ISP下载。
未来的计划或建议
建议优化十二指神探DAP,兼容全部环境使用。