找回密码
 立即注册
查看: 175|回复: 8

即热式恒温电热水龙头原码

[复制链接]
  • 打卡等级:常住居民III
  • 打卡总天数:137
  • 最近打卡:2025-05-01 00:01:04

6

主题

277

回帖

1108

积分

金牌会员

积分
1108
发表于 2025-3-3 15:04:36 | 显示全部楼层 |阅读模式
#include <STC8H.h>#define FLOW_SENSOR_PIN P32             //流量传感器P3.2  INTE0#define IN_NTC_PIN P10                                // 进水 NTCP1.0#define OUT_NTC_PIN P11                     // 出水 NTCP1.1#define HEATING_CTRL_PIN P33            // PWM 信号控制加热设备的功率#define UP_KEY_PIN P34                               // 按键+ #define DOWN_KEY_PIN P35                 // 按键-#define DIG1_PIN P20                                 //位选1 #define DIG2_PIN P21                                 //位选2unsigned int flow_count = 0;                  // 水流量脉冲计数float in_temp = 0.0;                                   // 进水温度 float out_temp = 0.0;                                  // 出水温度bit heating_flag = 0;                                   // 加热标志 1加热 0停止加热float set_temp = 40.0;                                 // 预设定出水温度unsigned int timer0_count = 0;              // 定时器 0 计数变量unsigned int show_set_temp_timer = 0;  // 显示设定温度的时间变量bit show_set_temp_flag = 0;                   // 显示设定温度标志位  1设定温度  0出水温度bit flow_detected = 0;                                 // 水流检测标志位 1 检测到水流 0未检测到水流unsigned int pwm_duty = 0;                  // PWM 占空比0 - 100加热设备功率调节unsigned int pwm_period = 100;           // PWM 周期,确定 PWM 信号一个周期时长unsigned int initial_full_heat_timer = 0; // 初始全功率加热计时bit is_initial_full_heat = 1;                      //全功率加热标志位 1 加热 0 结束                                                           // 数码管段码表(共阳极)unsigned char SEG_CODE[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};#define SPECIFIC_HEAT_WATER 4200    // 水的比热容(J/(kg·℃))#define HEATING_POWER 3000            //最高加热功率3000W void ADC_Init()                                      // ADC 初始化函数  {  ADC_CONTR = 0x80;                      // 使能 ADC 电源    while (timer0_count < 1);               // 延时 1ms等待 ADC 电源稳定    timer0_count = 0;                             //将定时器 0 计数变量清零        ADC_CONTR |= 0x08;                       // 启动 ADC 转换  8 分频 }unsigned int Read_ADC(unsigned char channel)   // 读取 ADC 值函数 {    ADC_CONTR &= 0xF0;                    // 清除通道选择位      ADC_CONTR |= channel;                 // 设置要转换的通道        ADC_CONTR |= 0x40;                      // 启动 ADC 转换           while (!(ADC_CONTR & 0x20));        // 等待转换完成    ADC_CONTR &= ~0x20;                 //清除转换完成标志        return (ADC_RES << 2) | (ADC_RESL & 0x03);   // 返回 10 位 ADC 值     }float ntc_to_temp(unsigned int adc_value)        // NTC 温度转换函数  {    // 根据 ADC 值计算对应的电压值,假设参考电压为 5V    float voltage = (float)adc_value * 5.0 / 1023.0;     // 根据电压值计算 NTC 热敏电阻的阻值,假设上拉电阻为 10K    float resistance = (5.0 - voltage) * 10000 / voltage;     // 通过简单的线性关系将电阻值转换为温度值,实际应用中需校准    float temperature = (resistance - 10000) / 38.5;     return temperature;}void EX0_Init()                               // 外部中断 0 初始化函数 {    IT0 = 1;                                     // 设置外部中断 0 为下降沿触发    EX0 = 1;                                    // 使能外部中断 0     EA = 1;                                     // 全局中断使能     }void EX0_ISR() interrupt 0             // 外部中断 0 服务函数  {    flow_count++;                          // 水流量脉冲计数加 1        flow_detected = 1;                   // 水流检测标志位置 1  }bit Key_Debounce(bit key_pin)     // 按键检测函数 {    if (!key_pin)                              // 检测按键是否按下       {        while (timer0_count < 10);   // 消抖延时 10ms        timer0_count = 0;                //将定时器0计数变量清零        if (!key_pin)                          // 再次检测按键是否仍然按下   {            while (!key_pin);               // 等待按键释放            return 1;                          // 按键操作有效,返回 1          }     }   return 0;   // 按键操作无效,返回 0   }unsigned int calculate_pwm_duty()   // 计算所需 PWM 占空比函数 {    // 假设水流量传感器每脉冲代表的水体积(L),需根据实际传感器校准    float water_volume_per_pulse = 0.01;     // 计算水流量(kg/s),假设水的密度为 1kg/L    float water_flow_rate = flow_count * water_volume_per_pulse;     // 计算温度差,即设定温度与进水温度的差值    float temp_diff = set_temp - in_temp;     // 计算所需加热功率(W),根据比热容公式计算    float required_power = water_flow_rate * SPECIFIC_HEAT_WATER * temp_diff;     // 计算 PWM 占空比,根据所需功率与设定加热功率的比例计算    unsigned int duty = (unsigned int)((required_power / HEATING_POWER) * 100);    // 确保占空比不超过 100  if (duty > 100)   {        duty = 100;     }    return duty; }void Heating_Control()         // 加热控制函数 {  if (flow_detected)    {        // 计算设定温度与进水温度的差值        float temp_diff = set_temp - in_temp;        // 假设水流量传感器每脉冲代表的水体积(L),需根据实际传感器校准        float water_volume_per_pulse = 0.01;         // 计算水流量(kg/s),假设水的密度为 1kg/L        float water_flow_rate = flow_count * water_volume_per_pulse;         unsigned int full_heat_time;        // 根据水流量和温差动态调整初始全功率加热时间        if (water_flow_rate > 0.5 && temp_diff > 10) {            // 流量大且温差大,将初始全功率加热时间延长到 3 秒            full_heat_time = 3000;         } else if (water_flow_rate < 0.1 && temp_diff < 5) {            // 流量小且温差小,将初始全功率加热时间缩短到 1 秒            full_heat_time = 1000;         } else {            // 其他情况,保持初始全功率加热时间为 2 秒            full_heat_time = 2000;         }        if (is_initial_full_heat) {            // 处于初始全功率加热阶段,PWM 占空比设为 100%            pwm_duty = 100;             // 初始全功率加热计时加 1            initial_full_heat_timer++;            if (initial_full_heat_timer >= full_heat_time) {                 // 达到设定的初始全功率加热时间                // 结束初始全功率加热阶段                is_initial_full_heat = 0;                // 初始全功率加热计时清零                initial_full_heat_timer = 0;                // 根据计算结果设置 PWM 占空比                pwm_duty = calculate_pwm_duty();            }        } else {            // 已结束初始全功率加热阶段,根据计算结果设置 PWM 占空比            pwm_duty = calculate_pwm_duty();        }        // 开启加热标志        heating_flag = 1;  }   else    {        pwm_duty = 0;           // 未检测到水流,PWM 占空比设为 0        heating_flag = 0;          // 关闭加热标志        is_initial_full_heat = 1;     // 下次有水流时重新进入初始全功率加热阶段         initial_full_heat_timer = 0;  // 初始全功率加热计时清零      } }// 数码管显示函数,在数码管上显示指定的温度值void Display_Temperature(float temp)  {    // 定义两个变量,用于存储温度值的十位和个位数字    unsigned char digit1, digit2;    // 将温度值转换为整数    int temp_int = (int)temp;    // 提取温度值的十位数字    digit1 = temp_int / 10;    // 提取温度值的个位数字    digit2 = temp_int % 10;    // 显示第一位    // 选中数码管的第一位    DIG1_PIN = 0;    // 取消选中数码管的第二位    DIG2_PIN = 1;    // 将十位数字对应的段码输出到数码管    P0 = SEG_CODE[digit1];    // 延时 5ms,确保数码管显示稳定    while (timer0_count < 5);     // 延时结束后,将定时器 0 计数变量清零,为下一次计时做准备    timer0_count = 0;    // 显示第二位    // 取消选中数码管的第一位    DIG1_PIN = 1;    // 选中数码管的第二位    DIG2_PIN = 0;    // 将个位数字对应的段码输出到数码管    P0 = SEG_CODE[digit2];    // 延时 5ms,确保数码管显示稳定    while (timer0_count < 5);     // 延时结束后,将定时器 0 计数变量清零,为下一次计时做准备    timer0_count = 0; }void Timer0_Init()                         // 定时器 0 初始化函数 {    TMOD &= 0xF0;                      // 清除定时器 0 模式位,不受之前的影响     TMOD |= 0x01;                        // 设置定时器 0 为模式 1(16 位定时器)    TH0 = (65536 - 1000) / 256;    // 设置定时器 0 的初值,使其定时 1ms    TL0 = (65536 - 1000) % 256;    ET0 = 1;                             // 使能定时器 0 中断    TR0 = 1;                             // 启动定时器 0}void Timer1_Init()                       // 定时器 1 初始化函数 {    TMOD &= 0x0F;                   // 清除定时器 1 模式位,不受之前的影响    TMOD |= 0x10;                      // 设置定时器 为模式 1(16 位定时器)    TH1 = (65536 - 100) / 256;    // 设置定时器 1 的初值,使其定时 100us    TL1 = (65536 - 100) % 256;    ET1 = 1;                  // 使能定时器 1 中断    TR1 = 1;                                // 启动定时器 1 }void main() {  unsigned int in_adc_value, out_adc_value;  //进水和出水的 ADC 值    Timer0_Init();                        // 调用定时器 0 初始化函数    Timer1_Init();                  //定时器 1 初始化函数,产生 PWM 信号来控制加热设备的功率    ADC_Init();                    //ADC 初始化函数    EX0_Init();                    //外部中断 0 初始化函数,够响应水流量传感器的脉冲信号    HEATING_CTRL_PIN = 0;          //将加热控制引脚置为低电平  while (1)   {   if (flow_count == 0)          // 检查水流量脉冲计数是否为 0           {              flow_detected = 0;     //将水流检测标志置为 0           }       in_adc_value = Read_ADC(0);                     //读取进水 NTC的adc值       in_temp = ntc_to_temp(in_adc_value);       //进水温度值存入 in_temp 变量中       out_adc_value = Read_ADC(1);                  //读取出水 NTC的 AD值       out_temp = ntc_to_temp(out_adc_value);  //出水温度值存入 out_temp 变量中              if (Key_Debounce(UP_KEY_PIN))          // 检测温度调节按键“+”是否被按下     {            if (set_temp < 50)                          //当前设定温度小于 50°C     {                 set_temp += 1;                         // 将设定温度加 1°C                 show_set_temp_flag = 1;          // 显示设定温度的标志位置 1(显示设定温度)                 show_set_temp_timer = 0;        // 将显示设定温度的计时变量清零,重新开始计时              }          }               if (Key_Debounce(DOWN_KEY_PIN))  // 检测温度调节按键“-”是否被按下     {            if (set_temp > 10)                         //当前设定温度大于 10°C              {                set_temp -= 1;                          // 将设定温度减 1°C                show_set_temp_flag = 1;          // 显示设定温度的标志位置 1(显示设定温度)                show_set_temp_timer = 0;        // 将显示设定温度的计时变量清零,重新开始计时              }           }        Heating_Control();                           //调用加热控制函数                if (show_set_temp_flag)                   // 如果显示设定温度的标志位为 1     {           Display_Temperature(set_temp);  //在数码管上显示设定温度          }    else                                                 // 如果显示设定温度的标志位为 0     {           Display_Temperature(out_temp); //数码管上显示出水温度          }        while (timer0_count < 10);             // 等待定时器 0 计数达到 10,实现 10ms 的延时        timer0_count = 0;                          //将定时器 0 计数变量清零    }}void Timer0_ISR() interrupt 1                    // 定时器 0 中断服务函数 {    TH0 = (65536 - 1000) / 256;     TL0 = (65536 - 1000) % 256;    timer0_count++;                                  // 定时器 0 计数变量加 1  if (show_set_temp_flag)                        // 显示设定温度标志位  1设定温度    {        show_set_temp_timer++;                 // 显示设定温度的计时变量加 1        if (show_set_temp_timer >= 5000)   // 显示设定温度的时间达到 5 秒          {             show_set_temp_flag = 0;             // 关闭显示设定温度的标志            show_set_temp_timer = 0;           // 显示设定温度的计时变量清零          }       }  }          void Timer1_ISR() interrupt 3                   // 定时器 1 中断服务函数,产生 PWM 信号  {    static unsigned int pwm_counter = 0;  // 静态变量,用于记录 PWM 信号的计数值    TH1 = (65536 - 100) / 256;     TL1 = (65536 - 100) % 256;    pwm_counter++;                                       // PWM 计数值加 1   if (pwm_counter < pwm_duty)  {        HEATING_CTRL_PIN = 1;                 // 在占空比范围内,输出高电平    } else     {         HEATING_CTRL_PIN = 0;              // 超出占空比范围,输出低电平      } if (pwm_counter >= pwm_period)     // 达到 PWM 周期,   {        pwm_counter = 0;                        //  PWM 计数值清零,开始下一个周期         }  }[color=var(--code-text_v3)]学单片机好几年了,还是写不好。总有些小毛病,有没有人能给看一下。
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:137
  • 最近打卡:2025-05-01 00:01:04

6

主题

277

回帖

1108

积分

金牌会员

积分
1108
发表于 2025-3-3 15:05:52 | 显示全部楼层
怎么发出来是这样的,不是一行一行的呢?这样怎么看。
回复 支持 反对

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 2025-3-3 15:08:00 | 显示全部楼层
您好,您提供的代码片段是一个即热式恒温电热水龙头的控制程序框架。从代码中可以看出,系统通过流量传感器(FLOW_SENSOR_PIN)检测水流状态,并利用进水(IN_NTC_PIN)和出水(OUT_NTC_PIN)温度传感器进行温度监控。通过PWM信号(HEATING_CTRL_PIN)控制加热设备的功率,实现恒温功能。此外,还定义了按键引脚(UP_KEY_PIN)用于用户交互。

建议在实际开发中,进一步优化PID控制算法,以实现更精确的温度调节。同时,确保各传感器的校准和稳定性,以提高系统的可靠性和用户体验。如有需要,可考虑加入故障检测和异常处理机制,增强系统的安全性。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:135
  • 最近打卡:2025-05-01 08:09:26
已绑定手机

2

主题

82

回帖

194

积分

注册会员

积分
194
发表于 2025-3-3 15:32:39 | 显示全部楼层
太乱了。
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:108
  • 最近打卡:2025-04-28 08:34:00
已绑定手机

5

主题

118

回帖

674

积分

高级会员

积分
674
发表于 2025-3-3 16:51:55 | 显示全部楼层
高级软件工程师-唐工
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:422
  • 最近打卡:2025-05-01 09:54:52
已绑定手机

19

主题

3190

回帖

4866

积分

论坛元老

积分
4866
发表于 2025-3-3 17:11:20 | 显示全部楼层
这编辑的真差,怎么不用插入代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:137
  • 最近打卡:2025-05-01 00:01:04

6

主题

277

回帖

1108

积分

金牌会员

积分
1108
发表于 2025-3-3 20:19:18 | 显示全部楼层
[code]/*Keil 软件“设置”--- “Editor”,在 “Encoding” 下拉框中选择 “Chinese-GB2312” */
#include <STC8H.h>

#define FLOW_SENSOR_PIN P32             //流量传感器P3.2  INTE0
#define IN_NTC_PIN P10                                // 进水 NTCP1.0
#define OUT_NTC_PIN P11                     // 出水 NTCP1.1
#define HEATING_CTRL_PIN P33            // PWM 信号控制加热设备的功率
#define UP_KEY_PIN P34                               // 按键+
#define DOWN_KEY_PIN P35                 // 按键-
#define DIG1_PIN P20                                 //位选1
#define DIG2_PIN P21                                 //位选2

unsigned int flow_count = 0;                  // 水流量脉冲计数
float in_temp = 0.0;                                   // 进水温度
float out_temp = 0.0;                                  // 出水温度
bit heating_flag = 0;                                   // 加热标志 1加热 0停止加热
float set_temp = 40.0;                                 // 预设定出水温度
unsigned int timer0_count = 0;              // 定时器 0 计数变量
unsigned int show_set_temp_timer = 0;  // 显示设定温度的时间变量
bit show_set_temp_flag = 0;                   // 显示设定温度标志位  1设定温度  0出水温度
bit flow_detected = 0;                                 // 水流检测标志位 1 检测到水流 0未检测到水流
unsigned int pwm_duty = 0;                  // PWM 占空比0 - 100加热设备功率调节
unsigned int pwm_period = 100;           // PWM 周期,确定 PWM 信号一个周期时长
unsigned int initial_full_heat_timer = 0; // 初始全功率加热计时
bit is_initial_full_heat = 1;                      //全功率加热标志位 1 加热 0 结束
                                                           // 数码管段码表(共阳极)
unsigned char SEG_CODE[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
#define SPECIFIC_HEAT_WATER 4200    // 水的比热容(J/(kg·℃))
#define HEATING_POWER 3000            //最高加热功率3000W

void ADC_Init()                                      // ADC 初始化函数
  {
  ADC_CONTR = 0x80;                      // 使能 ADC 电源  
  while (timer0_count < 1);               // 延时 1ms等待 ADC 电源稳定
    timer0_count = 0;                             //将定时器 0 计数变量清零   
    ADC_CONTR |= 0x08;                       // 启动 ADC 转换  8 分频
 }

unsigned int Read_ADC(unsigned char channel)   // 读取 ADC 值函数
 {
    ADC_CONTR &= 0xF0;                    // 清除通道选择位  
    ADC_CONTR |= channel;                 // 设置要转换的通道   
    ADC_CONTR |= 0x40;                      // 启动 ADC 转换      
    while (!(ADC_CONTR & 0x20));        // 等待转换完成
    ADC_CONTR &= ~0x20;                 //清除转换完成标志   
    return (ADC_RES << 2) | (ADC_RESL & 0x03);   // 返回 10 位 ADC 值   
 }

float ntc_to_temp(unsigned int adc_value)        // NTC 温度转换函数
{
    // 根据 ADC 值计算对应的电压值,假设参考电压为 5V
    float voltage = (float)adc_value * 5.0 / 1023.0;
    // 根据电压值计算 NTC 热敏电阻的阻值,假设上拉电阻为 10K
    float resistance = (5.0 - voltage) * 10000 / voltage;
    // 通过简单的线性关系将电阻值转换为温度值,实际应用中需校准
    float temperature = (resistance - 10000) / 38.5;
    return temperature;
}

void EX0_Init()                               // 外部中断 0 初始化函数
{
    IT0 = 1;                                     // 设置外部中断 0 为下降沿触发
    EX0 = 1;                                    // 使能外部中断 0
    EA = 1;                                     // 全局中断使能   
}

void EX0_ISR() interrupt 0             // 外部中断 0 服务函数
{
    flow_count++;                          // 水流量脉冲计数加 1   
    flow_detected = 1;                   // 水流检测标志位置 1
}

bit Key_Debounce(bit key_pin)     // 按键检测函数
{
    if (!key_pin)                              // 检测按键是否按下   
   {
        while (timer0_count < 10);   // 消抖延时 10ms
        timer0_count = 0;                //将定时器0计数变量清零
        if (!key_pin)                          // 再次检测按键是否仍然按下
   {
            while (!key_pin);               // 等待按键释放
            return 1;                          // 按键操作有效,返回 1
          }
     }
   return 0;   // 按键操作无效,返回 0  
}

unsigned int calculate_pwm_duty()   // 计算所需 PWM 占空比函数
{
    // 假设水流量传感器每脉冲代表的水体积(L),需根据实际传感器校准
    float water_volume_per_pulse = 0.01;
    // 计算水流量(kg/s),假设水的密度为 1kg/L
    float water_flow_rate = flow_count * water_volume_per_pulse;
    // 计算温度差,即设定温度与进水温度的差值
    float temp_diff = set_temp - in_temp;
    // 计算所需加热功率(W),根据比热容公式计算
    float required_power = water_flow_rate * SPECIFIC_HEAT_WATER * temp_diff;
    // 计算 PWM 占空比,根据所需功率与设定加热功率的比例计算
    unsigned int duty = (unsigned int)((required_power / HEATING_POWER) * 100);
    // 确保占空比不超过 100
  if (duty > 100)
   {
        duty = 100;
     }
    return duty;
 }

void Heating_Control()         // 加热控制函数
{
  if (flow_detected)
   {
        // 计算设定温度与进水温度的差值
        float temp_diff = set_temp - in_temp;
        // 假设水流量传感器每脉冲代表的水体积(L),需根据实际传感器校准
        float water_volume_per_pulse = 0.01;
        // 计算水流量(kg/s),假设水的密度为 1kg/L
        float water_flow_rate = flow_count * water_volume_per_pulse;

        unsigned int full_heat_time;
        // 根据水流量和温差动态调整初始全功率加热时间
        if (water_flow_rate > 0.5 && temp_diff > 10) {
            // 流量大且温差大,将初始全功率加热时间延长到 3 秒
            full_heat_time = 3000;
        } else if (water_flow_rate < 0.1 && temp_diff < 5) {
            // 流量小且温差小,将初始全功率加热时间缩短到 1 秒
            full_heat_time = 1000;
        } else {
            // 其他情况,保持初始全功率加热时间为 2 秒
            full_heat_time = 2000;
        }

        if (is_initial_full_heat) {
            // 处于初始全功率加热阶段,PWM 占空比设为 100%
            pwm_duty = 100;
            // 初始全功率加热计时加 1
            initial_full_heat_timer++;
            if (initial_full_heat_timer >= full_heat_time) {
                // 达到设定的初始全功率加热时间
                // 结束初始全功率加热阶段
                is_initial_full_heat = 0;
                // 初始全功率加热计时清零
                initial_full_heat_timer = 0;
                // 根据计算结果设置 PWM 占空比
                pwm_duty = calculate_pwm_duty();
            }
        } else {
            // 已结束初始全功率加热阶段,根据计算结果设置 PWM 占空比
            pwm_duty = calculate_pwm_duty();
        }
        // 开启加热标志
        heating_flag = 1;
  }
  else
   {
        pwm_duty = 0;           // 未检测到水流,PWM 占空比设为 0
        heating_flag = 0;          // 关闭加热标志
        is_initial_full_heat = 1;     // 下次有水流时重新进入初始全功率加热阶段
        initial_full_heat_timer = 0;  // 初始全功率加热计时清零
      }
}

// 数码管显示函数,在数码管上显示指定的温度值
void Display_Temperature(float temp)
{
    // 定义两个变量,用于存储温度值的十位和个位数字
    unsigned char digit1, digit2;
    // 将温度值转换为整数
    int temp_int = (int)temp;

    // 提取温度值的十位数字
    digit1 = temp_int / 10;
    // 提取温度值的个位数字
    digit2 = temp_int % 10;

    // 显示第一位
    // 选中数码管的第一位
    DIG1_PIN = 0;
    // 取消选中数码管的第二位
    DIG2_PIN = 1;
    // 将十位数字对应的段码输出到数码管
    P0 = SEG_CODE[digit1];
    // 延时 5ms,确保数码管显示稳定
    while (timer0_count < 5);
    // 延时结束后,将定时器 0 计数变量清零,为下一次计时做准备
    timer0_count = 0;

    // 显示第二位
    // 取消选中数码管的第一位
    DIG1_PIN = 1;
    // 选中数码管的第二位
    DIG2_PIN = 0;
    // 将个位数字对应的段码输出到数码管
    P0 = SEG_CODE[digit2];
    // 延时 5ms,确保数码管显示稳定
    while (timer0_count < 5);
    // 延时结束后,将定时器 0 计数变量清零,为下一次计时做准备
    timer0_count = 0;
}

void Timer0_Init()                         // 定时器 0 初始化函数
{
    TMOD &= 0xF0;                      // 清除定时器 0 模式位,不受之前的影响
    TMOD |= 0x01;                        // 设置定时器 0 为模式 1(16 位定时器)
    TH0 = (65536 - 1000) / 256;    // 设置定时器 0 的初值,使其定时 1ms
    TL0 = (65536 - 1000) % 256;
    ET0 = 1;                             // 使能定时器 0 中断
    TR0 = 1;                             // 启动定时器 0
}

void Timer1_Init()                       // 定时器 1 初始化函数
{
    TMOD &= 0x0F;                   // 清除定时器 1 模式位,不受之前的影响
    TMOD |= 0x10;                      // 设置定时器 为模式 1(16 位定时器)
    TH1 = (65536 - 100) / 256;    // 设置定时器 1 的初值,使其定时 100us
    TL1 = (65536 - 100) % 256;
    ET1 = 1;                  // 使能定时器 1 中断
    TR1 = 1;                                // 启动定时器 1
 }



void main()
{
  unsigned int in_adc_value, out_adc_value;  //进水和出水的 ADC 值
    Timer0_Init();                        // 调用定时器 0 初始化函数
    Timer1_Init();                  //定时器 1 初始化函数,产生 PWM 信号来控制加热设备的功率
    ADC_Init();                    //ADC 初始化函数
    EX0_Init();                    //外部中断 0 初始化函数,够响应水流量传感器的脉冲信号
    HEATING_CTRL_PIN = 0;          //将加热控制引脚置为低电平

  while (1)
   {
   if (flow_count == 0)          // 检查水流量脉冲计数是否为 0
           {
              flow_detected = 0;     //将水流检测标志置为 0
           }
       in_adc_value = Read_ADC(0);                     //读取进水 NTC的adc值
       in_temp = ntc_to_temp(in_adc_value);       //进水温度值存入 in_temp 变量中
       out_adc_value = Read_ADC(1);                  //读取出水 NTC的 AD值
       out_temp = ntc_to_temp(out_adc_value);  //出水温度值存入 out_temp 变量中

      
       if (Key_Debounce(UP_KEY_PIN))          // 检测温度调节按键“+”是否被按下
     {
            if (set_temp < 50)                          //当前设定温度小于 50°C
     {
                 set_temp += 1;                         // 将设定温度加 1°C
                 show_set_temp_flag = 1;          // 显示设定温度的标志位置 1(显示设定温度)
                 show_set_temp_timer = 0;        // 将显示设定温度的计时变量清零,重新开始计时
              }
          }
      
        if (Key_Debounce(DOWN_KEY_PIN))  // 检测温度调节按键“-”是否被按下
     {
            if (set_temp > 10)                         //当前设定温度大于 10°C
              {
                set_temp -= 1;                          // 将设定温度减 1°C
                show_set_temp_flag = 1;          // 显示设定温度的标志位置 1(显示设定温度)
                show_set_temp_timer = 0;        // 将显示设定温度的计时变量清零,重新开始计时
              }
          }

        Heating_Control();                           //调用加热控制函数
        
        if (show_set_temp_flag)                   // 如果显示设定温度的标志位为 1
     {
           Display_Temperature(set_temp);  //在数码管上显示设定温度
          }
   else                                                 // 如果显示设定温度的标志位为 0
     {
           Display_Temperature(out_temp); //数码管上显示出水温度
          }
        while (timer0_count < 10);             // 等待定时器 0 计数达到 10,实现 10ms 的延时
        timer0_count = 0;                          //将定时器 0 计数变量清零
    }
}

void Timer0_ISR() interrupt 1                    // 定时器 0 中断服务函数
{
    TH0 = (65536 - 1000) / 256;
    TL0 = (65536 - 1000) % 256;
    timer0_count++;                                  // 定时器 0 计数变量加 1
  if (show_set_temp_flag)                        // 显示设定温度标志位  1设定温度
    {
        show_set_temp_timer++;                 // 显示设定温度的计时变量加 1
        if (show_set_temp_timer >= 5000)   // 显示设定温度的时间达到 5 秒
          {
            show_set_temp_flag = 0;             // 关闭显示设定温度的标志
            show_set_temp_timer = 0;           // 显示设定温度的计时变量清零
          }
       }
  }         

void Timer1_ISR() interrupt 3                   // 定时器 1 中断服务函数,产生 PWM 信号
{
    static unsigned int pwm_counter = 0;  // 静态变量,用于记录 PWM 信号的计数值
    TH1 = (65536 - 100) / 256;
    TL1 = (65536 - 100) % 256;
    pwm_counter++;                                       // PWM 计数值加 1
  if (pwm_counter < pwm_duty)
  {
        HEATING_CTRL_PIN = 1;                 // 在占空比范围内,输出高电平
    }
 else
    {
         HEATING_CTRL_PIN = 0;              // 超出占空比范围,输出低电平
      }
 if (pwm_counter >= pwm_period)     // 达到 PWM 周期,
   {
        pwm_counter = 0;                        //  PWM 计数值清零,开始下一个周期   
      }
  }

噢 原来是这样啊,会了,插入代码才行啊。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:137
  • 最近打卡:2025-05-01 00:01:04

6

主题

277

回帖

1108

积分

金牌会员

积分
1108
发表于 2025-3-3 20:20:50 | 显示全部楼层
so*** 发表于 2025-3-3 17:11
这编辑的真差,怎么不用插入代码

谢谢您,你说的方法很好用,这样子插入代码真的就不乱了。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:137
  • 最近打卡:2025-05-01 00:01:04

6

主题

277

回帖

1108

积分

金牌会员

积分
1108
发表于 2025-3-3 20:24:14 | 显示全部楼层
国芯人*** 发表于 2025-3-3 15:08
您好,您提供的代码片段是一个即热式恒温电热水龙头的控制程序框架。从代码中可以看出,系统通过流量传感器 ...

好的,给他放个看门狗,PID就不用想了,弄不了这么复杂的参数。单片机程序中,我学个结构体就好费劲,学了一个下午才弄明白是怎么回事。
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 06:57 , Processed in 0.141575 second(s), 93 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表