项目描述
本次得捷购购买了AVR64DD32 Curiosity Nano 开发板,板载了一个功能非常完善的8位单片机,并且外设资源也是非常丰富。
- AVR64DD32微控制器
- 一个黄色用户LED
- 一个机械式用户开关
- 一个32.768kHz晶体
- 一个24MHz晶体
- 板载调试器:
- 一个绿色电源及状态指示LED
- 编程和调试
- 虚拟串行端口 (CDC)
- 两个调试GPIO通道 (DGI GPIO)
- USB供电
- 可调目标电压:
- MIC5353 LDO稳压器,由板载调试器控制
- 输出电压范围:1.8V至5.1V(受USB输入电压限制)
- 最大输出电流:500mA(受环境温度和输出电压限制)
板卡Pinout:
购买了温度模块、按键触摸模块,此次主要实现任务一,通过选用tmp235模拟温度传感器输入给主控,然后通过内部的比较器进行比较,当输入值大于设定值时,触发pwm播放使能,当温度低于设定温度时,pwm播放报警停止。同时通过uart 调试进行功能监测 功能验证,整体框图如下:
使用TCA0 WO1进行比较器设定,当达到一定阈值时,触发中断,中断修改标志位,然后主循环进行判断,然后使能蜂鸣器发声。
使用uart1进行串口log 打印 ,用于调试显示当前温度、状态机状态等
使用pd6 设定pwm输出驱动蜂鸣器,发出报警声音
TMP235温度传感器介绍
这款模拟温度传感器来自ADAFRUIT,这款温度传感器有三个引脚,分别是GND, VCC和模拟温度信号。其中,模块可以3v-5v供电,在外界温度为-50°C时,模拟温度信号的输出为0v;在外界温度为125°C时,模拟温度信号的输出为1.75v。PCB板子有温度和电压输入的转换关系
温度=(output-0.5)*100 摄氏度
功能展示及说明
1.使用自治的串口线连接串口1进行log 打印
2.温度计使用5v 供电 蜂鸣器使用3.3v供电,都使用自制的串口板进行供电
3.AVR64DD32与串口板进行共地
4.当温度超过30度时进行报警,当温度低于28度时 关闭报警
各功能对应的主要代码片段及说明
此次使用platformio进行开发,详细参考了avrcore 驱动代码完成外设驱动
1.pwm初始化,设置管脚 周期 占空比等信息
void pwm_set(void)
{
DutyCycle=0;
takeOverTCA0();
PORTMUX.TCAROUTEA = (PORTMUX.TCAROUTEA & ~(PORTMUX_TCA0_gm)) | PORTMUX_TCA0_PORTD_gc; // Set mux to PORTD
TCA0.SINGLE.CTRLB = (TCA_SINGLE_CMP1EN_bm | TCA_SINGLE_WGMODE_DSBOTTOM_gc); // Dual slope PWM mode OVF interrupt at BOTTOM, PWM on WO1.
TCA0.SINGLE.PER = 0xFFFF; // Count all the way up to 0xFFFF.
// At 20MHz, this gives ~152Hz PWM with no prescaling.
TCA0.SINGLE.CMP1 = DutyCycle; // 0 - 65535
TCA0.SINGLE.INTCTRL = TCA_SINGLE_OVF_bm; // enable overflow interrupt
TCA0.SINGLE.CTRLA = TCA_SINGLE_ENABLE_bm; // enable the timer with no prescaler
}
2. 当TCA0 阈值触发时,触发下面中断
ISR(TCA0_OVF_vect) { // on overflow, we will increment TCA0.CMP0, this will happen after every full cycle - a little over 7 minutes.
TCA0.SINGLE.CMP1 = DutyCycle++; // Because we are in Dual Slope Bottom mode, OVF fires at BOTTOM, at end, not TOP, in middle of the pulse.
TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm; // Always remember to clear the interrupt flags, otherwise the interrupt will fire continually!
}
3.比较器选用管脚PD6 使用1.024v做参考电压
void Compare_set(uint8_t value)
{
Comparator.input_p = comparator::in_p::inputP_t::pd6;
Comparator.input_n = comparator::in_n::inputN_t::dacref;
Comparator.dacref = value;
Comparator.reference = comparator::ref::vref_1v024; // Set the DACREF voltage to 1.024
Comparator.hysteresis = comparator::hyst::disable; // Use a 50mV hysteresis
Comparator.output = comparator::out::disable; // Use interrupt trigger instead of output pin
Comparator.init();
Comparator.attachInterrupt(waringFunc,RISING);
Comparator.start();
}
在主循环中检测中检测标记位是否改变 如果改变,则触发pwm初始化,并在循环中检测温度是否低于阈值,并且蜂鸣器在响,则关闭蜂鸣器。
temp = (float)analogRead(TEMP_PIN)*0.00322265625f ;
if((temp<0.75)&&(warning_flag)&&(temp>0))
{
warning_flag=false;
takeOverTCA0();
Comparator.start();
Serial1.println("stop warning!");
}
if(warning_enable)
{
warning_enable =0;
Comparator.start(false);
warning_flag = true;
Serial1.println("temp high! start waring");
Serial1.println(temp);
Serial1.println(temp*100-50);
pwm_set();
}
对本活动的心得体会(包括意见或建议)
1.此次学习了AVR64DD32单片机外设基本驱动配置选型,感觉使用platformio进行功能开发相对方便,兼容性比较强,针对中间层的应用可以使用arduino生态库,可以快速进行功能开发和验证,后续多进行相关的功能性开发、学习
2.对于单片机厂商来说现在都在做图形化配置,这个方向对于工程师来说比较友好,工程师在功能开发上不用细看datasheet 细化寄存器配置等枯燥设置,直接使用配置工具就能完成外设配置,将来感觉就是趋势,包括stm32cubemx 瑞萨的ra config 等等,后续我们工程的功能开发也可以考虑往这个方向进行考虑,尽量进行低代码量开发,减少出问题bug 的几率
3.在使用中发现使用platformio的库不能直接使用,环境搭建参考了这里https://blog.csdn.net/honestqiao/article/details/129635075
库代码需要在这里进行修改,否则无法正常使用