本文主要是介绍基于通用单片机(久齐) 半导体制冷制热的控制 手机散热器按摩仪器中冷热头的控制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
基于通用单片机(久齐) 手机散热器,按摩仪器中冷热头的控制
项目涉及到了硬件以及软件部分,硬件部分涉及到了ME4056电源管理IC,以及NY8B062D IC的应用,USB应用,H桥驱动输出元素 TEC1-7103 半导体制冷设备。
TEC1-7103 半导体制冷
半导体制冷片的工作原理是基于帕尔帖原理,该效应是在1834年由J.A.C帕尔帖首先发现的,即利用当两种不同的导体A和B组成的电路且通有直流电时,在接头处除焦耳热以外还会释放出某种其它的热量,而另一个接头处则吸收热量,且帕尔帖效应所引起的这种现象是可逆的,改变电流方向时,放热和吸热的接头也随之改变,吸收和放出的热量与电流强度I[A]成正比,且与两种导体的性质及热端的温度有关
半导体制冷片工作原理
致冷器件是由半导体所组成的一种冷却装置,随着近代的半导体发展才有实际的应用,也就是致冷器的发明。其工作原理是由直流电源提供电子流所需的能量,通上电源后,电子负极(-)出发,首先经过P型半导体,于此吸热量,到了N型半导体,又将热量放出,每经过一个NP模块,就有热量由一边被送到令外一边造成温差而形成冷热端。冷热端分别由两片陶瓷片所构成,冷端要接热源,也就是欲冷却之。
文章目录
- 基于通用单片机(久齐) 手机散热器,按摩仪器中冷热头的控制
- TEC1-7103 半导体制冷
- 内容涉及 :
- 一:编程要点
- 二:NY8B062D 久齐IC介绍
- 三:代码分析
- 软件层
- 1:main.c
- 2:BAT_State.h
- 3:BAT_State.c
- 4:ColdHotOut_State.h
- 5:ColdHotOut_State.c
- 6:Key_State.h
- 7:Key_State.c
- 9:PID.h
- 10:PID.c
- 11:Soft_State.h
- 12:Soft_State.c
- 硬件层
- 1:Hardware.h
- 2:Hardware.c
- 3:ADC_CO.h
- 4:ADC_CO.c
- 5:GPIO_OUT.h
- 6:GPIO_OUT.c
- 7:Key_CO.h
- 8:Key_CO.c
- 9:Pwm_CO.h
- 10:Pwm_CO.c
- 11:Sys_CO.h
- 12:Sys_CO.c
- 总结
内容涉及 :
- ANY8B062D IO控制
- ANY8B062D 输入控制
- ANY8B062D 定时器控制
- ANY8B062D 4路PWM器控制
- ANY8B062D AD采集控制
- ANY8B062D IO输入与输出复用
- ME4056电源管理
- PID NTC控制中的 P控制
- ANY8B062D 低功耗控制
一:编程要点
- 初始 单片机的RAM
- 初始化 IC的配置状态;
- 编写驱动层以及软件层;
- 驱动层与软件层分离运行,多线程运行;
SJ02冷热头功能说明开关机及切换:
长按图案对应热熬开关键2秒,加热功能开启,此时温度约45℃左右,指示灯暗红色;短按一次,温度约50℃左右,指示灯变红色;依此循环,长按3秒热敷键关掉;
长按图案对应冷熬开关键2秒,冷熬功能开启,此时温度约19℃左右,指示灯暗蓝色;短按一次,温度约13℃左右,指示灯变蓝色;依此循环,长按3秒冷敷键关掉;
例如:当前热熬功能,短按冷熬开关键,冷熬功能开启,热熬功能关闭,当冷熬功能状态,短按热熬功能,热熬功能开启,冷熬功能关闭,依此短按开关键可切换功能
二.低电压保护:
当电量低于3.3V时强制关机,低电关机后,重启开机电压3.5V。
三.自动关机:开机进入使用状态后不论有无功能操作10分钟自动关机。
四. 充电:适配器5V2A,充电需有独立充电0.5C,充至4.15V变灯充满,4.2V强制停止充电,充电时间2H-2.5H,充电电流到电芯不能大于0.5A,充电不工作,按键无效,超过3小时关闭充电功能。1).充电模式显示:充电状态下,呼吸灯变化,通过呼吸灯颜色显示当前电量。4.15V~以上 (红色灯长亮)3.3V~4.15V (红色呼吸灯)五.电池:1.一节14500锂电池3.7V 800mAh,2.最大放电电流0.8A,过流保护4A 10ms, 电池过放保护后充电可激活。
六.关机电流静态电流≤10uA
二:NY8B062D 久齐IC介绍
久齐IC 官网
NY8B062D是以EPROM作为存储器的 8 位单片机,专为家电或量测等等的I/O应用设计。采用CMOS制程并同时提供
客户低成本、高性能、及高性价比等显著优势。NY8B062D核心建立在RISC精简指令集架构可以很容易地做编程和控
制,共有 55 条指令。除了少数指令需要两个指令时钟,大多数指令都是一个指令时钟能完成,可以让用户轻松地以
过程控制完成不同的应用。因此非常适合各种中低记忆容量但又复杂的应用。NY8B062D内建高精度十一加一通道 12
位ADC模数转换器,与高精度电压比较器,足以应付各种模拟接口的侦测与量测。 在 I/O 的资源方面,NY8B062D 有 14 根弹性的双向 I/O 脚,每个 I/O 脚都有单独的寄存器控制为输入或输出脚。而且
每一个 I/O 脚位都能通过控制相关的寄存器达成如上拉或下拉电阻或开漏(Open-Drain)输出。此外针对红外线摇控
的产品方面,NY8B062D 内置了可选择频率的红外载波发射口。
NY8B062D 有四组定时器,可用系统时钟当作一般的计时应用或者从外部讯号触发来计数。另外 NY8B062D 提供 3 组 10 位的 PWM 输出,3 组蜂鸣器输出,可用来驱动马达、LED、或蜂鸣器等等。
NY8B062D 采用双时钟机制,高速振荡时钟或者低速振荡时钟都由内部 RC 振荡或外部晶振输入。在双时钟机制下,
NY8B062D 可选择多种工作模式如正常模式(Normal)、慢速模式(Slow mode)、待机模式(Standby mode)与睡
眠模式(Halt mode),可节省电力消耗,延长电池寿命。并且单片机在使用内部 RC 高速振荡时,低速振荡可以同时
使用外部精准的晶振计时。可以维持高速处理同时又能精准计算真实时间。
在省电的模式下,如待机模式(Standby mode)与睡眠模式(Halt mode)中,有多个中断源可以触发来唤醒 NY8B062D
进入正常操作模式(Normal mode)或慢速模式(Slow mode)来处理突发事件。
三:代码分析
软件层
1:main.c
代码如下:
/* =========================================================================* Project: PWM1~PWM4 output at the same time* File: main.c* Description:* PWM4(PA3/PA7) : Period = 4.88KHz (Duty: 512/1024)* PWM3(PA2) : Period = 4.88KHz (Duty: 768/1024)* PWM2(PA4/PB2) : Period = 4.88KHz (Duty: 1023/1024)* PWM1(PB3) : Period = 4.88KHz (Duty: 1/1024)* Author: Wangq* Version: v1.0 B01B7B* Date: 2021/03/25=========================================================================*/
#include <ny8.h>
#include "ny8_constant.h"#define UPDATE_REG(x) __asm__("MOVR _" #x ",F")#include "./Hardware/Hardware.h"
#include "./Software/Soft_State.h"
//---------------------------------------------------------
// 芯片引脚功能自定义 |
/*---------------------------------------------------------———————VDD 1-|。 |-16 VSS/PA6/Xin 2-| |-15 PA4/AIN4/EX_CL/LED4_R/PA7/Xout 3-| |-14 PA3/AIN3/LED3_GKEY/PA5/RSTb 4-| |-13 PA2/AIN2/PWM3/BZ3/PB3/AIN8/PWM1/BZ1 5-| |-12 PA1/AIN1/EX_CL/CDSPB2/AIN7/PWM2/BZ2 6-| |-11 PA0/AIN0/VREFI/OPTOPB1/AIN6/IR/INT1 7-| |-10 PB5/AIN10 PB0/AIN5/INT0 8-|_______|-9 PB4引脚1 :VDD 芯片电源端。 引脚2 : 引脚3 :引脚4 : 引脚5 :PB3 暖控制信号输出脚。引脚6 : PB2 冷控制信号输出脚。引脚7 : PB1 冷按键信号输入脚(中断) 引脚8 : PB0 暖按键信号输入脚(中断)引脚9 : 引脚10 : 引脚11 : PB5 BAT。 引脚12 : PA1 NTC。 引脚13 : PA2 LEDR引脚14 : PA3 LEDB
--------------------------------------------------------- */void Sys_sleep(void){if(machine_state.Modle_state != Modle_IDLE ){ gcount_asleep = 0; return;}if(!b_asleep100ms){ return;}b_asleep100ms = 0;if(gcount_asleep++<50){ return;}gcount_asleep = 0;b_asleep = 1;PABIE = 1;ENI();SLEEP();NOP();NOP();NOP();b_asleep = 0;gcount_asleep = 0;
}
void main(void)
{clear_memory(); //清理内存fn_sys_reset(); //初始化芯片Hardware_init(); //硬件初始化Software_State_init(); //软件初始化Hardware_Start(); //硬件热机while(1){ Sys_sleep(); //睡眠识别Hardware_run(); //硬件状态控制Software_Input_Check(); //输入状态机Software_State_Check(); //状态转化处理Software_Output_Check(); //输出状态机}}static unsigned char cunt1_T0 = 0;
static unsigned char cunt2_T0 = 0;
static unsigned char cunt3_T0 = 0;void isr(void) __interrupt(0)
{if(T0IF==1){ //500usTMR0 = CST_reload_T0; //递增定时器 1us*50=100us 装载值 T0IF= 0;if(cunt1_T0++ > 15){bkey1_10ms = 1; //硬件按键扫描时间bkey2_10ms = 1; cunt1_T0 = 0; //计数器清零b_pid500ms = 1; //PID控制基准时间b_led_Robing10ms = 1; //LED变化时间}if(cunt2_T0++ > 188){ //100MSbatceck_10ms_flag =1; //电池电压检测时间badc_10ms_flag = 1; //ADC采样时间cunt2_T0 = 0; //计数器清零bHardware_Start_100ms = 1; //硬件热机时间计时b_asleep100ms = 1; //睡眠检测时间if(cunt3_T0++ > 99){ //10Scunt3_T0 = 0;bworktime_100ms_flag = 1; //工作时间计时bchargtime_1s_flag = 1; //睡眠充电时间 }}}T1IF = 0; T2IF= 0;T3IF = 0;if(PABIF == 1){PABIF= 0;gcount_asleep = 1;}if(ADIF == 1){ADIF= 0;if(ADMDbits.EOC == 1){if(Count_Adc++>4){Count_Adc =0;ad_finish_flag = 1;}else{ADMDbits.START = 1;}}ADIF= 0; }if(WDTIF==1){ WDTIF= 0; } else {;}
}
2:BAT_State.h
代码如下:
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/9/2022
// Description:
// =========================================================================
#ifndef _BAT_State_H_
#define _BAT_State_H_
#include <ny8.h>
#include "ny8_constant.h"#define _BAT_2V6 1775 // 2.6V
#define _BAT_2V7 1843 // 2.7V
#define _BAT_3V0 2048 // 3.0V
#define _BAT_3V1 2090 // 3.1V
#define _BAT_3V3 2250//2252 // 3.3V
#define _BAT_3V5 2369 // 3.5V
#define _BAT_3V6 2457 // 3.6V
#define _BAT_3V7 2525 // 3.7V#define _BAT_4V0 2730 // 4.0V
#define _BAT_4V15 2846 // 4.15V
#define _BAT_4V2 2867 // 4.2V#define _BAT_CHECKL _BAT_3V3 //电压检测点设置
#define _BAT_CHECKL_OUT _BAT_3V1#define _BAT_CHECKML _BAT_3V5
#define _BAT_CHECKMH _BAT_4V0#define _BAT_CHECKH _BAT_4V15
#define _BAT_CHECKH_H _BAT_4V2 void BAT_State_Check(void); //电池电压状态机
void USB_State_Check(void); //USB识别状态机
void LED_Hot_Robing(void); //制冷制热状态机
void Low_Flash(void); //低电量指示灯闪烁
#endif
3:BAT_State.c
代码如下:
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/9/2022
// Description:
// =========================================================================
#include "BAT_State.h"
#include "Soft_State.h"//#define _BAT_CHECKL _BAT_3V3
//#define _BAT_CHECKL_OUT _BAT_3V3
//
//#define _BAT_CHECKML _BAT_3V5
//#define _BAT_CHECKMH _BAT_4V0
//
//#define _BAT_CHECKH _BAT_4V15
//#define _BAT_CHECKH_H _BAT_4V2 static unsigned char count_bat_checK = 0; //低电压计数
static unsigned char count_bat_checK1 = 0;
static unsigned char Merry_BAT_state = BAT_IDLE;static unsigned int Vla_BAT_CHECKL = _BAT_CHECKL;void BAT_State_Check(void){if(!batceck_10ms_flag){ return;} //电池检测为100ms左右batceck_10ms_flag = 0;
// if(Merry_BAT_state != machine_state.BAT_state){
// Merry_BAT_state = machine_state.BAT_state;
// count_bat_checK = 0;
// count_bat_checK1 = 0;
//
// }if(machine_state.BAT_state == BAT_IDLE){ //电池处于正常状态if( (PWM1_HardWare_State == PWM_OFF) && (PWM2_HardWare_State == PWM_OFF) ){Vla_BAT_CHECKL = _BAT_CHECKL;}else{Vla_BAT_CHECKL = _BAT_CHECKL_OUT;}if(BAT_Value < Vla_BAT_CHECKL){ //低于303V保护count_bat_checK1 = 0;if(count_bat_checK++<15){return;}count_bat_checK = 0;machine_state.BAT_state = BAT_empty; //电池保护状态LowPowerFlash_En = 1; //低电量闪烁machine_state.Modle_state = Modle_IDLE; //设备关机}else if((BAT_Value > _BAT_CHECKH) || ((STDBY_Get_Out() == 0) && (GPIO_STDBY == 0))){ //高于于4.15V充电完成 或者在STDBY为输入状态下 充电状态为0count_bat_checK = 0;if(count_bat_checK1++<15){return;}count_bat_checK = 0;machine_state.BAT_state = BAT_fully; //软件充满状态}else{count_bat_checK = 0;count_bat_checK1 = 0;}}else if(machine_state.BAT_state == BAT_empty){ //如果是低电压状态if(BAT_Value > _BAT_CHECKML){if(count_bat_checK++<15){return;}count_bat_checK = 0;machine_state.BAT_state = BAT_IDLE;count_charg_Time_Check = 0;bchargoff_fla = 0;
// if(machine_state.Modle_state == Modle_ON_USBIN){
// machine_state.BAT_state = BAT_IDLE;
// }}else{count_bat_checK = 0;}}else if(machine_state.BAT_state == BAT_fully){ //如果电压状态为满电状态if(((STDBY_Get_Out() == 0) && (GPIO_STDBY == 1)) && (BAT_Value<_BAT_CHECKMH)){count_bat_checK = 0;if(count_bat_checK1++<15){return;}count_bat_checK = 0;machine_state.BAT_state = BAT_IDLE;bchargoff_fla = 0;count_charg_Time_Check = 0;}else{count_bat_checK1 = 0;}}else{}
}void USB_State_Check(void){if(Hardware_USB_state == USB_IN ){ //如果USB硬件识别到以后if(machine_state.USB_state == USB_OFF){ //改变USB软件状态Machine_off(); }machine_state.USB_state = USB_CH; //USB状态为充电状态进入充电machine_state.Modle_state = Modle_ON_USBIN; //软件模式进入充电模式 }else{if(machine_state.USB_state == USB_CH){Machine_off();machine_state.Modle_state = Modle_IDLE; }machine_state.USB_state = USB_OFF;}
}void LED_Hot_Robing(void){if(machine_state.LED_state != Modle_LED_Bat_Charg ){ //如果不是在充电状态b_Exled_Robing = 0 ;return;}if( !b_led_Robing10ms ){ return;} //充电闪烁b_led_Robing10ms = 0;if( !b_Exled_Robing ){if(PWM3_Data > 0xFD){ b_Exled_Robing = 1 ;return;}PWM3_Data++;}else{if(PWM3_Data == 0x00 ){ b_Exled_Robing = 0 ; return;}PWM3_Data--;}PWM3_HardWare_State = PWM_ON; fn_PWM3_Check(PWM3_Data);
}void Low_Flash(void){ //低电压闪烁unsigned char TI = 0; unsigned char count_Ti = 0;if(!LowPowerFlash_En){ return ; }LowPowerFlash_En = 0;Machine_off();for(TI = 0; TI<10 ; TI++){GPIO_OUT1 = ~ GPIO_OUT1;for(count_Ti = 0 ;count_Ti<250 ;count_Ti++ ){fn_MOS_delay(240);fn_MOS_delay(250);fn_MOS_delay(240);fn_MOS_delay(250);}}gcount_asleep = 0; // 将设备睡眠计数器重新清理 LED_Hot_Close();
}
4:ColdHotOut_State.h
代码如下:
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/9/2022
// Description:
// =========================================================================
#ifndef _COLDHOTOUT_STATE_H_
#define _COLDHOTOUT_STATE_H_
#include <ny8.h>
#include "ny8_constant.h"void LED_State_Check(void); //LED状态机
void LED_OUTCold(unsigned char Dout ); //软件层的LED 控制
void LED_OUTHot(unsigned char Dout );//软件层的LED 控制
void LED_Close_Hot(void );//软件层的LED 控制
void LED_Close_Cold(void );//软件层的LED 控制void RTC_State_Check(void); //制热制冷状态机
void RTC_Cold_On(void); //软件层的L/制热制冷控制
void RTC_Hot_On( void); //软件层的L/制热制冷控制
void RTC_Hot_Close(void); //软件层的L/制热制冷控制
void RTC_Cold_Close(void); //软件层的L/制热制冷控制
void fn_MOS_delay(unsigned char count);void Hot_PID(unsigned int TargetAD); //P制热制冷控制
void Cold_PID(unsigned int TargetAD); //P制热制冷控制#endif
5:ColdHotOut_State.c
代码如下:
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/9/2022
// Description:
// =========================================================================#include "ColdHotOut_State.h"
#include "Soft_State.h"
#include "PID.h"void LED_State_Check(void){switch (machine_state.LED_state){case Modle_LED_IDE :{ //待机状态设备灯光控制LED_Close_Cold();LED_Close_Hot();break;}case Modle_LED_Cold_1:{LED_Close_Hot(); //1制冷状态关闭加热打开制冷LED_OUTCold(1); break;}case Modle_LED_Cold_2:{ //2制冷状态关闭加热打开制冷LED_Close_Hot(); LED_OUTCold(2); break;}case Modle_LED_Hot_1:{ //1加热状态关闭制冷打开加热LED_Close_Cold();LED_OUTHot(1); break;}case Modle_LED_Hot_2:{ //2加热状态关闭制冷打开加热LED_Close_Cold();LED_OUTHot(2); break;}case Modle_LED_Bat_Charg:{ //充电的时候呼吸灯LED_Hot_Robing(); break;}case Modle_LED_Bat_ChargOff:{ //充电满电的时候关闭 LED_OUTHot(2); break;}default:{;}}}void LED_OUTHot(unsigned char Dout ){ //灯光控制软件层状态switch(Dout){case 1:{PWM3_Data = 100;break;}case 2:{PWM3_Data = 0xFF;break;}default:{}}PWM3_HardWare_State = PWM_ON; fn_PWM3_Check(PWM3_Data);
}void LED_OUTCold(unsigned char Dout ){//灯光控制软件层状态switch(Dout){case 1:{PWM4_Data = 100;break;}case 2:{PWM4_Data = 0xFF;break;}default:{}}PWM4_HardWare_State = PWM_ON; fn_PWM4_Check(PWM4_Data);
}void LED_Close_Hot(void ){ //灯光控制软件层状态if(PWM3_HardWare_State != PWM_OFF){PWM3_HardWare_State = PWM_OFF; //关闭驱动层PWM3_Data = 0;fn_PWM3_Check(PWM3_Data);fn_PWM3_OFF();}LED_Hot_Close();
}
void LED_Close_Cold(void ){ //灯光控制软件层状态if(PWM4_HardWare_State != PWM_OFF){PWM4_HardWare_State = PWM_OFF; PWM4_Data = 0;fn_PWM4_Check(PWM4_Data);fn_PWM4_OFF();}LED_Cold_Close();
}//=================================================
//====== RTC 加热函数 ========
//=================================================void RTC_State_Check(void){ if(machine_state.USB_state == USB_IN){ return;}switch (machine_state.RTC_state){case Modle_RTC_IDE:{RTC_Cold_Close();RTC_Hot_Close();FA_Close();break;}case Modle_RTC_Cold_1:{ATarget_PWM_max = TARGET_PWM_MAX1;RTC_Hot_Close();Cold_PID(TARGET_PWMAD_Cold1);RTC_Cold_On();break;}case Modle_RTC_Cold_2:{ATarget_PWM_max = TARGET_PWM_MAX2;RTC_Hot_Close();Cold_PID(TARGET_PWMAD_Cold2);RTC_Cold_On();break;}case Modle_RTC_Hot_1:{ATarget_PWM_max = TARGET_PWM_MAX1;RTC_Cold_Close();Hot_PID(TARGET_PWMAD_Hot1);RTC_Hot_On(); break;}case Modle_RTC_Hot_2:{ATarget_PWM_max = TARGET_PWM_MAX2;RTC_Cold_Close();Hot_PID(TARGET_PWMAD_Hot2);RTC_Hot_On(); break;}default:{machine_state.RTC_state = Modle_RTC_IDE;}}
}void RTC_Cold_On( void ){ //制冷的驱动层控制Cold_EN();PWM1_HardWare_State = PWM_ON; fn_PWM1_Check(PWM1_Data); }void RTC_Cold_Close(void){ //制冷的驱动层控制if(PWM1_HardWare_State != PWM_OFF){PWM1_Data = 0; //首先先关闭所有的MOS ENfn_PWM1_Check(PWM1_Data);fn_PWM1_OFF();PWM1_HardWare_State = PWM_OFF;Cold_Close();PWM2_Data = 0;fn_PWM2_Check(PWM2_Data);fn_PWM2_OFF();PWM2_HardWare_State = PWM_OFF;Hot_Close();fn_MOS_delay(80); //对地进行放电PWOUT_Cold_OUT(); fn_MOS_delay(80);PWOUT_Cold_Close();}Cold_Close();
}void RTC_Hot_On(void){ //制热的驱动层控制Hot_EN();PWM2_HardWare_State = PWM_ON;fn_PWM2_Check(PWM2_Data);
}void RTC_Hot_Close(void){ //制热的驱动层控制if(PWM2_HardWare_State != PWM_OFF){PWM1_Data = 0;fn_PWM1_Check(PWM1_Data);fn_PWM1_OFF();PWM1_HardWare_State = PWM_OFF; //首先先关闭所有的MOS ENCold_Close();PWM2_Data = 0;fn_PWM2_Check(PWM2_Data);fn_PWM2_OFF();PWM2_HardWare_State = PWM_OFF;Hot_Close();fn_MOS_delay(80); //对地进行放电PWOUT_Hot_OUT();fn_MOS_delay(80);PWOUT_Hot_Close();}Hot_Close();
}void fn_MOS_delay(unsigned char count){unsigned char i = 0;for(i = 0;i <= count;i++){NOP(); NOP();}
}void Cold_PID(unsigned int TargetAD){ //PID简单的采样电路unsigned target_pwm = 0;if(!b_pid500ms){ return ;}b_pid500ms = 0;if(NTC_Value > TargetAD){target_pwm = 0;//FA_OUT();GPIO_FAOUT = 1;}else{target_pwm = PIDcompute( TargetAD , NTC_Value );if(target_pwm > 196){//FA_OUT();GPIO_FAOUT = 1;}else{//FA_Close();GPIO_FAOUT = 0;}}if(PWM1_Data > target_pwm){PWM1_Data --;}else if (PWM1_Data < target_pwm){PWM1_Data ++;}else{}}void Hot_PID(unsigned int TargetAD){ //PID简单的采样电路unsigned target_pwm = 0;if(!b_pid500ms){ return ;}b_pid500ms = 0;if(NTC_Value < TargetAD){target_pwm = 0;//FA_OUT();GPIO_FAOUT = 1;}else{//FA_Close();GPIO_FAOUT = 0;target_pwm = PIDcompute( TargetAD , NTC_Value );}if(PWM2_Data > target_pwm){PWM2_Data --;}else if (PWM2_Data < target_pwm){PWM2_Data ++;}else{}
}
6:Key_State.h
代码如下:
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/9/2022
// Description:
// =========================================================================
#ifndef _Key_State_H_
#define _Key_State_H_
#include <ny8.h>
#include "ny8_constant.h"void Key_State_Check(void);#endif
7:Key_State.c
代码如下:
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/9/2022
// Description:
// =========================================================================#include "Key_State.h"
#include "Soft_State.h"void Key_State_Check(void){if((machine_state.Modle_state == Modle_ON_USBIN)){ //在USB以及低电压保护的时候不检查按键Hardware_key_state = Key_IDLE;return;}switch (Hardware_key_state){ //判断两个按键的长短按case Key1_Effect:{count_Work_Time_Check = 0;Hardware_key_state = Key_IDLE;if((machine_state.Modle_state == Modle_ON_Hot_1) ||(machine_state.Modle_state == Modle_ON_Hot_2)){machine_state.Modle_state = Modle_ON_Cold_1; //设置制冷1}else if (machine_state.Modle_state == Modle_ON_Cold_1){machine_state.Modle_state = Modle_ON_Cold_2; //设置制冷2}else if (machine_state.Modle_state == Modle_ON_Cold_2){machine_state.Modle_state = Modle_ON_Cold_1; //设置制冷1}else{;}break;}case Key1_Long_Effect:{count_Work_Time_Check = 0;Hardware_key_state = Key_IDLE;if(machine_state.Modle_state == Modle_IDLE){machine_state.Modle_state = Modle_ON_Cold_1; //长按制冷} else if((machine_state.Modle_state == Modle_ON_Cold_1)||(machine_state.Modle_state == Modle_ON_Cold_2) ){machine_state.Modle_state = Modle_IDLE; //再次长按关机}else if((machine_state.Modle_state == Modle_ON_Hot_1)||(machine_state.Modle_state == Modle_ON_Hot_2) ){machine_state.Modle_state = Modle_ON_Cold_1; //长按换挡}else{;} break;}case Key2_Effect:{count_Work_Time_Check = 0;Hardware_key_state = Key_IDLE;if((machine_state.Modle_state == Modle_ON_Cold_1)||(machine_state.Modle_state == Modle_ON_Cold_2)){machine_state.Modle_state = Modle_ON_Hot_1;}else if (machine_state.Modle_state == Modle_ON_Hot_1){machine_state.Modle_state = Modle_ON_Hot_2;}else if (machine_state.Modle_state == Modle_ON_Hot_2){machine_state.Modle_state = Modle_ON_Hot_1;}else{;}break;}case Key2_Long_Effect:{count_Work_Time_Check = 0;Hardware_key_state = Key_IDLE;if(machine_state.Modle_state == Modle_IDLE){machine_state.Modle_state = Modle_ON_Hot_1;}else if((machine_state.Modle_state == Modle_ON_Hot_1) ||(machine_state.Modle_state == Modle_ON_Hot_2)){machine_state.Modle_state = Modle_IDLE;}else if((machine_state.Modle_state == Modle_ON_Cold_1)||(machine_state.Modle_state == Modle_ON_Cold_2) ){machine_state.Modle_state = Modle_ON_Hot_1;}else{;}break;}default:{return;}}if(machine_state.BAT_state == BAT_empty){LowPowerFlash_En = 1; //低电量闪烁machine_state.Modle_state = Modle_IDLE; //设备关机}}
9:PID.h
代码如下:
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/11/2022
// Description:
// =========================================================================
#ifndef _PID_H_
#define _PID_H_
#include <ny8.h>
#include "ny8_constant.h"#define TARGET_PWM_MAX 0X03FF
#define TARGET_PWM_MAX1 0X0398//0X02BC
#define TARGET_PWM_MAX2 0X03FF//0x0320
#define TARGET_PWM_MIN 0x0000/*
50. 35.7K 0.78V 1077
45. 43.34K 0.9V 123825 100K 1.5V 202824 104K 1.52V 2088
19. 131K 1.7V 2322
18 137.2 2369
13. 173K 1.9V 2595
12 181 2638
AMAX = 1518 /7
AMIN = 951 /7
*/#define TARGET_PWMAD_Hot2 1145
#define TARGET_PWMAD_Hot1 1300#define TARGET_PWMAD_Cold1 2399
#define TARGET_PWMAD_Cold2 2658#define D_TARGET_Real_1 515
#define D_TARGET_Real_2 479
#define D_TARGET_Real_3 343
#define D_TARGET_Real_4 207
#define D_TARGET_Real_5 171
#define D_TARGET_Real_6 100
#define D_TARGET_Real_7 20#define D_TARGET_Cold 0
#define D_TARGET_Hot 200extern volatile unsigned int ATarget_PWM_max;
unsigned int PIDcompute(unsigned int Target,unsigned int Real);#endif
10:PID.c
代码如下:
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/11/2022
// Description:
// =========================================================================
#include "PID.h"//===========================================
//
//===========================================
volatile unsigned int ATarget_PWM_max =0;
unsigned int PIDcompute(unsigned int Target,unsigned int Real)
{unsigned int Error = 0;//-----------------------------------
//根据设定及采集值进行计算PID调节,计算pwm输出值()if(Target < Real){Error = Real - Target;}else{Error = Target - Real;} if(Error> D_TARGET_Real_5){return ATarget_PWM_max ; }else if(Error> D_TARGET_Real_6){ return 796 ; } else if(Error> D_TARGET_Real_7){return 196 ; } else {return 0 ; }/*if(Error> D_TARGET_Real_1){PW_Value = TARGET_PWM_MAX ; }else if(Error> D_TARGET_Real_2){PW_Value = 998 ; }else if(Error> D_TARGET_Real_3){PW_Value = 896 ; } else if(Error> D_TARGET_Real_4){PW_Value = 796 ; } else if(Error> D_TARGET_Real_5){PW_Value = 696 ; } else if(Error> D_TARGET_Real_6){PW_Value = 596 ; } else if(Error> D_TARGET_Real_7){PW_Value = 496 ; } else {PW_Value = 0 ; } */ }
11:Soft_State.h
代码如下:
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/8/2022
// Description:
// =========================================================================
#ifndef _Soft_State_H_
#define _Soft_State_H_
#include <ny8.h>
#include "ny8_constant.h"#include ".././Hardware/Hardware.h"
#include "PID.h"
#include "Key_State.h"
#include "ColdHotOut_State.h"
#include "BAT_State.h"
typedef union {struct{unsigned char BIT0:1;unsigned char BIT1:1;unsigned char BIT2:1;unsigned char BIT3:1;unsigned char BIT4:1;unsigned char BIT5:1;unsigned char BIT6:1;unsigned char BIT7:1;//unsigned char BIT8:1;unsigned char BIT9:1;unsigned char BIT10:1;unsigned char BIT11:1;//unsigned char BIT12:1;unsigned char BIT13:1;unsigned char BIT14:1;unsigned char BIT15:1;}DATA_BIT;unsigned char DATA_BYTE;
}Per_Machine_type;extern volatile Per_Machine_type machine_flag;#define bworktime_100ms_flag machine_flag.DATA_BIT.BIT0#define batceck_10ms_flag machine_flag.DATA_BIT.BIT1#define b_pid500ms machine_flag.DATA_BIT.BIT2 #define LowPowerFlash_En machine_flag.DATA_BIT.BIT3#define b_led_Robing10ms machine_flag.DATA_BIT.BIT4 #define b_Exled_Robing machine_flag.DATA_BIT.BIT5 #define bchargtime_1s_flag machine_flag.DATA_BIT.BIT6 #define bchargoff_fla machine_flag.DATA_BIT.BIT7 typedef struct _Machine_State{unsigned char Modle_state ;unsigned char USB_state ;unsigned char BAT_state ;unsigned char LED_state ;unsigned char RTC_state ;
}Machine_State ;extern volatile Machine_State machine_state;
extern volatile unsigned char MerryModle_state;
//-------------------------------------
// 开关状态
enum
{Modle_IDLE = 0, // Modle_ON_Hot_1 , // Modle_ON_Cold_1 ,Modle_ON_Hot_2 , // Modle_ON_Cold_2 ,Modle_ON_USBIN
};
//-------------------------------------
// LED状态
enum
{Modle_LED_IDE = 0, // Modle_LED_Hot_1, // Modle_LED_Hot_2, // Modle_LED_Cold_1,Modle_LED_Cold_2,Modle_LED_Bat_Charg,Modle_LED_Bat_ChargOff,Modle_LED_Error
};
//-------------------------------------
// RTC_状态
enum
{Modle_RTC_IDE = 0, // Modle_RTC_Hot_1, // Modle_RTC_Cold_1,Modle_RTC_Hot_2, // Modle_RTC_Cold_2,Modle_RTC_Error
};
//-------------------------------------
// BAT状态
enum
{BAT_IDLE = 0, // BAT_fully, // //BAT_fully_MaX, BAT_empty,BAT_ERROR
};enum
{USB_OFF = 0, USB_CH
};#define _WORK_TIME_ 59
#define _Charge_TIME_ 1079
extern volatile unsigned char count_Work_Time_Check;
extern volatile unsigned int count_charg_Time_Check;void Software_State_init(void);
void Software_State_Check(void);
void Software_Input_Check(void);
void Software_Output_Check(void);void Work_Time_Check(void);
void Work_charg_Check(void);
void Machine_off(void);#endif
12:Soft_State.c
代码如下:
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/8/2022
// Description:
// =========================================================================#include "Soft_State.h"
#include "Key_State.h"
#include "ColdHotOut_State.h"
#include "BAT_State.h"volatile Machine_State machine_state ;
volatile Per_Machine_type machine_flag;void Software_State_init(void){machine_state.Modle_state = Modle_IDLE; //待机模式MerryModle_state = machine_state.Modle_state;machine_state.USB_state = USB_OFF; // USB关机machine_state.BAT_state = BAT_IDLE; //电池状态为待机machine_state.LED_state = Modle_LED_IDE; //LED状态为待机machine_state.RTC_state = Modle_RTC_IDE; //RTC 待机状态STDBY_TO_IN();CE_OUT(); //允许充电PWM1_Data = 0;PWM2_Data = 0;PWM3_Data = 0;PWM4_Data = 0;}//=================================================
volatile unsigned char MerryModle_state = 0;void Software_State_Check(void){if(MerryModle_state != machine_state.Modle_state){MerryModle_state = machine_state.Modle_state;Machine_off(); }switch( machine_state.Modle_state ){case Modle_IDLE : { //待机状态STDBY_TO_IN();machine_state.LED_state = Modle_LED_IDE; //输出关闭 machine_state.RTC_state = Modle_RTC_IDE;break;}case Modle_ON_Hot_1 : {STDBY_TO_OUT();machine_state.LED_state = Modle_LED_Hot_1; //输出打开加热功能 machine_state.RTC_state = Modle_RTC_Hot_1;break;}case Modle_ON_Cold_1 : {STDBY_TO_OUT();machine_state.LED_state = Modle_LED_Cold_1; //输出打开制冷功能 machine_state.RTC_state = Modle_RTC_Cold_1; break;}case Modle_ON_Hot_2 : {STDBY_TO_OUT();machine_state.LED_state = Modle_LED_Hot_2; //输出打开加热功能2 machine_state.RTC_state = Modle_RTC_Hot_2; break;}case Modle_ON_Cold_2 : {STDBY_TO_OUT();machine_state.LED_state = Modle_LED_Cold_2; //输出打开制冷功能2 machine_state.RTC_state = Modle_RTC_Cold_2;break;}case Modle_ON_USBIN : { //充电状态进入充电状态以后进行指示灯的操作STDBY_TO_IN();if(bchargoff_fla == 1){ //充电市场控制状态标志位machine_state.LED_state = Modle_LED_Bat_ChargOff ;break;}if((machine_state.BAT_state == BAT_fully)){ machine_state.LED_state = Modle_LED_Bat_ChargOff ; //充电完成状态}else{machine_state.LED_state = Modle_LED_Bat_Charg ; //充电中}break;}default:{Software_State_init();}}}
void Software_Input_Check(void){ //应用层检测输入状态Key_State_Check();BAT_State_Check();USB_State_Check();Work_Time_Check();Work_charg_Check();
}
void Software_Output_Check(void){ // 驱动层检测输出状态LED_State_Check();RTC_State_Check();Low_Flash();
}
//=================================================// 工作状态检测 以及 充电时长检测
//=================================================
volatile unsigned char count_Work_Time_Check = 0 ; void Work_Time_Check(void){ if((machine_state.Modle_state != Modle_IDLE) && (machine_state.Modle_state != Modle_ON_USBIN) ){if(!bworktime_100ms_flag){ return; }bworktime_100ms_flag = 0;if(count_Work_Time_Check++ > _WORK_TIME_){count_Work_Time_Check = 0;Machine_off();machine_state.Modle_state = Modle_IDLE ;}}else{count_Work_Time_Check = 0;}
}volatile unsigned int count_charg_Time_Check = 0 ;
void Work_charg_Check(void){ if(machine_state.Modle_state == Modle_ON_USBIN){if(bchargoff_fla == 1){CE_Close();return;}CE_OUT(); //允许充电if(!bchargtime_1s_flag){ return; }bchargtime_1s_flag = 0;if(count_charg_Time_Check++ >= _Charge_TIME_){count_charg_Time_Check = 0;bchargoff_fla = 1;}}else{CE_OUT(); //允许充电count_charg_Time_Check = 0;bchargoff_fla = 0;}
}void Machine_off(void){ ///关机入口函数LED_Close_Cold();LED_Close_Hot();RTC_Cold_Close();RTC_Hot_Close();LED_Close_Hot();FA_Close();STDBY_TO_IN();CE_OUT(); //允许充电
}
硬件层
1:Hardware.h
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/7/2022
// Description:
// =========================================================================
#ifndef _HARDWARE_H_
#define _HARDWARE_H_#include "Sys_CO.h"
#include "Key_CO.h"
#include "ADC_CO.h"
#include "Pwm_CO.h"
#include "GPIO_OUT.h"void Hardware_init(void);
void Hardware_run(void);
void Hardware_Start(void);
#endif
2:Hardware.c
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/8/2022
// Description:
// =========================================================================#include "Hardware.h" void Hardware_init(void){PWM1_HardWare_State = PWM_OFF;PWM2_HardWare_State = PWM_OFF;PWM3_HardWare_State = PWM_OFF;PWM4_HardWare_State = PWM_OFF;Hardware_key_state = PWM_OFF;Hardware_USB_state = USB_IDLE;gcount_asleep = 0;
}void Hardware_run(void){fn_key_Check();fn_PWM1_Check(PWM1_Data);fn_PWM2_Check(PWM2_Data);fn_PWM3_Check(PWM3_Data);fn_PWM4_Check(PWM4_Data);ADC_Check();USB_In_Check();
}void delay_Hardware(unsigned char count){unsigned char i = 0;for(i = 0;i <= count;i++){ NOP(); NOP();NOP();}
}void Hardware_Start(void){unsigned char count_heart = 10;CE_OUT();while(count_heart-- > 0){while(bHardware_Start_100ms == 0){Hardware_run();delay_Hardware(100);}bHardware_Start_100ms = 0;}CE_Close();
}
3:ADC_CO.h
代码如下:
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/6/2022
// Description:
// =========================================================================#ifndef _ADC_CO_H_
#define _ADC_CO_H_
#include <ny8.h>
#include "ny8_constant.h"typedef union {struct{unsigned char BIT0:1;unsigned char BIT1:1;unsigned char BIT2:1;unsigned char BIT3:1;unsigned char BIT4:1;unsigned char BIT5:1;unsigned char BIT6:1;unsigned char BIT7:1;//unsigned char BIT8:1;unsigned char BIT9:1;unsigned char BIT10:1;unsigned char BIT11:1;//unsigned char BIT12:1;unsigned char BIT13:1;unsigned char BIT14:1;unsigned char BIT15:1;}DATA_BIT;unsigned char DATA_BYTE;
}Per_adc_type;extern volatile Per_adc_type adc_flag;#define badc_10ms_flag adc_flag.DATA_BIT.BIT0#define ad_finish_flag adc_flag.DATA_BIT.BIT1extern volatile unsigned int Count_Adc;
extern volatile unsigned int NTC_Value;
extern volatile unsigned int BAT_Value;void ADC_Check();
unsigned int ADC_get_value(unsigned char vref_value,unsigned char channal);void STDBY_TO_IN(void);
void STDBY_TO_OUT(void);
unsigned char STDBY_Get_Out(void);
#endif
4:ADC_CO.c
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/6/2022
// Description:
// =========================================================================#include "ADC_CO.h"
#include "Pwm_CO.h"
#include "GPIO_OUT.h"volatile Per_adc_type adc_flag;volatile unsigned int NTC_Value;
volatile unsigned int BAT_Value;/*依序设定ADC时钟(ADCLK),ADC采样时间,ADC位数,ADC参考电压(寄存器ADVREFH),选择模拟输
入通道并将寄存器PACON相应位设置为 1,再将GCHS位(寄存器ADMD[4])与ADEN位(寄存器ADMD[7])
设置为 1。 在ADEN设置为 1 后必须等待 256us(ADC电路启动时间),再将START位(寄存器ADMD[6])写 1 来启动ADC
模数转换。ADC转换尚未完成时,读取EOC位(寄存器ADMD[5])会得到 0。当ADC模数转换完成后会自动将
EOC位设置为 1。先设置ADEN=1(寄存器ADMD[7])
后须等待 256us,再将START(寄存器ADMD[6])写 1 来启动ADC模数转换。
读取寄存器EOC=0(寄存器ADMD[5])
表示ADC还在转换中,EOC=1 表示ADC已完成一次模数转换。如果寄存器ADIE=1
(寄存器ADR[6])与GIE设置为 1,在EOC自动从 0→1 后,中断标志ADIF
(寄存器ADR[7])位将被硬件设为 1
并处理此中断请求
*/void fn_adc_delay(unsigned char count){unsigned char i = 0;for(i = 0;i <= count;i++){NOP(); }
}
volatile unsigned int Count_Adc;
unsigned int ADC_get_value(unsigned char vref_value,unsigned char channal){volatile unsigned char AD_ValueL = 0;volatile unsigned int AD_Value = 0; ADVREFH = vref_value; //EVHENB = 0 | C_Vrefh_2V | C_Vrefh_3V | C_Vrefh_4V | C_Vrefh_VDDADR |= C_Ckl_Div16; //ADC转换时钟的选择8个时钟 低4位AD值 AD中断标志 ADCR |= C_Sample_8clk | C_12BIT; //ADC采样时钟 ADMD |= C_ADC_En | C_ADC_CH_En | channal ; //AD 通道 fn_adc_delay(60); ENI(); //GIEADIE = 1;ad_finish_flag = 0;Count_Adc = 0;ADMDbits.START = 1;while( !ad_finish_flag ){
// if(ADCSet_State == 0){
// OSCCR = 0X00;//先切入低速模式
// NOP();
// OSCCR = 0X0A;//然后停振高频进入待机模式保留低频唤醒。
// NOP();
// NOP();
// NOP();
// OSCCR = 0X01;
// NOP();
//
// TMR0 = 0xFF ;
// }NOP();}ADIE = 0;AD_ValueL = ( 0x0F & ADR); //低4位 AD_Value = ADD; //高8位 AD_Value <<= 4;AD_Value += AD_ValueL; //AD 值ADMD = 0x00;return AD_Value ;}void ADC_Check(void){ if(!badc_10ms_flag ){return;}badc_10ms_flag = 0;if( STDBY_Get_Out() == 1 ){NTC_Value = ADC_get_value(C_Vrefh_VDD,C_ADC_PA0);}//BAT_Value = ADC_get_value(C_Vrefh_3V,C_ADC_PA1); //testBAT_Value = ADC_get_value(C_Vrefh_3V,C_ADC_PB5);
} void STDBY_TO_IN(void){ //0 为输出 1 为输入IOSTA |= C_PA6_Input;APHCON &= ~C_PA6_PHB ;
}
void STDBY_TO_OUT(void){ //0 为输出 1 为输入IOSTA &= ~C_PA6_Input;APHCON |= C_PA6_PHB ;PA6 = 0;
} unsigned char STDBY_Get_Out(void) {if( (IOSTA & (C_PA6_Input)) == C_PA6_Output ){return 1;}return 0;
}
5:GPIO_OUT.h
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/7/2022
// Description:
// =========================================================================#ifndef _GPIO_OUT_H_
#define _GPIO_OUT_H_
#include <ny8.h>
#include "ny8_constant.h"
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/6/2022
// Description:
// =========================================================================#define GPIO_USBIn PB4
#define GPIO_STDBY PA6 #define GPIO_PWOUT_Cold PB3
#define GPIO_PWOUT_Hot PB2
#define PWOUT_Cold_OUT() GPIO_PWOUT_Cold = 1
#define PWOUT_Cold_Close() GPIO_PWOUT_Cold = 0
#define PWOUT_Hot_OUT() GPIO_PWOUT_Hot = 1
#define PWOUT_Hot_Close() GPIO_PWOUT_Hot = 0#define GPIO_OUT1 PA2
#define GPIO_OUT2 PA3
#define LED_Cold_OUT() GPIO_OUT2 = 1
#define LED_Hot_OUT() GPIO_OUT1 = 1
#define LED_Cold_Close() GPIO_OUT2 = 0
#define LED_Hot_Close() GPIO_OUT1 = 0#define GPIO_OUT3 PB1
#define GPIO_OUT4 PB0
#define Cold_EN() GPIO_OUT3 = 1
#define Hot_EN() GPIO_OUT4 = 1
#define Cold_Close() GPIO_OUT3 = 0
#define Hot_Close() GPIO_OUT4 = 0#define GPIO_CEOUT PA4
void CE_Close();
void CE_OUT();//#define GPIO_FAOUT PB5 //test
#define GPIO_FAOUT PA1
#define FA_OUT() GPIO_FAOUT = 1
#define FA_Close() GPIO_FAOUT = 0
//-------------------------------------
// 开关状态
extern volatile unsigned char Hardware_USB_state;
enum
{USB_IDLE = 0, USB_IN
};
void USB_In_Check(void);
#endif
6:GPIO_OUT.c
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/7/2022
// Description:
// =========================================================================
#include "GPIO_OUT.h"
#include "Sys_CO.h"
volatile unsigned char Hardware_USB_state;void USB_In_Check(void){ if(GPIO_USBIn == 1){gcount_asleep = 0; Hardware_USB_state = USB_IN ;}else{Hardware_USB_state = USB_IDLE ;}
}void CE_Close(void){ //关闭充电APHCON |= C_PA4_PHB; //上拉电阻控制寄存器 1,关闭上拉电阻IOSTA &= ~C_PA4_Input;GPIO_CEOUT = 0;
}
void CE_OUT(void){ //允许充电IOSTA |= C_PA4_Input;//---APHCON &= ~C_PA4_PHB; //上拉电阻控制寄存器 1,关闭上拉电阻
}
7:Key_CO.h
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/6/2022
// Description:
// =========================================================================#ifndef _KEY_CO_H_
#define _KEY_CO_H_
#include <ny8.h>
#include "ny8_constant.h"
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/6/2022
// Description:
// =========================================================================
#define KEY1_IN_GPIO_Pin PA7
#define KEY2_IN_GPIO_Pin PA5typedef union {struct{unsigned char BIT0:1;unsigned char BIT1:1;unsigned char BIT2:1;unsigned char BIT3:1;unsigned char BIT4:1;unsigned char BIT5:1;unsigned char BIT6:1;unsigned char BIT7:1;}DATA_BIT;unsigned char DATA_BYTE;
}Per_key_type;#define _LONG_key 200
extern volatile Per_key_type key1_flag;#define bkey1_10ms key1_flag.DATA_BIT.BIT0#define bkey1_judge key1_flag.DATA_BIT.BIT1#define bkey1_judge_long key1_flag.DATA_BIT.BIT2#define bkey1_Effect key1_flag.DATA_BIT.BIT3#define bkey1_LongEffect key1_flag.DATA_BIT.BIT4#define bkey1_Effect_Lose key1_flag.DATA_BIT.BIT5#define bkey1_Effect_LLose key1_flag.DATA_BIT.BIT6#define bkey1_change key1_flag.DATA_BIT.BIT7extern volatile Per_key_type key2_flag;#define bkey2_10ms key2_flag.DATA_BIT.BIT0#define bkey2_judge key2_flag.DATA_BIT.BIT1#define bkey2_judge_long key2_flag.DATA_BIT.BIT2#define bkey2_Effect key2_flag.DATA_BIT.BIT3#define bkey2_LongEffect key2_flag.DATA_BIT.BIT4#define bkey2_Effect_Lose key2_flag.DATA_BIT.BIT5#define bkey2_Effect_LLose key2_flag.DATA_BIT.BIT6#define bkey2_change key2_flag.DATA_BIT.BIT7//-------------------------------------
// 开关状态
extern volatile unsigned char Hardware_key_state;
enum
{Key_IDLE = 0, Key1_Effect,Key1_Long_Effect, Key2_Effect,Key2_Long_Effect,
};void fn_Key_Init(void);
void fn_key_judge(void);
void fn_key_Effect(void);
void fn_key_Check(void);#endif
8:Key_CO.c
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/6/2022
// Description:
// =========================================================================
#include "Key_CO.h"
#include "Sys_CO.h"
#include "GPIO_OUT.h"volatile Per_key_type key1_flag;
volatile Per_key_type key2_flag;
volatile unsigned char Hardware_key_state;static unsigned char count_key1 ;
void fn_key1_judge(void){if(!bkey1_10ms){return;}bkey1_10ms = 0;if(KEY1_IN_GPIO_Pin==0){gcount_asleep = 0;if(count_key1++<3){return;}if(!bkey1_judge){bkey1_judge = 1;bkey1_Effect = 1; }else{if(count_key1>_LONG_key){count_key1 = 0;if(!bkey1_judge_long){bkey1_judge_long = 1;bkey1_judge_long = 1;bkey1_LongEffect = 1;}}}}else{count_key1 = 0;if(bkey1_judge){if(bkey1_judge_long){bkey1_judge_long = 0;bkey1_Effect_LLose = 1;}else{bkey1_judge_long = 0;bkey1_Effect_Lose = 1;}} bkey1_judge = 0; }
}static unsigned char count_key2 ;
void fn_key2_judge(void){if(!bkey2_10ms){return;}bkey2_10ms = 0;if(KEY2_IN_GPIO_Pin==0){gcount_asleep = 0;if(count_key2++<3){return;}if(!bkey2_judge){bkey2_judge = 1;bkey2_Effect = 1; }else{if(count_key2>_LONG_key){count_key2= 0;if(!bkey2_judge_long){bkey2_judge_long = 1;bkey2_judge_long = 1;bkey2_LongEffect = 1;}}}}else{count_key2 = 0;if(bkey2_judge){if(bkey2_judge_long){bkey2_judge_long = 0;bkey2_Effect_LLose = 1;}else{bkey2_judge_long = 0;bkey2_Effect_Lose = 1;}}bkey2_judge = 0; }
}/************************************************************
* @brief
* void fn_key_Effect(void);
* @param
* @retval
*************************************************************/
void fn_key_Effect(void){if(bkey1_Effect_Lose){bkey1_Effect_Lose = 0; Hardware_key_state = Key1_Effect;}else if(bkey1_LongEffect){bkey1_LongEffect = 0; Hardware_key_state = Key1_Long_Effect; }else if(bkey2_Effect_Lose){bkey2_Effect_Lose = 0; Hardware_key_state = Key2_Effect;}else if(bkey2_LongEffect){bkey2_LongEffect = 0; Hardware_key_state = Key2_Long_Effect; }else{;}
}/************************************************************
* @brief
* void fn_key_Effect(void);
* @param
* @retval
*************************************************************/
void fn_key_Check(void){fn_key1_judge();fn_key2_judge();fn_key_Effect();
}
9:Pwm_CO.h
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/7/2022
// Description:
// =========================================================================
#ifndef _PWM_CO_H_
#define _PWM_CO_H_
#include <ny8.h>
#include "ny8_constant.h"#define P_PWM1_OUT PB3
#define P_PWM2_OUT PB2
#define P_PWM1_close() P_PWM1_OUT = 0;
#define P_PWM2_close() P_PWM2_OUT = 0;#define P_PWM3_OUT PA2
#define P_PWM4_OUT PA3#define P_PWM3_close() P_PWM3_OUT = 0;
#define P_PWM4_close() P_PWM3_OUT = 0;#define PWM1_L_MAX 0xFF
#define PWM1_H_MAX 0x03
#define PWM1_VAL_MAX 0x03FF
#define PWM1_VAL_MIN 0x0000#define PWM2_L_MAX 0xFF
#define PWM2_H_MAX 0x03
#define PWM2_VAL_MAX 0x03FF
#define PWM2_VAL_MIN 0x0000#define PWM3_VAL_MAX 0xFF
#define PWM3_VAL_MIN 0x00#define PWM4_VAL_MAX 0xFF
#define PWM4_VAL_MIN 0x00typedef union {struct{unsigned char BIT0:1;unsigned char BIT1:1;unsigned char BIT2:1;unsigned char BIT3:1;unsigned char BIT4:1;unsigned char BIT5:1;unsigned char BIT6:1;unsigned char BIT7:1;//unsigned char BIT8:1;unsigned char BIT9:1;unsigned char BIT10:1;unsigned char BIT11:1;//unsigned char BIT12:1;unsigned char BIT13:1;unsigned char BIT14:1;unsigned char BIT15:1;}DATA_BIT;unsigned char DATA_BYTE;
}Per_pwm_type;extern volatile Per_pwm_type pwm_flag;#define b_pwm1_start pwm_flag.DATA_BIT.BIT0#define b_pwm2_start pwm_flag.DATA_BIT.BIT1#define b_pwm3_start pwm_flag.DATA_BIT.BIT2#define b_pwm4_start pwm_flag.DATA_BIT.BIT3//-------------------------------------
// 开关状态
#define PWM_OFF 0
#define PWM_ON 1
extern volatile Per_pwm_type pwm_state_flag;#define PWM1_HardWare_State pwm_state_flag.DATA_BIT.BIT0#define PWM2_HardWare_State pwm_state_flag.DATA_BIT.BIT1#define PWM3_HardWare_State pwm_state_flag.DATA_BIT.BIT2#define PWM4_HardWare_State pwm_state_flag.DATA_BIT.BIT3extern volatile unsigned int PWM1_Data;
extern volatile unsigned int PWM2_Data;
extern volatile unsigned char PWM3_Data;
extern volatile unsigned char PWM4_Data;void fn_PWM1_Check(unsigned int PWM_Value);
void fn_PWM2_Check(unsigned int PWM_Value);
void fn_PWM3_Check(unsigned char PWM_Value);
void fn_PWM4_Check(unsigned char PWM_Value); void fn_PWM1_OFF(void);
void fn_PWM2_OFF(void);
void fn_PWM3_OFF(void);
void fn_PWM4_OFF(void);
#endif
10:Pwm_CO.c
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/7/2022
// Description:
// =========================================================================
#include "Pwm_CO.h"volatile Per_pwm_type pwm_flag;
volatile Per_pwm_type pwm_state_flag;volatile unsigned int PWM1_Data = 0;
volatile unsigned int PWM2_Data = 0;
volatile unsigned char PWM3_Data = 0;
volatile unsigned char PWM4_Data = 0;/*
// Initialize Timer1/2 & PWM1/2TMRH = C_TMR2_Data_b9 | C_TMR2_Data_b8 | C_TMR1_Data_b9 | C_TMR1_Data_b8 | C_PWM2_Duty_b9 | C_PWM2_Duty_b8;TMR1 = 0xFF; // TMR1[9:0]=3FFHTMR2 = 0xFF; // TMR2[9:0]=3FFHPWM1DUTY = 0x01; // PWM1DUTY[9:0]=001HPWM2DUTY = 0xFF; // PWM2DUTY[9:0]=3FFHT1CR2 = C_PS1_Dis | C_TMR1_ClkSrc_Inst; // Prescaler 1:1, Timer1 clock source is instruction clockT2CR2 = C_PS2_Dis | C_TMR2_ClkSrc_Inst; // Prescaler 1:1, Timer2 clock source is instruction clockT1CR1 = C_PWM1_En | C_PWM1_Active_Hi | C_TMR1_Reload | C_TMR1_En; // Enable PWM1, Active_High, Non-Stop mode, Reloaded from TMR1[9:0], Enable Timer1T2CR1 = C_PWM2_En | C_PWM2_Active_Hi | C_TMR2_Reload | C_TMR2_En; // Enable PWM2, Active_High, Non-Stop mode, Reloaded from TMR2[9:0], Enable Timer2
*/
void fn_PWM1_run(unsigned int PWM1_VAL) {volatile unsigned char T1DATAL = 0;volatile unsigned char T1DATAH = 0;if(PWM1_VAL == PWM1_VAL_MAX){T1CR1 = 0x00;b_pwm1_start = 0;P_PWM1_OUT = 1;}else if(PWM1_VAL == PWM1_VAL_MIN){T1CR1 = 0x00;b_pwm1_start = 0;P_PWM1_OUT = 0;}else{T1DATAL = ( unsigned char )(PWM1_VAL &(0x00FF));T1DATAH = ( unsigned char )((PWM1_VAL>>8)&(0x0003));if(b_pwm1_start == 0){ TMRH = 0x30; //(定时器 1 高字节寄存器) TMR1 = 0xFF; T1CR2 = C_PS1_Div2; // 2分频 T1CR1 = C_PWM1_En | C_PWM1_Active_Hi | C_TMR1_Reload | C_TMR1_En; // PWM1DUTY = T1DATAL;b_pwm1_start= 1;}TMRH = (TMRH & 0xFC )|(T1DATAH & 0x03);PWM1DUTY = T1DATAL;}
}void fn_PWM1_OFF(void){T1CR1 = 0x00;b_pwm1_start = 0;P_PWM1_OUT = 0;
}void fn_PWM1_Check(unsigned int PWM_Value){if (PWM1_HardWare_State == PWM_ON){fn_PWM1_run(PWM_Value);}else {fn_PWM1_OFF();}
}//=================================================================void fn_PWM2_run(unsigned int PWM2_VAL) {volatile unsigned char T2DATAL = 0;volatile unsigned char T2DATAH = 0;if(PWM2_VAL == PWM1_VAL_MAX){T2CR1 = 0x00;b_pwm2_start = 0;P_PWM2_OUT = 1;}else if(PWM2_VAL == PWM2_VAL_MIN){T2CR1 = 0x00;b_pwm2_start = 0;P_PWM2_OUT = 0;}else{T2DATAL = ( unsigned char )(PWM2_VAL &(0x00FF));T2DATAH = ( unsigned char )((PWM2_VAL>>8)&(0x0003));if(b_pwm2_start == 0){ TMRH = 0xC0; //(定时器 1 高字节寄存器) TMR2 = 0xFF; T2CR2 = C_PS2_Div2; // 2分频 T2CR1 = C_PWM2_En | C_PWM2_Active_Hi | C_TMR2_Reload | C_TMR2_En; // PWM1DUTY = T1DATAL;b_pwm2_start = 1;}TMRH = (TMRH & 0xF3)|((T2DATAH << 2 )& 0x0C);PWM2DUTY = T2DATAL;}
}void fn_PWM2_OFF(void){T2CR1 = 0x00;b_pwm2_start = 0;P_PWM2_OUT = 0;
}void fn_PWM2_Check(unsigned int PWM_Value){if (PWM2_HardWare_State == PWM_ON){fn_PWM2_run(PWM_Value);}else {fn_PWM2_OFF();}
}//=================================================================
// Initialize Timer3 & PWM3/4
/*TM3RH = C_TMR3_Data_b9 | C_TMR3_Data_b8 | C_PWM4_Duty_b9 | C_PWM3_Duty_b9 | C_PWM3_Duty_b8;TMR3 = 0xFF; // TMR3[9:0]=3FFHPWM3DUTY = 0x00; // PWM3DUTY[9:0]=300HPWM4DUTY = 0x00; // PWM4DUTY[9:0]=200HT3CR2 = C_PS3_Dis | C_TMR3_ClkSrc_Inst; // Prescaler 1:1, Timer3 clock source is instruction clockT3CR1 = C_PWM3_En | C_PWM3_Active_Hi | C_TMR3_Reload | C_TMR3_En; // Enable PWM3, Active_High, Non-Stop mode, Reloaded from TMR3[9:0], Enable Timer3P4CR1 = C_PWM4_En | C_PWM4_Active_Hi; // Enable PWM4, Active_High*/
void fn_PWM3_run(unsigned char PWM3_VAL) {if(PWM3_VAL == PWM3_VAL_MAX){ P_PWM3_OUT = 1;T3CR1 &= (~(C_PWM3_En));b_pwm3_start = 0;}else{if(b_pwm3_start == 0){ TM3RH = 0x00; //(定时器 1 高字节寄存器) TMR3 = 0xFF; T3CR2 = C_PS3_Dis | C_TMR3_ClkSrc_Inst; // 2分频 T3CR1 = C_PWM3_En | C_PWM3_Active_Hi | C_TMR3_Reload | C_TMR3_En; // PWM1DUTY = T1DATAL;b_pwm3_start= 1;} }PWM3DUTY = PWM3_VAL;
}void fn_PWM3_OFF(void){P_PWM3_OUT = 0;T3CR1 &= (~(C_PWM3_En));b_pwm3_start = 0;}void fn_PWM3_Check(unsigned char PWM_Value){if (PWM3_HardWare_State == PWM_ON){fn_PWM3_run(PWM_Value);}else if(PWM3_HardWare_State == PWM_OFF){fn_PWM3_OFF();}else{;}
}//=================================================================
// Initialize Timer3 & PWM3/4
/*TM3RH = C_TMR3_Data_b9 | C_TMR3_Data_b8 | C_PWM4_Duty_b9 | C_PWM3_Duty_b9 | C_PWM3_Duty_b8;TMR3 = 0xFF; // TMR3[9:0]=3FFHPWM3DUTY = 0x00; // PWM3DUTY[9:0]=300HPWM4DUTY = 0x00; // PWM4DUTY[9:0]=200HT3CR2 = C_PS3_Dis | C_TMR3_ClkSrc_Inst; // Prescaler 1:1, Timer3 clock source is instruction clockT3CR1 = C_PWM3_En | C_PWM3_Active_Hi | C_TMR3_Reload | C_TMR3_En; // Enable PWM3, Active_High, Non-Stop mode, Reloaded from TMR3[9:0], Enable Timer3P4CR1 = C_PWM4_En | C_PWM4_Active_Hi; // Enable PWM4, Active_High*/
void fn_PWM4_run(unsigned char PWM4_VAL) { PWM4DUTY = PWM4_VAL; if(PWM4_VAL == PWM4_VAL_MAX){ P_PWM4_OUT = 1;P4CR1 &= ~( C_PWM4_En);b_pwm4_start = 0;}else{if(b_pwm4_start == 0){ P_PWM4_OUT = 1;TM3RH = 0x00; //(定时器 1 高字节寄存器) TMR3 = 0xFF; T3CR2 = C_PS3_Dis | C_TMR3_ClkSrc_Inst; // 2分频 T3CR1 = C_PWM3_Active_Hi | C_TMR3_Reload | C_TMR3_En; // Enable PWM3, Active_High, Non-Stop mode, Reloaded from TMR3[9:0], Enable Timer3P4CR1 = C_PWM4_En | C_PWM4_Active_Hi; // Enable PWM4, Active_Highb_pwm4_start = 1;}}}void fn_PWM4_OFF(void){P_PWM4_OUT = 0;P4CR1 &= ~( C_PWM4_En);b_pwm4_start = 0;}void fn_PWM4_Check(unsigned char PWM_Value){if (PWM4_HardWare_State == PWM_ON){fn_PWM4_run(PWM_Value);}else{fn_PWM4_OFF();}
}
11:Sys_CO.h
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/7/2022
// Description:
// =========================================================================
#ifndef _Sys_CO_H_
#define _Sys_CO_H_
#include <ny8.h>
#include "ny8_constant.h"#define CST_reload_T0 0typedef union {struct{unsigned char BIT0:1;unsigned char BIT1:1;unsigned char BIT2:1;unsigned char BIT3:1;unsigned char BIT4:1;unsigned char BIT5:1;unsigned char BIT6:1;unsigned char BIT7:1;}DATA_BIT;unsigned char DATA_BYTE;
}Per_sys_type;extern volatile Per_sys_type sof_sys_flag;#define b_asleep100ms sof_sys_flag.DATA_BIT.BIT0 #define b_asleep sof_sys_flag.DATA_BIT.BIT1#define bHardware_Start_100ms sof_sys_flag.DATA_BIT.BIT2
extern volatile unsigned char gcount_asleep; void clear_memory(void);
void GPIO_Init(void);
void ADIO_Init(void);
void Time0_init(void);
void fn_sys_reset( void ); #endif
12:Sys_CO.c
// =========================================================================
// Created by NYIDE.
// User: 23045
// Date: 7/7/2022
// Description:
// =========================================================================#include "Sys_CO.h"volatile unsigned char gcount_asleep;
volatile Per_sys_type sof_sys_flag;void clear_memory(void)
{
//R-page特殊功能寄存器和数据存储器分为四组Bank,
//可透过数据指针寄存器(FSR)来切换Bank。寄存器BK[1:
//0]为STATUS[7:6],可从四个Bank中选择其中一个
//功能寄存器只存在于Bank 0。GPR占用了Bank 0 数据存储器的 0x20 到 0x7F与BankSTATUS=0x00;for(FSR =0x20; FSR<=0x7F; FSR++) {INDF = 0; } STATUS=0x40;for(FSR =0x20; FSR<=0x3F; FSR++) {INDF = 0; }
}void GPIO_Init(void){// Initialize GPIOIOSTA = C_PA_Input; // PortA as inputIOSTB = C_PB_Input; // PortA as inputPORTA = 0x00; // PortA output lowPORTB = 0x00;IOSTA = (( C_PA0_Input )|( C_PA1_Output )|( C_PA2_Output )|( C_PA3_Output )|(C_PA4_Output )|(C_PA5_Input )|( C_PA6_Input )|( C_PA7_Input )); IOSTB = (( C_PB0_Output )|( C_PB1_Output )|( C_PB2_Output )|( C_PB3_Output )|( C_PB4_Input )|( C_PB5_Input ));//IOSTA = (( C_PA0_Input )|( C_PA1_Input )|( C_PA2_Output )|( C_PA3_Output )|(C_PA4_Output )|(C_PA5_Input )|( C_PA6_Input )|( C_PA7_Input )); //IOSTB = (( C_PB0_Output )|( C_PB1_Output )|( C_PB2_Output )|( C_PB3_Output )|( C_PB4_Input )|( C_PB5_Output )); //testAPHCON = 0xFF ^ ((C_PA6_PHB)|(C_PA7_PHB)); //上拉电阻控制寄存器 1,关闭上拉电阻ABPLCON = 0xFF; //下拉电阻控制寄存器 1,关闭下拉电阻PHPA5 = 0; ///PHPA5=1 时,关闭PA5 上拉电阻。BPHCON = C_PB_PHB ; //上拉电阻控制寄存器 1,关闭上拉电阻//BPHCON = C_PB_PHB ^ (C_PB4_PHB) ; //testAWUCON = (( C_PA5_Wakeup )|( C_PA7_Wakeup )); //WUPAx=1 时,开启PAx唤醒功能BWUCON = ( C_PB4_Wakeup); BODCON = 0X00; //0B0000 0000;0关闭,1开漏 PA默认开漏输出
}void ADIO_Init(void){PACON = ( C_PA0_AIN0 )|( C_PA1_AIN1 ); //ADC 引脚数模控制寄存器 PACON0=1作为ADC模拟输入引脚。ADCR = ((C_PB5_AIN10)) ; //PBCON5/PBCON4/PBCON3/SHCK1/SHCK0/ADCR1/ADCR0
}void Time0_init(void){PCON1 = C_TMR0_Dis; //T0EN=0 GIE=0TMR0 = ( 0XFF - CST_reload_T0 ); //递增定时器 1us*50=100us 装载值//T0MD = C_PS0_TMR0 | C_PS0_Div4 ; //2分屏 100*1=100usT0MD = C_PS0_TMR0 | C_PS0_Div8; //test//Setting Interrupt Enable RegisterINTE=0x45; //中断使能寄存器(T0IE=1,WDTIE=1)//;Enable Timer0 & Global interrupt bit PCON1 |= C_TMR0_En; // Enable Timer0 T0EN=1; GIE=1;T0IE = 1; // Enable all unmasked interrupts T0IF=0;WDTIF=0;ENI();
}//{-------------------系统复位子程序-----------------------
void fn_sys_reset( void ) //系统复位子程序
{// Initialize SystemPCON = C_LVR_En|C_LVR_En|C_LVD_En&(~C_WDT_En); // Enable WDT & LVRDISI();CLRWDT();GPIO_Init();ADIO_Init();Time0_init();OSCCR = C_FHOSC_Sel; //高频振荡器打开
}
总结
一.开关机及切换测试 :
1.长按图案对应热敷开关键2秒,加热功能开启短按一次指示灯变红色;依此循环长按2秒热敷键关掉。
2.长按图案对应冷熬开关键2秒,冷熬功能开启短按一次指示灯变蓝色;依此循环长按3秒冷敷键关掉。
3.S1 S2 : 长按开关机,断案切换模式,指示灯会随着变化。
二.温度控制测试 :热敷与冷敷,目前设计为P控制
所以会在电池电压不一样的时候制冷片功率不同,导致制热制冷效果有一些区别,目前制冷状态我这边测试:制冷一档18-20°C制冷二档10-15°C
制热一档44-47°C
制冷二档49-52°C二.低电压保护测试:
无负载时候,当电量低于3.35V时强制关机,低电关机后,重启开机电压3.56V。
有负载时候,当电量低于3.07V时强制关机,(电池电压为3.34V),低电关机后,重启开机电压3.56V。测试中途开机3.3V低电压识别保护,3.5V低电压识别,3.6V状态恢复识别。
三.自动关机测试:开机进入使用状态后 在最后一次能操作后10分钟 偏差10S 自动关机。四. 充电测试:适配器5V2A,充电需有独立充电0.574C,充至4.12V变灯充满,4.2V强制停止充电,充电时间2H-2.5H,充电电流到电芯不能大于0.574A,充电不工作,按键无效。
超过3小时关闭充电功能。1).充电模式显示:充电状态下,呼吸灯变化,通过呼吸灯颜色显示当前电量。
4.15V~以上 (红色灯长亮)
3.3V~4.15V (红色呼吸灯)充电过程中关闭所有的功能操作。测试点: 开机下插入充电口,充电电流为574mA 指示灯闪烁。其他功能关闭风扇关闭。关机下插入充电口,充电电流为574mA 指示灯闪烁。4.12V 测试充电充满状态指示灯亮起来停止闪烁为高亮,电压低于3.92V LED充电闪烁状态恢复。五.功耗:
5.关机电流静态电流≤10uA 旧电路
6.待机功耗为1034UA
这篇关于基于通用单片机(久齐) 半导体制冷制热的控制 手机散热器按摩仪器中冷热头的控制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!