【Funpack2-4】基于AVR64DD32的加热和温度采集系统
基于AVR64DD32的加热及温度采集,使用了GPIO、ADC、UART、I2C、SPI等外设。
标签
AVR64DD32
测温
wakojosin
更新2023-04-23
545

 

功能简介

本项目是基于AVR64DD32 Curiosity Nano核心板和IOBV3-MSP430扩展板的加热及温度采集系统。项目主要用到的单片机外设有ADC、I2C、SPI、PWM、UART和GPIO,包含的硬件有LCD屏、nst112温度传感器、LED灯和按键。

实现思路

通过SPI来控制屏幕的显示,PWM驱动加热电阻进行加热,通过I2C跟温度传感器通讯进行温度数据采集,通过ADC采集扩展版的按键模拟信号来判断哪个按键按下,然后通过不同的按键来选择不同的功能或模式。UART作为日志信息输出接口,打印一下参数信息。

框图(当前设备环境无法上传文件,只能这么绘制了):

```c

/*

               +-------+      

         +-- | START | 

       /       +-------+      

     \|/         
+-----+      +------------+     +------------+     +-------------+      +-------------------+
 | INIT | --> | BTN Check | --> | read temp | --> | LED control | --> | draw temp wave |
+-----+      +------------+     +------------+     +-------------+      +-------------------+
                                                    /|\                                                                         |
                                                      \       +---------------+      +--------------+       /
                                                        +--  | Update PWM | <-- | BTN process  | <-+
                                                              +---------------+      +---------------+       
*/

```

硬件连接

硬件的连接如下:

LED1接到了PF4,LED2接到了PF3,LED3接到了PC2;

SPI使用的默认的PORTMUX配置,接口是:

  • LCD_SCL接到了PA6
  • LCD_SDA接到了PA4
  • LCD_CS接到了PA7

还有LCD的其他引脚:

  • LCD_RST接到了PC3
  • LCD_DC接到了PD2

温度传感器使用的引脚是:

  • IIC_SCL接到了PA3
  • IIC_SDA接到了PA2

PWM引脚使用的是:

  • V_HEAT接到了PF2,用来控制加热电阻工作。

ADC使用的引脚是:

  • AOUT接到了PD1,接到了按键,不同的按键对应的输出电压是不一样的,OK键的ADC值大概是3500,UP键对应的是2900,DOWN键对应的是1900。

扩展板和核心板使用杜邦线连接。

代码分析

首先是主函数,下面的代码删掉了部分变量申明,具体的可以查看源码:

int main(void) {
    sysclk_init();
    board_init();
    uint8_t tmp = 0x06;
    i2c_send_bytes(0, 0, &tmp, 1);
    uint8_t mask = i2c_device_check(0, 0x48, 0x4C);
    uart_printf(0, "mask:%02x\n", mask);
    /* 检查温度传感器的地址 */
    for(int i=0; i<4; i++)
    {
        if(mask & (1 << i))
        {
            drv_nst112_init(0x48+i);
            break;
        }
    }
    drv_lcd_clear();
    struct drv_lcd_coordinate coord;
    drv_lcd_coordinate_create(&coord, -40, 125);
    drv_lcd_draw_coordinate_with_color(&coord, 18,10, 100, 100, RED);
    while (1) {
        uint16_t adc_value = drv_adc_read(0);
        if(++tick >= 10)
        {
            tick = 0;
            if(drv_nst112_read_temp(&temp))
            {
                int num = snprintf(str_buf, 31, "T%.02f,A%d,D%d  \n", temp, adc_value, duty);
                led_process(&temp);
                uart_puts(0, str_buf);
                str_buf[num - 1] = ' ';
                drv_lcd_string(10,113,0,str_buf);
                if(!keep)
                {
                    temp_buf_write((int8_t)temp);
                }
                drv_lcd_draw_coordinate_point(&coord, temp_buf, temp_buf_cnt);
            }
        }
        key_active = key_process(adc_value, key_active, &duty);
        if(key_active == KEY_UP_RELEASE || key_active == KEY_DOWN_RELEASE)
        {
            key_active = KEY_NULL;
            drv_pwm_set(2, 100, duty);
        }
        if(key_active == KEY_OK_RELEASE)
        {
            key_active = KEY_NULL;
            keep = !keep;
        }
        _delay_ms(100);
    }
}

其中主要的函数及逻辑有:

  • sysclk_init():进行时钟初始化,里面实现了采用外部24MHz晶振和内置24MHz高速晶振两种系统时钟。
  • board_init():硬件外设初始化,包括led、uart、lcd、pwm、adc。
  • i2c_send_bytes(0, 0, &tmp, 1):其中tmp=0x06,参考nst112手册,这是复位内部寄存器操作,具体查看手册《3.4.3.3 General Call》
  • mask = i2c_device_check(0, 0x48, 0x4C):实现I2C设备检测,检测范围是0x38到0x4C,返回检测到的设备掩码(哪几个设备有应答),具体可以查看源码实现
  • drv_nst112_init(0x48+i):初始化相应地址的温度传感器
  • drv_lcd_coordinate_create(&coord, -15, 125):创建一个y坐标是-15到125的一个坐标系
  • drv_lcd_draw_coordinate_with_color(&coord, 18,10, 100, 100, RED):在屏幕(18,10)处绘制这个坐标系,大小是100x100,使用红色绘制
  • drv_adc_read(0):读取通道0的ADC值,通道定义可以查看源码
  • drv_nst112_read_temp(&temp):读取温度数据
  • led_process(&temp):根据温度数据点亮不同的LED灯
  • temp_buf_write((int8_t)temp):保存温度到缓存中
  • drv_lcd_draw_coordinate_point(&coord, temp_buf, temp_buf_cnt):绘制保存的温度曲线
  • key_process(adc_value, key_active, &duty):根据按键更新pwm占空比
  • drv_pwm_set(2, 100, duty):更新PWM占用比

主函数介绍完毕。

其他的代码就直接看源码吧,源码里面有较详细的中文注释。

功能展示

  • 下图标出了按键的功能,当前是绿灯,即温度大于20度小于50度。

屏幕的内容中T表示温度,A表示ADC读到的值,D表示PWM的占空比,1000表示10%。

Fr28UjJ3WhXafcCbDMD8O74UNQP2

  • 下图是一个温度变化曲线:

Fs9cVUukM4yaOCWcLD61dwFl6Mpv

  • 下图是当温度高于50度后LED灯的变化:

FqhB35WqApWWq9iSn4kXIKFODZ7K

其他说明:UP键是用来增加占空比的,按一次增加10%,DOWN键是减少占空比的,一次减少10%,OK键是用来截图的,按下后温度曲线就会保持住,但是没有存储下来,再按一次后就会接着采集温度了。

心得体会

通过本次活动,了解了AVR64DD32单片机的使用,包括时钟配置,GPIO、I2C、SPI、PWM、ADC等的使用以及LCD屏、NST112温度传感器,相对往期来说,写的代码也是最多的,所有驱动都是自己写的。

对比ARM单片机,AVR单片机还是要简单很多的,做一些简单功能的产品还是可以拿来用的,不过这款单片机没有看到对arduino的支持,这个比较遗憾。

最后希望编辑区支持markdown语法,方便绘图等操作,如果已支持,希望有个帮助来指导如果使用此功能。

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