[书房系统项目开发报告]硬件与控制部分
一、电路设计
1-1LED灯板
1-1-1LED灯板原理图
1-1-2LED灯板布线图
1-1-5LED灯板实物
1-1-4LED灯板技术分析
- 看到LED最大电流为150mA,
这是LED灯珠的电流,这通常是指LED灯珠的正向极限电流,指LED灯珠的正极接电源正极,负极接电源负极的极限电流(IF),现阶段大多在20MA以内。通常LED灯珠的光衰电流不能够大于IF2/3,大约在15MA到18MA。LED灯珠的发光强度仅仅在相应范围内与IF成正比,当IF>20MA时,亮度的增强已经不再规律了,所以LED灯珠的工作电流一般选在17—19MA左右比较合理
1-2、主控板
1-2-1、主控板实物图
- 第一代
- 第二代(修改了FB8013芯片外围电路+增加语音模块接口+复位电路)
1-2-1、主控板布线图
1-2-3、主控板原理图
1-2-3-1、主控板综述
1-2-4、DC-DC电源电路(Buck)
电路分析
-
从左到右分别是输入、接地和输出。另外,C11和C10为输出滤波电容,用于抑制自激振荡。如果这两个电容不接,线性稳压器的输出通常会是一个振荡波形。
-
C5和C8是输入电容。对于交流电压整流输入,它们的第一个作用是将单向脉动电压转换为直流电压。在这个图中,输入已经是+5V直流电源,它们的作用是防止断电后电压发生倒置,所以经常输入电容的容量要大于输出电容。
-
AMS1117系列稳压器提供可调和固定电压版本,旨在提供1A的输出电流和低至1V的压差。在最大输出电流下,AMS1117-3.3器件的压降保证不超过1.3V,并随着负载电流的减小而逐渐减小。
-
AMS1117-3.3的片上微调将参考电压调整到1.5%的误差范围内,并调整电流限制以最大限度地减少稳压器和电源电路过载造成的压力。
-
DCDC电源电路是一种在直流电路中将一个电压值的电能变为另一个电压值的电能的装置。它主要通过控制开关管的通断占空比,来实现输入输出电压的转换。
-
DCDC电源电路有多种拓扑结构,如降压型(Buck)、升压型(Boost)、反激型(Flyback)等
-
AMS1117-3.3是一种输出电压为3.3V的正向低压降稳压器,适用于高效率线性稳压器。它具有以下特点:
最大输出电流为1A
输出电压精度高达±2%
稳定工作电压范围为高达12V
电压线性度为0.2%
负载线性度为0.4%
AMS1117-3.3的封装有SOT-223、SOT-89和TO252等类型,本次工程选用SOT-223
1-2-5、TTL电路
电路分析
- CH340C芯片通过USB转换出来的TTL串口输出和输入电压是根据芯片供电电压是自适应的。也即,如果芯片是5V供电,那么串口输出和采样都是5V;如果是3.3V供电,那么标准就成了3.3V(本次工程采用5V标准)。
- 在实际使用的时候,串口连接到的对端设备需要注意电压匹配的问题。如果对端设备不支持5V或者3.3V的信号输入或输出,可能会造成设备损坏或者通信失败。
- CH340C模块测试时,首先把模块TX RX两个引脚短接,插到电脑USB口,打开串口调试工具,按照以上步骤操作即可。若能自收自发数据,说明这个USB转TTL模块是好的。
- CH340C模块插在USB2.0口时,5V排针输出口电流只有500MA左右。如果要接的功率比较大的模块建议接USB3.0或者给大功率模块单独外接电源且共地3。
- 经验
- 勿将VCC与GND短接,否则会烧坏模块。发现插上后模块灯不亮或者模块发烫严重请立即拔掉检测是否接反或者短路;
1-2-6、电源切换电路
- 电源切换电路是使用低阈值型的PMOS管作为开关,当外部5V电源接入时,PMOS管截止,输出为外部5V;
- 当外部5V断开时,PMOS管导通,输出为内部锂电池的3.7~4.2V。
- 这种电路简单、高效、可靠。
1-2-7、LED驱动电路
- FP8013是一颗同步降压LED驱动IC,内置60mΩ PMOS和NMOS,高效率可驱动单串白光LED,VFB反馈电压0.1V,让取样电阻功率损耗降低,整体转换效率提升,根据外部电阻设定LED电流;FP8013包含高低侧切换MOS,可实现高效率与简化周边元件及PCB Layout,为延长应用电池的寿命,低压差应用可支持100%占空比,内建软启动、过热保护与过电流保护功能,透过FB Pin实现直流与PWM调光控制,封装SOP-8L(EP)。
- 它广泛应用于手电筒、监控摄像头等领域。
PWM调光有以下优点
- 不会产生任何色谱偏移,因为LED始终工作在满幅度电流和0之间。
- 可以有极高的调光精确度,因为脉冲波形可以控制到很高的精度,甚至达到万分之一。
- 可以和数字控制技术相结合来进行控制,因为任何数字都可以很容易变换成为一个PWM信号。
- 即使在很大范围内调光,也不会发生闪烁现象,因为不会改变恒流源的工作条件(升压比或降压比),更不可能发生过热等问题。
PWM调光也有以下需要注意的问题:
- 脉冲频率的选择。因为LED是处于快速开关状态,如果工作频率很低,人眼就会感到闪烁。为了充分利用人眼的视觉残留现象,它的工作频率应当高于100Hz,最好为200Hz。
- 消除调光引起的噪声。虽然200Hz以上人眼无法察觉,但一直到20kHz却都是人耳听觉的范围。如果脉冲信号对周围设备产生干扰或者引起共振等现象,就会产生可听见的噪声。因此需要采取一些隔离或者滤波等措施来消除噪声。
1-2-8、波轮按键、电位器、蜂鸣器
- 波轮按键一个按钮实现三个按钮的功能,提高板载pcb空间利用率
- 电位器提供给esp32ADC引脚一个模拟输入,作为led驱动pwm的理想值
- 蜂鸣器作为信号提醒台灯前的学生,并且分别调试
1-2-9、IPS屏幕、TF卡座、环境光传感器
- IPS屏幕+LVGL嵌入式专用UI 带来良好的人机交互体验
- TF卡座扩展ESP32的存储空间,用于保存数据或文件,可透过屏幕显示,通过SPI或SDMMC接口与ESP32通信,提高数据传输速度,本项目采用速度较慢,但是占用引脚更少的SPI通信;
- 环境光传感器提高给单片机一个环境亮度亮度值,
- BH1750FVI-TR是一种环境光传感器,由ROHM(罗姆)公司生产,采用WSOF-6封装,支持I2C接口,可以测量16位的环境光强度。该传感器的工作电压为2.4V~3.6V,分辨率可调节为1、4、16或64 lx/ct
1-2-10、ESP32S主控
二、控制开发
2-1、LED工作逻辑部分 (状态机思想实现)
//状态机部分
/* 转换执行的外部函数声明 */
void Light_OFF(void)
{
ledcWrite(ledChannel, 0);
Serial.println("姿势不正确,关灯!");
}
void LED_adc_work(void)
{
Serial.println("PWM(变化):1-姿势正确");
dutyCycle_int= adc_button_filter();
ledcWrite(ledChannel, dutyCycle_int);
}
void LED_adc_keep(void){
Serial.println("PWM(锁定):");
dutyCycle_int_keep= adc_button_filter();
ledcWrite(ledChannel, dutyCycle_int_keep);
}
void Light_ON(void){
Serial.println("1-姿势正确");
}
/* 信号产生者 */
void Test_Flag_Process(void)
{
// static NF_Bool last_q_val = NF_Bool_False;
// static NF_Bool last_e_val = NF_Bool_False;
// NF_Bool then_q_val;
// NF_Bool then_e_val;
// then_q_val = KEY_VALUE('Q');
// then_e_val = KEY_VALUE('E');
/* people_flag事件处理 */
if (flag_0==0)
{
NF_FSM_Dispatch(&FSM_fsm, NF_FSM_Event("people_flag0"));
}
else if (flag_0==1)
{
NF_FSM_Dispatch(&FSM_fsm, NF_FSM_Event("people_flag1"));
}
/* Botton_flag事件处理 */
if (Flag_1_Judge() ==1)
{
NF_FSM_Dispatch(&FSM_fsm, NF_FSM_Event("Botton_flag1"));
}
else if (Flag_1_Judge() ==0)
{
NF_FSM_Dispatch(&FSM_fsm, NF_FSM_Event("Botton_flag0"));
}
// last_q_val = then_q_val;
// last_e_val = then_e_val;
}
2-2、ESP32连接网络、服务器
#include <HttpClient.h>
#include <wifi.h>
//UDP INT
Udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(Udp.remotePort());
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
setSyncInterval(100);
Serial.println(WiFi.localIP());
//UDP INT
Udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(Udp.remotePort());
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
setSyncInterval(100);
Serial.println(WiFi.localIP());//打印本机IP
Serial.println("Sending an HTTP GET request to the server");
client.get("/b"); // 发送GET请求
Serial.print("HTTP response status code: ");
Serial.println(client.responseStatusCode());
Serial.print("HTTP response body: ");
Serial.println(client.responseBody());
delay(5000); // 间隔5秒再次发送请求
2-3、ESP32连接阿里云服务器显示时间
//RTC
#include <WiFi.h>
#include <TimeLib.h>
#include <WiFiUdp.h>
#include <lvgl.h>
// NTP Servers:
static const char ntpServerName[] = "time1.aliyun.com";//阿里云的时间服务器
const int timeZone = 8; // 时区
WiFiUDP Udp;
unsigned int localPort = 8888; // local port to listen for UDP packets
void link_wifi(void);
void udp_int(void);
time_t getNtpTime();
char *num_week(uint8_t dayofweek,int Mode);//计算星期
void digitalClockDisplay();
void printDigits(int digits);
void sendNTPpacket(IPAddress &address);
void link_wifi(void)
{
//联网
WiFi.begin(ssid, pswd);
while (WiFi.status() != WL_CONNECTED) {
static int i = 0;
i++;
delay(500);
Serial.print(".");
if(i == 20) break;
}
}
void udp_int(void)
{
//UDP INT
Udp.begin(localPort);
Serial.print("Local port: ");
Serial.println(Udp.remotePort());
Serial.println("waiting for sync");
setSyncProvider(getNtpTime);
setSyncInterval(100);
}
/*
@功能:判断星期并赋值
*/
char week1[10],week2[8],week3[2],week4[4];
char *num_week(uint8_t dayofweek,int Mode){
switch(dayofweek)
{
case 1:
strcpy(week1,"Sunday");
strcpy(week2,"周日");
strcpy(week3,"Su");
strcpy(week4,"日");
break;
case 2:
strcpy(week1,"Monday");
strcpy(week2,"周一");
strcpy(week3,"Mo");
strcpy(week4,"一");
break;
case 3:
strcpy(week1,"Tuesday");
strcpy(week2,"周二");
strcpy(week3,"Tu");
strcpy(week4,"二");
break;
case 4:
strcpy(week1,"Wednesday");
strcpy(week2,"周三");
strcpy(week3,"We");
strcpy(week4,"三");
break;
case 5:
strcpy(week1,"Thursday");
strcpy(week2,"周四");
strcpy(week3,"Th");
strcpy(week4,"四");
break;
case 6:
strcpy(week1,"Friday");
strcpy(week2,"周五");
strcpy(week3,"Fr");
strcpy(week4,"五");
break;
case 7:
strcpy(week1,"Saturday");
strcpy(week2,"周六");
strcpy(week3,"Sa");
strcpy(week4,"六");
break;
default:
strcpy(week1,"NO");
strcpy(week2,"无");
strcpy(week3,"NO");
strcpy(week4,"无");
break;
}
switch(Mode)
{
case 1: return week1; break;
case 2: return week2; break;
case 3: return week3; break;
case 4: return week4; break;
default: return " "; break;
}
}
void digitalClockDisplay()
{
now();
printDigits(minute());
printDigits(second());
char timedate[128];
snprintf(date_str, DATE_LABEL_TEXT_LEN, "%04d-%02d-%02d", year(), month(), day());
lv_label_set_text(date_label, date_str);
snprintf(time_str, TIME_LABEL_TEXT_LEN, "%02d:%02d:%02d", hour(), minute(), second());
lv_label_set_text(time_label, time_str);
}
void printDigits(int digits)
{
// utility for digital clock display: prints preceding colon and leading 0
Serial.print(":");
if (digits < 10)
Serial.print('0');
Serial.print(digits);
}
2-4、滤波算法
- 电位器ADC读取值会在一定范围波动,故采用滤波算法
//-------------------------------------------------------------------------------------------------------------------
// 函数简介 ADC 均值滤波转换
// 参数说明 ch 选择
// 参数说明 count 均值滤波次数
// 返回参数 uint16 转换的 ADC 值
// 使用示例 adc_mean_filter_convert(ADC1_CH0_A0, 5); // 采集5次 然后返回平均值
// 备注信息
//-------------------------------------------------------------------------------------------------------------------
unsigned int adc_mean_filter_convert (unsigned int abc, unsigned int count)
{
unsigned int i;
unsigned int sum;
//zf_assert(count);// 断言次数不能为0
sum = 0;
for(i=0; i<count; i++)
{
sum += abc;
}
sum = sum/count;
return int(sum);
}
2-5、Lvgl嵌入式图像库ui设计
显示校徽及时间
void lv_ex_tabview_1(void)
{
//翻页
/*Create a Tab view object*/
// 创建选项卡视图对象
// 指向“已创建”选项卡的指针
tabview = lv_tabview_create(lv_scr_act(), NULL);///创建选项卡视图对象
/*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/
tab1 = lv_tabview_add_tab(tabview, "MEMU");
tab2 = lv_tabview_add_tab(tabview, "Time");
tab3 = lv_tabview_add_tab(tabview, "swjtu");
/*Add content to the tabs*/
label = lv_label_create(tab1, NULL);
lv_label_set_text(label, "This the first tab\n"
"If the content\n"
"of a tab\n");
#define DATE_LABEL_TEXT_LEN 20
#define TIME_LABEL_TEXT_LEN 20
// 创建主屏幕对象
lv_obj_t *scr = lv_scr_act();
// 创建日期标签对象
date_label = lv_label_create(tab2, NULL);
lv_label_set_text(date_label, "0000-00-00");
lv_obj_set_pos(date_label, 0, 0);
lv_obj_set_size(date_label, 135, 100);
lv_label_set_align(date_label, LV_LABEL_ALIGN_CENTER);
// 创建时间标签对象
time_label = lv_label_create(tab2, NULL);
lv_label_set_text(time_label, "00:00:00");
lv_obj_set_pos(time_label, 0, 100);
lv_obj_set_size(time_label, 135, 100);
lv_label_set_align(time_label, LV_LABEL_ALIGN_CENTER);
//-----------------------------------------------------------
//图片
lv_obj_t * img1 = lv_img_create(tab3, NULL);
lv_img_set_src(img1, &img_cogwheel_argb);
lv_obj_align(img1, NULL, LV_ALIGN_CENTER, 0, -20);
lv_obj_t * img2 = lv_img_create(tab3, NULL);
lv_img_set_src(img2, LV_SYMBOL_OK "Accept");
lv_obj_align(img2, img1, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
//按钮
lv_group_t * group = lv_group_create();
lv_group_add_obj(group, tabview);
}
2-6遇见的问题
报错1
src/main.cpp: In function 'void loop()':
src/main.cpp:158:9: error: 'HTTPClient' was not declared in this scope
HTTPClient http;
^~~~~~~~~~
src/main.cpp:158:9: note: suggested alternative: 'HttpClient'
HTTPClient http;
^~~~~~~~~~
HttpClient
src/main.cpp:163:9: error: 'http' was not declared in this scope
http.begin("https://4g526880v1.goho.co/b"); //HTTP
^~~~
src/main.cpp:175:28: error: 'HTTP_CODE_OK' was not declared in this scope
添加绝对路径后,此问题解决,出现以下问题,继续添加绝对路径
报错2
C:/Users/17752352458/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src/HTTPClient.cpp:1558:5: error: 'strptime' was not declared in this scope
C:/Users/17752352458/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src/HTTPClient.cpp:1673:24: error: 'time' was not declared in this scope
C:/Users/17752352458/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src/HTTPClient.cpp:1558:5: error: 'strptime' was not declared in this scope
HTTPClient.cpp的头文件,里面添加time.h头文件的绝对路径解决
报错3
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\src\main.cpp.o:(.literal._Z17Test_Flag_Processv+0x18): undefined reference to `NF_FSM_Event(char const*)'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\src\main.cpp.o:(.literal._Z17Test_Flag_Processv+0x1c): undefined reference to `NF_FSM_Dispatch(_nf_state_machine*, _nf_event)'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\src\main.cpp.o:(.literal._Z4loopv+0x0): undefined reference to `FSM_fsm_Light_mode_ON(_nf_state_machine*, _nf_event)'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\src\main.cpp.o:(.literal._Z4loopv+0x28): undefined reference to `NF_FSM_State(void (*)(_nf_state_machine*, _nf_event))'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\src\main.cpp.o:(.literal._Z4loopv+0x2c): undefined reference to `NF_FSM_Translate(_nf_state_machine*, _nf_state)'c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\src\main.cpp.o: in function `Test_Flag_Process()':
H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/src/main.cpp:170: undefined reference to `NF_FSM_Event(char const*)'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/src/main.cpp:170: undefined reference to `NF_FSM_Dispatch(_nf_state_machine*, _nf_event)'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/src/main.cpp:180: undefined reference to `NF_FSM_Event(char const*)'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/src/main.cpp:180: undefined reference to `NF_FSM_Dispatch(_nf_state_machine*, _nf_event)'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\src\main.cpp.o: in function `loop()':
H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/src/main.cpp:326: undefined reference to `NF_FSM_State(void (*)(_nf_state_machine*, _nf_event))'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/src/main.cpp:326: undefined reference to `NF_FSM_Translate(_nf_state_machine*, _nf_state)'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\lib0ce\libn_frame.a(fsm_fsm.c.o):(.literal.FSM_fsm_Light_mode_ON+0x10): undefined reference to `LED_adc_keep'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\lib0ce\libn_frame.a(fsm_fsm.c.o):(.literal.FSM_fsm_Light_mode_ON+0x14): undefined reference to `LED_adc_work'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\lib0ce\libn_frame.a(fsm_fsm.c.o):(.literal.FSM_fsm_Light_mode_ON+0x18): undefined reference to `Light_OFF'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\lib0ce\libn_frame.a(fsm_fsm.c.o):(.literal.FSM_fsm_Light_mode_OFF+0x4): undefined reference to `Light_ON'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\lib0ce\libn_frame.a(fsm_fsm.c.o): in function `FSM_fsm_Light_mode_ON':
H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/lib/n_frame/fsm_fsm.c:80: undefined reference to `LED_adc_keep'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/lib/n_frame/fsm_fsm.c:87: undefined reference to `LED_adc_work'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/lib/n_frame/fsm_fsm.c:94: undefined reference to `Light_OFF'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\lib0ce\libn_frame.a(fsm_fsm.c.o): in function `FSM_fsm_Light_mode_change':
H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/lib/n_frame/fsm_fsm.c:49: undefined reference to `Light_OFF'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/lib/n_frame/fsm_fsm.c:56: undefined reference to `LED_adc_keep'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\lib0ce\libn_frame.a(fsm_fsm.c.o): in function `FSM_fsm_Light_mode_OFF':
H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/lib/n_frame/fsm_fsm.c:68: undefined reference to `Light_ON'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: .pio\build\node32s\lib0ce\libn_frame.a(fsm_fsm.c.o): in function `FSM_fsm_Light_mode_keep':
H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/lib/n_frame/fsm_fsm.c:30: undefined reference to `LED_adc_work'
c:/users/17752352458/.platformio/packages/toolchain-xtensa-esp32@8.4.0+2021r2-patch5/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: H:\GeXingHuaLAB_TeacherPAN\ESP32_v2.x\ESP32_LVGL_V7.1.x/lib/n_frame/fsm_fsm.c:37: undefined reference to `Light_OFF'
collect2.exe: error: ld returned 1 exit status
*** [.pio\build\node32s\firmware.elf] Error 1
=========================================================== [FAILED] Took 15.37 seconds ===========================================================
在我插入状态机的.c.h文件后,并应用函数以后,出现不能正常编译,是因为
我是platformio+arduino+esp32编程,在fsm_fsm.c文件中写了extern void Light_OFF(void);,并且在fsm_fsm.c文件中有函数引用Light_OFF();但是我是在main.c中定义 void Light_OFF(void);并引用fsm_fsm.h,报错了
这个错误是链接器错误,意味着编译器找不到 'Light_OFF函数的定义。您需要确保在链接时将main.c中的Light_OFF函数与fsm_fsm.c中引用的函数连接起来。
可能的解决方案包括:
-
在 'main.c文件中定义Light_OFF函数的实现,以便编译器可以找到它的定义并将其与fsm_fsm.c中的函数引用连接起来。
-
确保 'main.c文件中包含了fsm_fsm.h头文件,这样编译器就知道函数Light_OFF的声明。
-
确保 'fsm_fsm文件中包含了fsm_fsm.h头文件,这样编译器就知道需要引用 'Light_OFFLight_OFF函数。
结果: 检查我的代码并尝试这些解决方案就解决链接错误(在.h文件中声明要在main.c文件中定义的函数)
结果: 其实我也尝试过这样声明,但是没有效果,是因为还有一个错误,就是我的状态机相关.c.h文件是C语言文件,而我用的编译环境是C++语言环境
- 参考
C++项目中的extern “C” {} https://www.cnblogs.com/skynet/archive/2010/07/10/1774964.html
在C++源文件中的语句前面加上extern “C”,表明它按照类C的编译和连接规约来编译和连接,而不是C++的编译的连接规约。这样在类C的代码中就可以调用C++的函数or变量等。(注:我在这里所说的类C,代表的是跟C语言的编译和连接方式一致的所有语言)
C语言代码头文件做如下改变,
#ifdef __cplusplus
extern "C" {
#endif
/*...*/
#ifdef __cplusplus
}
#endif
三、资料参考:
- 三种典型的基于AMS1117稳压IC的5v转3.3v电路https://www.eefocus.com/article/401372.html
- LED灯珠常见两大参数指标 https://www.sohu.com/a/594047621_121085916
- 5v稳压电源电路图大全(七款5v稳压电源电路设计原理图详解)https://www.elecfans.com/dianlutu/dianyuandianlu/20180227640046.html
- 外部电源和锂电池自动切换电路https://blog.csdn.net/k1ang/article/details/85332331
- 一种关于高精度PWM调光技术的应用研究https://xueshu.baidu.com/usercenter/paper/show?paperid=0b09ef584ae7b02b22113e61fdb29f66
- [1]周浩, 宫新保, 段士龙. 一种关于高精度PWM调光技术的应用研究[J]. 工程技术(文摘版).
- PWM调光非隔离降压型LED恒流驱动芯片https://www.erfang-ic.com/static/upload/BP2956.pdf
- 【高清网络监控摄像头IC方案】远翔LED驱动芯片FP8013XR-G1-供电2.5-5.5V 3A零压差降压恒流驱动芯片https://www.elecfans.com/s/comp-2697485-180309000297537970176.html
- ESP32 with BH1750 Ambient Light Sensorhttps://randomnerdtutorials.com/esp32-bh1750-ambient-light-sensor/
- NorthFrame 单片机极简图形化状态机框架https://gitee.com/PISCES_X/NorthFrame