基于AVR64DD32单片机的加热和温度采集系统
基于AVR64DD32单片机的加热和温度采集系统。IO扩展板上有一处加温电阻,通过电流给电阻加热,并通过温度传感器感知板上温度的变化,将测量到的温度信息显示在LCD屏幕上
标签
AVR64DD32
Funpack2-4
加热和温度采集系统
纳芯微NST112
自动控温系统
PWM调温
lixiang
更新2023-04-20
760

本次Funpack2-4活动,我选择的题目是:基于AVR64DD32单片机的恒温自控系统。下面先介绍任务,以及任务实现思路,然后再分章节介绍详细的设计实现。

任务2 - 实现一个恒温自动控制系统

  • IO扩展板上有一处加温电阻,将加热区域用物体(纸巾等)包裹起来,通过电流给电阻加热,并通过温度传感器感知板上温度的变化,测温以及在LCD屏上的温度显示。

要求:使用按键设定目标温度,并且通过程序控制加热功率,使得温度尽快尽量稳定的维持在目标温度。温度偏离设定温度±3°C彩灯变为红色。(注意,加热电阻满占空比开启后温度较高)

任务实现思路介绍:

首先熟悉本任务中的各个模块:

  • 主控单元:AVR64DD32,Microchip公司近期推出的高性能24MHz,丰富片上外设的8位单片机。
  • 温度传感器:NST112,纳芯微电子推出一款低功耗高精度数字温度传感器。适用于负温度系数和正温度系数热敏电阻的替换。NST112具有可兼容I2C和SMBus的接口,可通过I2C总线连接到AVR64DD32上。
  • LCD显示模块:1.44彩色LCD,基于ST7735,SPI接口,方便与AVR64DD32单片机连接。
  • RGB彩灯:R, G, B三色灯分别连接到AVR64DD32不同的GPIO引脚。
  • 目标温度设定按键:使用到是Curiosity Nano板子上连接到PF6引脚的板载按键,设定好按键中断后,即可在中断服务程序中对目标温度进行更改。

硬件系统框图如下:

Ftc3aclcyA7lmXGVDLTe0MyfbEFP

根据任务要求,

  • 我在项目设计中先实现了LCD屏幕驱动设计,这里采用的GPIO模拟SPI方式,详见第一节。完成这一节后,可以正常在屏幕上显示各种文字或者数值。
  • 温度传感器NST112的温度值通过I2C接口发送到AVR64DD32,详见第二节。完成这一节后,可以把采集到的温度数据显示在LCD屏幕上。
  • 目标温度的设定是通过连接到PF6的按键来调节,每次按键按下后,温度先逐步增高0.5°,到达32度的最大目标温度后,每次按下按键,目标温度逐步递减0.5度。详细的设计参考第三节。
  • 加热控温或者自然降温:这部分在设计的时候采用了PWM不同占空比来进行快速加热(比如占空比为100%, 60%等)还是慢速加热(比如占空比为10%, 8%,3%,2%等)。比如当目标温度大于当前温度4度的时候,占空比为60%,温差为3度的时候,占空比为30%,温差为2度,1度,0.5度,0.2度,0.1度的时候分别设计了不同的PWM占空比。当目标温度低于当前温度的时候,由于没有风扇等辅助降温,在设计中把PWM的占空比设定为0,让加温电阻自然降温,逐步靠近目标温度。

程序流程图如下:

FoIemdHpM6jv6bhMzixrsWp2BpVh

一、LCD屏幕驱动

本次使用的LCD是SPI接口,相关的电路图:

   Fm97oOcuZhmIc7rEP5Vo68jhGLHD

AVR64DD32上也有一路SPI0,本次使用了GPIO模拟SPI,其中SCK-PA6, MOSI-PA4,RESET-PC3, DC-PC2, CS-PC1。

通过MCC进行配置,自动生成代码。

FqLiTDB9LxGpRMUXV2__y9qerS7T

烧录程序后,LCD可以正常刷新!

Fmo67omLhCwQmOvwv3zjHg3ttb2X

二、温度传感器数据读取

扩展板上的温度传感器采用了纳芯微的NST112,IIC接口。AVR64DD32也有硬件IIC,位于PA2与PA3.

Fgn19D5duLrgQIjeOEnn3HgJGVt5FtSJCWSlgDz_jiBqZE8hnpw0n5oC

在使用NST112温度传感器的时候,有个非常重要的寄存器就是Pointer Register,这个寄存器的后两个bits决定了我们读/写哪个特定的寄存器,这个8bit寄存器除了最低的2个LSB外均为0,因此使用宏定义的方式把这些寄存器都预先定义好。

FgCxDteSNsnGJsb0NtFyeoIsmHoS

#define NST112_CLIENT_ADDR                   0x48    /* NST112 client device address */ 
#define NST112_TEMPERATURE_REG          0x00    /* Temperature register (default) (R only) */
#define NST112_CONFIG_REG                     0x01    /* Configuration register (R/W)  */
#define NST112_TLOW_REG                        0x02    /* TLOW register (R/W)  */
#define NST112_THIGH_REG                       0x03    /* THIGH register (R/W)  */

还有一个比较重要的寄存器就是control register,控制了温度传感器的工作模式,转换精度以及上电复位后的默认值等。实际上在本设计中,我使用到都是默认值,比如连续转换模式使得应用程序能够连续获取温度值;默认的12bit转换精度也足以满足设计需求。

FqISOYzVXkp4oNAnVRUkEWx70JfG

接下来需要读取NST112的温度数据,我们需要完善NST112的读函数:

/* Reads the ADC conversion result from the 12-bit ADC I2C client device
 * - returns true if 2 bytes have been received
 * - returns false if client did not ACK/an unexpected number of bytes have been 
 * received
 * Only one single word (uint16_t) variable must be allocated
 */
bool NST112_Read (uint16_t *pData)
{
    uint8_t *pDataTemp = (uint8_t *)pData;
    uint16_t temp = 0;
    
    if(pData == NULL)
    {
        return false;
    }
    
    TWI0_Read(NST112_CLIENT_ADDR, pDataTemp, 2);
    do
    {
        TWI0_Tasks();
    }while(TWI0_IsBusy());
      
    if(TWI0_ErrorGet() == I2C_ERROR_NONE)
    {
        temp = pDataTemp[0] + pDataTemp[1];
        pDataTemp[1] = temp - pDataTemp[1];
        pDataTemp[0] = temp - pDataTemp[1];
        return true;
    }
    
    return false;
}

在处理温度数据的时候,需要注意字节序的问题。根据纳芯微的手册:The Temperature Register storing the results of each completed temperature conversion, which consists of 2bytes in the format shown in Table 4.3, with MSB output first and followed by the LSB。TWI0_Read()执行后,pDataTemp[0]存放的是温度寄存器的高8bit,pDataTemp[1]存放的是温度寄存器的低8bit数据。单片机存储uint16_t数据是小端模式,低字节对应低地址,高字节对高地址。因此需要对换一下字节数据。

主函数(main.c)中调用NST112读函数来获取默认的12-bit精度的温度值:

  /* Read the ADC result */
if (NST112_Read(&adc_result))
{
        adc_result = adc_result>>4; //12-bit LSB 4bits should be dropped
        TemperatureValue = adc_result*0.0625;
        LCD_ShowString(0,110,"Degre2:",BLACK,CYAN,12,0);
        LCD_ShowFloatNum1(40,110,TemperatureValue,4,RED,CYAN,12); 
}

三、按键调整目标温度

通过AVR64DD32板载的按键SW0调节目标温度,根据手册描述,需要使能内部上拉电阻才能正常使用按键。

FpMFHQAb6dRrwpv0gGL8sajzEICl

在MCC中配置上拉,并且开启按键中断,下降沿触发。

FpnolhJTOcVN9fFmcqw2bMZk1AVG

在生成的代码中,加入目标温度设定的策略。每次按下后,增加0.5°,目标最大为32°。到达最大温度后,再次按下SW0后,逐步降低0.5°,最小目标温度是23度。

void PF6_DefaultInterruptHandler(void)
{
    printf("\r\n Key Pressed");
            if(dir == 1){
                TargetTemperatureValue += 0.5;
                if(TargetTemperatureValue >= 32){
                    TargetTemperatureValue = 32;
                    dir = 0;
                }      
            }else{
                TargetTemperatureValue -= 0.5;
                if(TargetTemperatureValue <= 23){
                    TargetTemperatureValue += 0.5;
                    dir = 1;
                }
            }  
}

四、加热温控

如果目标温度与实际温度相差正负3度以上,红色LED亮起。

if(fabs(TargetTemperatureValue - TemperatureValue) >= 3){
    IO_PD1_REDLED_SetLow();
}
 else{
 IO_PD1_REDLED_SetHigh();
 }

如果实际温度超过目标温度,关闭PWM输出,自然降温。如果实际温度没有达到目标温度,根据与目标温度的差值,动态调整PWM的占空比。

在本项目中,我使用的是TCA0模块的波形生成功能,生成“Single Slope PWM”。

FiPCdBCRi0aRoarXcZhOotStuF32

 

PWM波形不同的占空比对应不同的CMP0.自动生成的代码为占空比50%的PWM,对应的CMP0为0x5DB即十进制1499

FqZwH-03TE8Pc58-6yejsTpcjAmI

uint16_t DutyCycleLookupArray[11] = {0, 299, 599, 899, 1199, 1499, 1799, 2099, 2399, 2699, 2999};
uint16_t CurrentDutyCycle = 0;

主要的温度调控策略如下:

if(TargetTemperatureValue <= TemperatureValue){
            CurrentDutyCycle = 0;
            TCA0.SINGLE.CMP0BUF = DutyCycleLookupArray[CurrentDutyCycle];
            LCD_ShowIntNum(100,65,CurrentDutyCycle,3,RED,WHITE,12);
        }else if((TargetTemperatureValue - TemperatureValue)>=4){
            CurrentDutyCycle = 60;
            TCA0.SINGLE.CMP0BUF = DutyCycleLookupArray[CurrentDutyCycle/10];
            LCD_ShowIntNum(100,65,CurrentDutyCycle,3,RED,WHITE,12);
        }else if((TargetTemperatureValue - TemperatureValue)>=3){
            CurrentDutyCycle = 50;
            TCA0.SINGLE.CMP0BUF = DutyCycleLookupArray[CurrentDutyCycle/10];
            LCD_ShowIntNum(100,65,CurrentDutyCycle,3,RED,WHITE,12);
        }else if((TargetTemperatureValue - TemperatureValue)>=2){
            CurrentDutyCycle = 40;
            TCA0.SINGLE.CMP0BUF = DutyCycleLookupArray[CurrentDutyCycle/10]; 
            LCD_ShowIntNum(100,65,CurrentDutyCycle,3,RED,WHITE,12);
        }else if((TargetTemperatureValue - TemperatureValue)>=1){
            CurrentDutyCycle = 20;
            TCA0.SINGLE.CMP0BUF = DutyCycleLookupArray[CurrentDutyCycle/10];
            LCD_ShowIntNum(100,65,CurrentDutyCycle,3,RED,WHITE,12);
        }else if((TargetTemperatureValue - TemperatureValue)>=0.5){
            CurrentDutyCycle = 10;
            TCA0.SINGLE.CMP0BUF = DutyCycleLookupArray[CurrentDutyCycle/10];
            LCD_ShowIntNum(100,65,CurrentDutyCycle,3,RED,WHITE,12);
        }else if((TargetTemperatureValue - TemperatureValue)>=0.2){
            CurrentDutyCycle = 8;
            TCA0.SINGLE.CMP0BUF = 239;
            LCD_ShowIntNum(100,65,CurrentDutyCycle,3,RED,WHITE,12);
        }else if((TargetTemperatureValue - TemperatureValue)>=0.1){
            CurrentDutyCycle = 6;
            TCA0.SINGLE.CMP0BUF = 179;
            LCD_ShowIntNum(100,65,CurrentDutyCycle,3,RED,WHITE,12);
        }else if((TargetTemperatureValue - TemperatureValue)>=0.01){
            CurrentDutyCycle = 3;
            TCA0.SINGLE.CMP0BUF = 89;
            LCD_ShowIntNum(100,65,CurrentDutyCycle,3,RED,WHITE,12);
        }else if((TargetTemperatureValue - TemperatureValue)>=0.1){
            CurrentDutyCycle = 2;
            TCA0.SINGLE.CMP0BUF = 59;
            LCD_ShowIntNum(100,65,CurrentDutyCycle,3,RED,WHITE,12);
        }

下面展示的是目标温度为25度,最下面的温度不停变化的是实际温度,可以看到当实际温度大于目标温度的时候,PWM占空比为0,实际上不加热;当实际温度低于25度的时候,占空比不为0,进行不同程度的加热。

FhDj_IFuVakbVL4WjB18NweAbuOW

五、总结

非常感谢此次硬禾学堂举办的funpack活动,这次深度体验了AVR单片机便捷的图形化编程方式,使用了SPI, IIC以及TCA0等重要外设,最终实现了实际温度尽量稳定在目标温度上浮动。

在设计加热温度控制的时候,也有别的朋友分享了PID相关的控制策略,自己对这块不了解,可能后续还可以用PID来改进一下。

最后,希望这个活动越办越好!

附件下载
Hw-i2c -9-Final.zip
团队介绍
电子爱好
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号