非常感谢硬禾学堂与Digikey联合举办的第四期Funpack活动。
我参加本次活动选择的题目是:任务1 - 开放题
- 自行搭配已有传感器,配合AVR64DD32 Curiosity Nano核心板的至少两个片内外设,完成任务,任务难度不低于以上任务。例如:搭配温度传感器和蜂鸣器,实现温度监控,当超过一定温度时报警。
本次活动中使用到的两个片上外设:ADC和UART。考虑到题目要求至少两个片上外设,因此本设计使用片上ADC来采集温度传感器数据,然后使用另外一个片上外设UART来传输温度数据到上位机电脑上。
一、主控芯片:AVR64DD32简介
本次设计使用的板卡是AVR64DD32 Curiosity Nano开发板,板载了一个功能非常完善的8位单片机,并且外设资源也是非常丰富。
- AVR64DD32微控制器
- 一个黄色用户LED
- 一个机械式用户开关
- 一个32.768kHz晶体
- 一个24MHz晶体
- 板载调试器:
- 一个绿色电源及状态指示LED
- 编程和调试
- 虚拟串行端口 (CDC)
- 两个调试GPIO通道 (DGI GPIO)
- USB供电
- 可调目标电压:
- MIC5353 LDO稳压器,由板载调试器控制
- 输出电压范围:1.8V至5.1V(受USB输入电压限制)
- 最大输出电流:500mA(受环境温度和输出电压限制)
板卡Pinout:
本次设计主要实现的功能是任务3:通过ADC采集温度传感器输出的模拟温度信号,如果温度超过预设值,通过板载LED0进行报警,与此同时,报警信息会通过UART模块进行上位机通知。下面介绍一个具体的实现:
二、温度传感器TMP235介绍
这款优秀的温度传感器来自知名的Adafruit,参考资料为:https://media.digikey.com/pdf/Data%20Sheets/Adafruit%20PDFs/4686_Web.pdf
这款温度传感器有三个引脚,分别是GND, VCC和模拟温度信号。其中,模块可以3v-5v供电,在外界温度为-50°C时,模拟温度信号的输出为0v;在外界温度为125°C时,模拟温度信号的输出为1.75v
此外,手册还提供了一个通过电压计算温度的公式: Temp °C = 100*(reading in V) - 50。因此,接下来通过ADC获取温度值后,可以方便的进行温度监测等后续功能开发。
三、片上模数转换器ADC配置
ADC的配置参考了Microchip官方提供的ADC例程,链接为:https://github.com/microchip-pic-avr-examples/avr64dd32-getting-started-with-adc-mplabx-mcc。
由于温度传感器的输出电压范围在0v ~ 1.75v,因此将ADC的参考电压设置为2.048v可以满足要求。
在MCC图形化配置工具中打开VREF模块的配置界面,在Hardware Settings-> ADC Reference Source,以及ADC Reference Voltage选择内部2.048v电压源即可满足要求。
下面是VREF模块通过自动代码生成工具生成的配置代码:
int8_t VREF_Initialize(void)
{
// ALWAYSON disabled; REFSEL Internal 1.024V reference;
VREF.ACREF = 0x0;
// ALWAYSON disabled; REFSEL Internal 2.048V reference;
VREF.ADC0REF = 0x1;
// ALWAYSON disabled; REFSEL Internal 1.024V reference;
VREF.DAC0REF = 0x0;
return 0;
}
接下来需要配置ADC的具体参数:
- 配置ADC为连续转换模式: Free Running Mode
- ADC转换结果为10bit: Resolution Selection选择10-bit
- 时钟源 外设时钟的1/4。
根据上述的设计要求,先使用MCC进行图形化配置:
然后自动生成配置代码,代码如下:
int8_t ADC0_Initialize(void)
{
// SAMPNUM No accumulation;
ADC0.CTRLB = 0x0;
// PRESC CLK_PER divided by 4;
ADC0.CTRLC = 0x1;
// INITDLY DLY0; SAMPDLY DLY0;
ADC0.CTRLD = 0x0;
// WINCM No Window Comparison;
ADC0.CTRLE = 0x0;
// DBGRUN disabled;
ADC0.DBGCTRL = 0x0;
// STARTEI disabled;
ADC0.EVCTRL = 0x0;
// RESRDY disabled; WCMP disabled;
ADC0.INTCTRL = 0x0;
// MUXPOS ADC input pin 18;
ADC0.MUXPOS = 0x12;
// MUXNEG ADC input pin 1;
ADC0.MUXNEG = 0x1;
// SAMPLEN 0;
ADC0.SAMPCTRL = 0x0;
// Window comparator high threshold
ADC0.WINHT = 0x3FF;
// Window comparator low threshold
ADC0.WINLT = 0x0;
// ENABLE enabled; FREERUN enabled; RESSEL 10-bit mode; RUNSTBY disabled; CONVMODE disabled; LEFTADJ disabled;
ADC0.CTRLA = 0x7;
return 0;
}
之后在主程序中调用如下接口即可获取ADC值:
adcVal = ADC0_GetConversion(ADC_MUXPOS_AIN18_gc);
TempDegree = adcVal/5 - 50;
四、UART配置
板载Debugger的CDC TX,RX分别与AVR64DD32的PD5与PD4相连接。用户可以依照这个连接,在MCC图形化配置工具中把相关PIN分别设置为UART RX与TX,然后点击Generate即可生成UART模块的配置代码。
在MCC中的配置如下图所示。请勾选“Redirect Printf to UART”,这样生成的代码就支持直接在程序中通过Printf函数向串口工具打印调试信息,非常方便调试。
下图是最终的效果展示截图:
- 当温度超过20度的时候,通过ADC模块采集到的模拟温度值会通过UART模块发送至上位机,从而实现温度报警。
- 当温度没有超过20度的时候,串口会打印出当前的温度以及所对应的ADC raw value.
五、总结
这次参加Funpack活动体验的AVR64DD32虽然是一个8 bit单片机,但是MCC图形化配置界面,方便使用的各种外设模块都使得这款单片机更加易用,自动化代码生成大大节约了项目开发的时间,也保证了代码质量。
本项目的遗憾是没有进行相关屏幕的扩展,如果能够把温度或者报警信息动态的展示在OLED屏幕上,应该会更加的直观,也可以使用一个开源的GUI库,在温度超过警戒值后,亮灭亮灭一个警报图形。
这次任务的完成也是在技术交流群里得到了不少朋友的帮助,在此表示非常感谢!希望Funpack活动能够越办越好!