发作品签到
专业版

温控设备1.0

工程标签

840
0
0
0

简介

基于stm32的温控设备,带oled,a24c64存储,ch340e串口,tja1050 can通讯,pd12v诱骗等

简介:基于stm32的温控设备,带oled,a24c64存储,ch340e串口,tja1050 can通讯,pd12v诱骗等

开源协议

GPL 3.0

创建时间:2023-12-04 11:44:58更新时间:2024-03-29 09:30:22

描述

仅供学习,不可商用

 

本项目是一个基于stm32f103cbt6FreeRTOS系统的温控设备,用到的外设或者功能有spi oled屏幕、tja1050 can通讯、ch340e串口通讯、五向按键、adc、pid控制pwm输出、iic at24c64存储、ch224k pd12v诱骗、降压。

我这里用了一个3d打印的挤出头作为负载来演示功能,当然做这个项目的目的也主要是为了练习freertos、iic、spi、can等协议的使用。

 

代码链接

https://github.com/cnxft/Temperature_Control_Equipment/tree/main

 

一、总体设计框图

电源:

其他:

 

二、硬件电路组成

1.AT24C64存储部分,芯片和他IIC的上拉

2.12864OLED屏幕的SPI接线

3.pwm控制输出的大小电路

三、程序流程图

 

在启动freertos的任务调度器之前初始化或启动了以下内容

  HAL_ADCEx_Calibration_Start(&hadc1);
  HAL_ADC_Start_DMA(&hadc1, (uint32_t *)&dmaadc, 3);

  HAL_TIM_Base_Start_IT(&htim2);
  HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_1);
  HAL_TIM_PWM_Start_IT(&htim2, TIM_CHANNEL_3);

  NTC1save_init(ntc1save);
  Key_Loading();
  userShellInit();
  CAN_SetFilters();
  HAL_CAN_Start(&hcan);
  u8g2Init(&u8g2);

 

随后oled屏幕上出现进度条,进度条的长度随着从at24c64获取参数的进度增加而增加

本项目用到了FreeRTOS系统,所以整个功能设计起来就比较简单,这里一共用到了7个任务

void AppTask_App(void *argument);

//读取ntc的值并计算

void AppTask_OutPut(void *argument);

//使用pid算法计算输出的pwm波形的占空比

void AppTask_MessSend(void *argument);

//发送can、串口消息、保存数据到at24c64

void AppTask_SerCom(void *argument);

//使用shell_letter开源库

void AppTask_CanCom(void *argument);

//轮询方式can接收消息

void AppTask_Key(void *argument);

//使用multi_button开源库,产生5ms的滴答

void AppTask_Menu(void *argument);

//驱动oled屏幕的程序

 

 

1、任务内容

各个任务写在了UserApp下的文件里了大家可以自行查看

2、oled菜单划分

oled屏幕用的b站大佬开源的程序,思路大概是做成链表,可以指向下一级菜单,也可以指向想要做成的界面(函数形式)

简单列写了一个菜单列表

3、u8g2初始化

在oled.c文件里写了u8g2库驱动oled的回调函数,u8g2初始化:
u8g2_Setup_ssd1306_128x64_noname_f(u8g2, U8G2_R0, u8x8_byte_4wire_hw_spi, u8x8_stm32_gpio_and_delay);
其中u8x8_byte_4wire_hw_spi()函数的意思是使用了4线硬件spi,函数里将hal库中spi的驱动函数写在对应位置;
u8x8_stm32_gpio_and_delay()函数为使用软件spi/iic时的gpio与延时函数,使用软件方式时要将hal gpio与delay的函数写在这个函数里,但是这里用的硬件方式,故而函数直接return 1
使用u8g2库自带的针对ssd1306的setup函数,就不用自己写了

4、菜单的切换

当按键按下时,改变屏幕的运行状态,再根据运行状态去刷新菜单或者打开指定的函数。
按键检测任务写在TaskKey任务中,此任务每间隔5ms会产生一个嘀嗒,用来检测按键。然后将按键检测的结果放到提前创建好的队列中
TaskMenu任务中调用阻塞方式获取按键状态的函数,阻塞时间200ms
(xQueueReceive(Queue_OLEDKeysHandle, &Dir, pdMS_TO_TICKS(200)) != pdTRUE)
(可以理解成隔200ms刷新一次屏幕)

5、can

没有针对can接口设计很多的功能,也没有很细致的操作,只写了配置了以下能正常发送接收,没有任何功能
使用can的函数在usercan.c文件中,发送、轮询接收、筛选器配置均在。
筛选器配置成了32位掩码模式。以后有了具体的应用再改吧。

6、串口

针对串口部分使用了一个letter_shell库,可以像linux的shell一样操纵设备
在shell_func..c文件中,增加了几个函数,可以使用指令来调用这些函数来实现改动kp、ki、kd的值来更加方便的调参。
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), out_state, Shell_OUT, Enable output 1 or 0);
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), out_target, Shell_Target, Set target temp double);
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), parameter_show, Shell_Parameter_Show, show pid wushen);
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), pid_reset, Shell_PID_Reset, pid reset wushen);
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), kp_set, Shell_Kp, Set Kp float);
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), ki_set, Shell_Ki, Set Ki float);
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), kd_set, Shell_Kd, Set Kd float);
这里的kp等的参数虽然在定义的时候是double类型,但是这个letter_shell的库形参是double会出错(0),float正常。
连接串口后,可以按Tab键或输入help+enter来查看可用的指令。值得注意的是,当函数类型是浮点类型时,小数点不要省略。
另在shell.c文件中可以修改logo。
看我改的,是不是非常漂亮

7、adc采集

这里使用了公式法根据B值计算当前温度,函数名:float ntc_count_value(ntcpar ntcx)。此函数位于ntc.c中。使用了dma来获取adc,在AppTask_App中 定时获取adc的值并计算和保存。

8、输出

使用了pwm控制三极管控制mos管的方式驱动加热设备,pwm占空比的多少由pid算法计算得来,这里使用的是左侧的输出与感温电阻。右侧可以使用pwm来控制风扇之类的。分频值与记数值设置如下,可以根据自己的需求自行修改,修改记数值时,要记得改一下pid计算结果映射到pwm占空比部分的函数。

9、数据的保存与读取

单独设计了一块AT24C64的芯片用来保存设备的参数,包括kp、ki、kd的值,感温电阻的B值,感温电阻的分压电阻的阻值、测压的两个电阻的阻值等等
数据在AT24C64芯片上保存的位置如下,包括了起始地址与相对于起始位置的偏移。
/****************在AT24C64保存数据的相对地址*******************/
#define DATE_FIRST_ADD 352  // 保存数据的第一个位置
#define Date_OUTSTATE_SUM 0 // 相对初始位置的差值
#define Date_NTCB_SUM 1     // 相对差值1
#define Date_NTCT25_SUM 3
#define Date_NTCMAXADC_SUM 7
#define Date_NTCR1_SUM 11
#define Date_NTCR2_SUM 15
#define Date_VADCMADC_SUM 19
#define Date_VDDA_SUM 21
#define Date_RESH_SUM 25
#define Date_RESL_SUM 29
#define Date_KP_SUM 33
#define Date_KI_SUM 41
#define Date_KD_SUM 49
#define Date_TARGET_SUM 57
#define Date_TIMEDELTA_SUM 65
#define Date_TOTAL_NUM 15
在SaveAndRead_func.c文件中,定义了两个函数:
HAL_StatusTypeDef Date_Init(uint8_t which_one);
HAL_StatusTypeDef Date_Save(uint8_t which_one);
分别用来保存和读取数据。再函数中使用了一个共用体的变量,使得保存于读取更便捷。

10、进度条

在AppTask_App中for(;;)循环前会进行数据的读取,将一些必要的参数读取到程序之中。
此初用了一个freertos系统中程序间同步的功能,使用通知来模拟二值信号量,来同步AppTask_App与AppTask_Menu。AppTask_Menu任务中的进度条没获取到一个二值信号量就会变长,否则进入阻塞状态。直到跑完进度条进入菜单界面。

11、问题与反思

首先要说的是这个并不能算是一个完美的作品,功能、程序、外壳还有很多需要完善的地方。
......未完待续

四、实物展示

我的焊接顺序:第一步先焊接背面,可以用焊台焊接,第二步焊接芯片和两个type-c接口,确保焊接正确,第三步焊接其他,可用热风枪,但要注意type-c的位置。这一步也可先焊接pd12v诱骗部分,试试效果,成功诱骗灯会亮。再焊接5v转3.3v。最后焊接屏幕和插件。

温度曲线

 

输出设置(开关,目标温度,风扇的pwm占空比)

 

设置PID的kp

 

 

参数显示

 

 

五、演示视频

演示视频在附录中,演示了letter_shell的用法,同时也展示了修改参数和自动保存到at24c64的功能。

 

 

 

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

附件

序号文件名称下载次数
1
底座2.SLDPRT
7
2
上壳.STL
5
3
bandicam 2024-03-28 20-00-33-611.mp4
5
克隆工程
添加到专辑
0
0
分享
侵权投诉

工程成员

评论

全部评论(1
按时间排序|按热度排序
粉丝0|获赞0
相关工程
暂无相关工程

底部导航