这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 【AT-START-M412测评】+④夏季室内温控系统

共2条 1/1 1 跳转至

【AT-START-M412测评】+④夏季室内温控系统

菜鸟
2025-07-02 15:24:41     打赏

一、引言        
          前面帖子也分享了正常驱动DS18B20模块,今天分享一下,在上期工程的基础上,增加驱动电机模块,实现一个简易的夏季降温控制装置。夏季到来,南方室内温度过高,很难入睡。一整晚开着空调觉得太费电,整夜开着吊扇又怕着凉感冒,那如果使用一套自动控温装置,既能实现节能减排,又能达到精准降温,非常适用。
二、电机驱动模块
      原本使用42步进电机驱动器去驱动42步进电机,结果没有相应的风扇叶,驱动演示效果不怎么理想。然后选择采用L298N电机驱动模块,连接12V直流电机,并拧紧风扇叶片,驱动效果非常不错。
      下面介绍一下L298N模块的基本资料。

      由上图可知,该驱动板可驱动两路直流电机,使能端ENA,ENB为高电平有效,控制方式及直流电机状态表如下所示:

       若要对直流电机进行PWM调速控制,则需要设置IN1和IN2,确定电机的转动方向,然后对使能端输出PWM脉冲,即可实现调速。注意当使能信号为0时,电机处于自动停止状态;当使能信号为1,且IN1和IN2为00或11时,电机处于制动状态,阻止电机转动。
三、硬件接口
      根据《DS_AT32M412_416_V2.01_ZH.pdf》数据手册,结合《AT_START_M412_V1.0_SCH.pdf》原理图,管脚复用关系,选择相应IO口。为了更好的交互体验,这里还引入蜂鸣报警器模块,占用一个GPIO口。综上情况,实验中使用到的硬件接口关系列表如下:

     因为电机是12V直流电机,因此L298N模块采用12V供电。结合板上的VCC与GND管脚分布,硬件实物连接图见如下:

四、驱动源码
     原本使用GPIO中断方式触发电机启动,然而LCD屏显示温度变的没那么流畅,因此直接采用循环检测模式,体验效果还不错。之前也分享了LCD、DS18B20的驱动源码,今儿就不再分享这部分代码,有需要的网友请翻阅前期发布的帖子。
L298N与Beep初始化驱动部分代码如下:
motor.h
复制

;
;
;

motor.c
复制

{
  
  crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE);

  
  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
}


{
  gpio_init_type gpio_init_struct;

  gpio_default_para_init(&gpio_init_struct);

  gpio_init_struct.gpio_pins =  GPIO_PINS_1;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;

  gpio_init(GPIOB, &gpio_init_struct);
  gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE1, GPIO_MUX_2);
        
  gpio_init_struct.gpio_pins = GPIO_PINS_2 | GPIO_PINS_10;
  gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init(GPIOB, &gpio_init_struct);
}


{
  gpio_init_type gpio_init_struct;

  gpio_default_para_init(&gpio_init_struct);

  gpio_init_struct.gpio_pins = GPIO_PINS_5;
  gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init(GPIOB, &gpio_init_struct);
  gpio_bits_reset(GPIOB,GPIO_PINS_5);
}

main.c
复制

tmr_output_config_type tmr_oc_init_structure;
crm_clocks_freq_type crm_clocks_freq_struct = {};

  temperature = ;
 ccr1_val = ;
 ccr2_val = ;
 ccr3_val = ;
 ccr4_val = ;
 prescalervalue = ;


{
    i, DS18B20ID[];
    str[];
        
  system_clock_config();
  at32_board_init();
  motor_crm_configuration();
  crm_clocks_freq_get(&crm_clocks_freq_struct);
  motor_gpio_configuration();
  beep_gpio_configuration();
  uart_print_init();
        

  prescalervalue = () ((crm_clocks_freq_struct.apb1_freq) / ) - ;

  
  tmr_base_init(TMR3, , prescalervalue);
  tmr_cnt_dir_set(TMR3, TMR_COUNT_UP);
  tmr_clock_source_div_set(TMR3, TMR_CLOCK_DIV1);

  tmr_output_default_para_init(&tmr_oc_init_structure);
  tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
  tmr_oc_init_structure.oc_idle_state = FALSE;
  tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_oc_init_structure.oc_output_state = TRUE;

  tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_4, &tmr_oc_init_structure);
  tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_4, ccr1_val);
  tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_4, TRUE);
  tmr_period_buffer_enable(TMR3, TRUE);

  
  tmr_counter_enable(TMR3, TRUE);
  tmr_output_enable(TMR3, TRUE);
        
  LcdInit();
  ();
  LcdFill(,,,,BLACK);
  LcdShowString(,,,RED, BLACK,);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  delay_ms();
  (DS18B20_Init())        
  {
    ();
    LcdFill(,,,,BLACK);
    LcdShowString(,,,RED, BLACK,);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    delay_ms();
  }
  ();
  LcdFill(,,,,BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShowString(,,,RED, BLACK,);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShowString(,,,YELLOW, BLACK,);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);

 
  DS18B20_ReadId(DS18B20ID);
  ();  
   ( i = ; i < ; i ++ )             
        ( , DS18B20ID[i]);
  ();
        
  (str,,DS18B20ID[],DS18B20ID[],DS18B20ID[],DS18B20ID[],
                                                                     DS18B20ID[],DS18B20ID[],DS18B20ID[],DS18B20ID[]);
  
  LcdShowString(,,,RED, BLACK,);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShow16x16Hz(, , , YELLOW, BLACK);
  LcdShowString(,,str,RED,BLACK,);
  delay_ms();
  ()
  {
    temperature = DS18B20_GetTemp_MatchRom(DS18B20ID);
    
    (,temperature);
    LcdFill(,,,,BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LcdShow16x16Hz(, , , YELLOW, BLACK);
    LCD_ShowFloatNum1(,,temperature,,RED, BLACK,);
    LcdShow16x16Hz(, , , RED, BLACK);
    delay_ms();
    (temperature <= TEMP_THRESHOLD) {
           tmr_output_enable(TMR3, FALSE);
           gpio_bits_reset(GPIOB,GPIO_PINS_5);
           gpio_bits_reset(GPIOB,GPIO_PINS_2);
           gpio_bits_reset(GPIOB,GPIO_PINS_10);        
     }  (temperature-TEMP_THRESHOLD <= ) {
           
           gpio_bits_reset(GPIOB,GPIO_PINS_10);
           gpio_bits_set(GPIOB,GPIO_PINS_2);
           tmr_output_enable(TMR3, FALSE);
           tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_4, ccr1_val);
           tmr_output_enable(TMR3, TRUE);
           gpio_bits_toggle(GPIOB,GPIO_PINS_5);
           delay_ms();
      } (temperature-TEMP_THRESHOLD <= ) {
            tmr_output_enable(TMR3, FALSE);
            tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_4, ccr2_val);
            tmr_output_enable(TMR3, TRUE);
            gpio_bits_toggle(GPIOB,GPIO_PINS_5);
            delay_ms();
       } (temperature-TEMP_THRESHOLD <= ) {
            tmr_output_enable(TMR3, FALSE);
            tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_4, ccr3_val);
            tmr_output_enable(TMR3, TRUE);
            gpio_bits_toggle(GPIOB,GPIO_PINS_5);
            delay_ms();
        } (temperature-TEMP_THRESHOLD <= ) {
             tmr_output_enable(TMR3, FALSE);
             tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_4, ccr4_val);
             tmr_output_enable(TMR3, TRUE);
             gpio_bits_toggle(GPIOB,GPIO_PINS_5);
             delay_ms();
         }
          {
              tmr_output_enable(TMR3, FALSE);
              gpio_bits_reset(GPIOB,GPIO_PINS_5);
              gpio_bits_reset(GPIOB,GPIO_PINS_2);
              gpio_bits_reset(GPIOB,GPIO_PINS_10);        
         }
    }
}

        根据以上代码可知,温度门限控制在31.8℃以下,高于该温度0.5℃内为一等级预警;高于1.5℃为二等级报警;高于2.5℃为三等级鸣警;高于3.5℃为四等级超温告警。每等级驱动的PWM占空比不同,因此驱动电机的转速也不同,蜂鸣器告警的频率也不同。
五、效果演示
        使用手指触摸DS18B20给温度传感器加温,当温度超过限定阀值时,则启动风机,并唤起蜂鸣器报警提示,吹风给DS18B20模块降温;当温度还持续加热,则启动更高等级的风速与报警频率,等级越高,风速越快越大,因此降温越快。风吹着降温明显,正如演示视频当中,用手指加温的同时,风机启动了加温进度明显减慢了。



专家
2025-07-06 18:43:52     打赏
2楼

感谢分享


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]