项目名称 DSP2
基于STM32F407VE的一个桌面课程表的项目,啊也不算项目就是自己玩一玩
硬件设计
1) STM32F407VE 最小系统
2) GXHT30 温度采集
3) DS3231 RTC时间读取
4) AT24C02 EEPROM扩展
5) W25Q16 FLASH扩展
6) 板载ESP8266
7) 系统供电电压采集
8) 八位LCD屏幕
9) 板载无源蜂鸣器
10) 板载两路CAN接口
11) 板载SD卡卡槽
硬件项目如果想要的人多的话我会将工程文件上传到网盘,放在第二期的LVGL的学习笔记中
各部分硬件的软件驱动也写的差不多了,把LittleVGL学完之后就可以开始捋系统的逻辑了
本来LCD屏幕准备自己写UI的开始写了一会之后发现自己写的实在是太丑了,况且每个部件都得自己写一个函数,最后就想着用LittleVGL来实现DSP2的界面UI设计,这也就是学习LittleVGL的缘由
在移植LVGL的过程中发现自己的LCD是八位的导致肉眼还是可以看出来屏幕的刷新速度,虽然加了FSMC,所以就有了新的设计方案,在这备注以便后期设计参考
新的设计方案
1)加入SRAM将一部分内存分配到SRAM
2)换屏幕为16位接口加快刷新速度
3)加入I2S音频解码电路(不一定加入,感觉有用又没有用···)
4)由于32的高速时钟32本身就发热 虽然加入了两个1117一个用于STM32与LCD的供电一个用于ESP8266的供电但是1117本身就是一个LDO线性降压芯片所以不可避免的发出热量,然后还有ESP8266的无线通信导致ESP8266也散发出热量,所以拟在系统中加入一个可调速的小风扇,通过一个MOS加PWM实现风扇调速效果(不一定加因为这个热量好像不会影响系统的正常工作,因为后期项目PCB定型之后会通过光固化设计一个外壳,如果不加风扇,导致热量不能散发出去,影响系统正常工作也影响用户体验)
LittleVGL学习笔记(1)
以下是LittleVGL的学习笔记,前几节是记的手写笔记所以就不上传了(前几节主要讲的是LVGL的移植与PC端模拟器的使用,还有一个LVGL自带任务线程的API接口都可以看视频移植啥的,在这我就主要写一下LVGL的对象接口以便于以后查阅,如果代码或笔记有什么不妥之处,烦请私信告诉我)
这个代码是基于正点原子的官方视频边讲边学的,不得不说正点原子YYDS
先是此LittleVGL演示的样式结构图
/*
当前文件所完成的功能
1) 获取当前活跃的屏幕对象
2) 创建某个对象的子对象
3) 设置对象坐标
4) 设置对象大小
5) 设置对象样式
6) 设置按钮与其回调函数
7) 如何判断回调函数的触发与回调函数触发的条件
8) 更换某个对象的父对象
9) 更改某个对象的层级(也就是相对于Z轴的坐标大小)
10) 设置某个对象的对齐方式
11) 设置某个对象是否隐藏
12) 设置某个对象是否可以点击
13) 设置某个对象能否在某个方向被拖拽
14) 设置对象的透明度
*/
#include "DSP2_1.h"
lv_obj_t* Screen1;
lv_obj_t* LVbutton1;
lv_obj_t* LVobj1;
lv_obj_t* LVobj2;
lv_obj_t* LVobj3;
lv_style_t Child1Style;
lv_obj_t* Child1;
void test1_start(){
//获取当前活跃的屏幕对象
Screen1 = lv_scr_act();
//创建屏幕Screen1的子对象LVobj1
LVobj1 = lv_obj_create(Screen1,NULL);
//设置LVobj1的坐标
lv_obj_set_pos(LVobj1,50,50);
//使能LVobj1的点击功能(默认情况下基础对象的点击功能是没有被使能的)
lv_obj_set_click(LVobj1,true);
//设置LVobj1的点击回调函数
lv_obj_set_event_cb(LVobj1,LVobj1Click_Callback);
//创建第二个LVobj2以此体现不同对象的层级问题
//当然你也可以把某个对象放在层级的最前面官方给出的函数是lv_obj_set_top(lv_obj_t* obj,bool en)
//此处LVobj2的样式直接CopyLVobj1
//则这样创建的LVobj2的坐标是50*50
LVobj2 = lv_obj_create(Screen1,LVobj1);
//设置LVobj2的样式
lv_obj_set_style(LVobj2,&Child1Style);
lv_obj_set_pos(LVobj2,100,100);
//创建第三个LVobj3以此体现对象的对齐方式
//此处LVobj2的样式直接CopyLVobj1
//则这样创建的LVobj3的坐标是50*50
LVobj3 = lv_obj_create(Screen1,LVobj1);
//设置LVobj3的样式
lv_obj_set_style(LVobj3,&Child1Style);
//设置LVobj3的大小
lv_obj_set_size(LVobj3,30,30);
//设置LVobj3相对于LVobj2的位置(对齐方式)
//此种对齐方式以被对象左上角的坐标为参考点来对齐
lv_obj_align(LVobj3,LVobj2,LV_ALIGN_OUT_BOTTOM_MID,0,10);
//设置LVobj3相对于LVobj2的位置(对齐方式)
//此种对齐方式以被对齐对象的整体中点的坐标为参考点来对齐
//lv_obj_align_origo(LVobj3,LVobj2,LV_ALIGN_OUT_BOTTOM_LEFT,0,0);
//还有一种对齐方式叫重新对齐lv_obj_realign(lv_obj_t* obj)
//上面的这种对齐方式举个栗子你将一个现有文本居中对齐后来你又更改了文本内容导致文本长度发生变化使对象的居中对齐被破坏
//当你调用lv_obj_realign(lv_obj_t* obj)这个函数之后此文本又将被中心对齐
//若要使用上述重新对齐则需使能lv_conf.h中的LV_USE_OBJ_REALIGN宏
//觉得上述方法很麻烦?当然官方也提出了解决方案
//是否使能重新对齐lv_obj_set_auto_realign(lv_obj_t* obj,bool en)这个函数直接可以免去重复调用lv_obj_realign函数的困扰
//设置对象LVobj3能否被拖拽
//lv_obj_set_drag(LVobj3,true);
//设置对象LVobj3在某个方向上被拖拽
lv_obj_set_drag_dir(LVobj3,LV_DRAG_DIR_HOR);
//设置对象LVobj3的惯性功能
lv_obj_set_drag_throw(LVobj3,true);
//设置父容器与自己联动滑动由于此处LVobj3父对象直接是屏幕无法使用仅做介绍
//父对象必须使能可以被拖拽
//lv_obj_set_drag_parent(lv_obj_t*obj,bool en)
//使能并设置LVobj1的透明度
//透明度也可以在样式中设置透明度
lv_obj_set_opa_scale_enable(LVobj3,true);
//设置透明度值范围0~55(0为透明)
lv_obj_set_opa_scale(LVobj3,50);
//创建一个属于Screen1的按钮对象
LVbutton1 = lv_btn_create(Screen1,NULL);
//设置LVbutton1的坐标
lv_obj_set_pos(LVbutton1,200,50);
//设置按钮LVbutton1的事件回调函数
lv_obj_set_event_cb(LVbutton1,LVbutton1_Callback);
//此处创建的Child1是为了演示清除一个对象下的子对象操作
//创建LVobj1的子对象Child1
Child1 = lv_obj_create(LVobj1,NULL);
//设置Child1的大小
lv_obj_set_size(Child1,20,20);
//设置Child1的坐标
lv_obj_set_pos(Child1,10,10);
//设置Child1的样式
//先定义样式(注意定义为静态或者全局都可)
//static lv_style_t Child1Style;
//拷贝系统现有样式到Child1Style lv_style_plain_color为系统现有样式
lv_style_copy(&Child1Style,&lv_style_plain_color);
//修改Child1Style样式的背景颜色为红色
//main_color为上半部分的颜色grad_color为下半部分的颜色
Child1Style.body.main_color = LV_COLOR_RED;
Child1Style.body.grad_color = LV_COLOR_YELLOW;
//将Child1Style样式赋给Child1对象
lv_obj_set_style(Child1,&Child1Style);
}
//按钮LVbutton1的事件回调函数
void LVbutton1_Callback(lv_obj_t* obj,lv_event_t event){
//判断该回调是由哪个对象引起
if(obj == LVbutton1){
//判断引起回调的事件是不是释放
if(event == LV_EVENT_RELEASED){
//如果触发了这个事件则马上删除LVobj1这个对象
//lv_obj_del(LVobj1);
//除了lv_obj_del这个函数可以同步删除对象之外还有一个函数也可以删除对象
//lv_obj_del_async是在下一个handle之后删除这个对象
//lv_obj_del_async(LVobj1);
//在触发这个事件时清空LVobj1对象的子对象
//lv_obj_clean(LVobj1);
//在触发这个事件时我们吧LVobj1的父对象更换为Screen1
//lv_obj_set_parent(Child1,Screen1);
//在触发这个事件时将LVobj1放在LVobj2之前(刚开始LVobj1默认是在LVobj2的后面因为LVobj2较晚于LVobj1创建)
//lv_obj_move_foreground(LVobj1);
//在触发这个事件时将LVobj2放在LVobj1之后(刚开始默认是在LVobj1的前面因为LVobj2较晚于LVobj1创建)
//lv_obj_move_background(LVobj2);
//在触发这个事件时将LVobj2隐藏
lv_obj_set_hidden(LVobj2,true);
}
}
}
//基础对象LVobj1的事件回调函数声明
void LVobj1Click_Callback(lv_obj_t* obj,lv_event_t event){
//判断该回调是由哪个对象引起
if(obj == LVobj1){
//判断引起回调的事件是不是释放
if(event == LV_EVENT_RELEASED){
lv_obj_set_pos(LVobj1,150,150);
}
}
}