Funpack2-4 基于AVR64DD32的音量监控显示
Funpack第二季第4期 AVR64DD32 ADC IIC 数字麦克风 LCD1602 液晶屏 Arduino vscode Platformio
标签
嵌入式系统
Funpack活动
数字逻辑
显示
aramy
更新2023-04-25
402

硬件介绍:AVR64DD32 Curiosity Nano开发板是参加funpack第二季第四期活动的开发板。这款开发板主芯片是Microchip公司AVR单片机产品线中的最新的一员,它的内部结构灵活、性能强大,有着比较丰富的外设和存储资源,是一个8位的芯片。该系列采用了最新的不依赖内核的外设,能够以非常低的功耗、在多种电压输入输出之间进行安全的双向通信,事件系统、可配置逻辑CCL、智能模拟外设,比如12位的ADC和过零检测都使得AVR DD系列非常适用于传感、IoT终端节点以及其它需要信号调理及电平转移的应用。

任务选择:查看芯片介绍,惊喜地发现这个开发板支持Arduino开发。于是愉快地决定使用Arduino作为这个开发的工具。选择了任务三: 自行选购来自DFRobot、Adafruit、Mikrobus、Sparkfun四个厂商其中的一个/多个厂商的至少一个传感器,搭配AVR64DD32 Curiosity Nano至少两个片内外设,完成任务,任务难度不低于以上两个任务。硬件上我选择了DFRobot的MEMS麦克风(SKU:SEN0487),这是一款超小体积的MEMS麦克风。放大器增益为66,当没有检测到声音时,输出电压在1.5V左右浮动,在说话时通过ADC采样可以很容易看到声音的波形。用这个数字麦克风来收集声音信息,然后通过一个LCD1602屏幕显示出来。LCD1602使用的是并口驱动,这里我做了一片PCF8574T,改为IIC来驱动LCD1602屏幕。FrrRE2VCo6LRZfbmuZAdhsuXzoeC
Flsc8wQw3ONdX8zt7KPNZLV5XGyrFsQW-WYfuVVMmGMfOUr5Njf-J-eT

环境搭建:拿到板卡,就遇到个头大的问题,官方写着支持Arduino。但是我是使用Vscode+Platformio。搭建环境就遇到了巨大的困难。在Funpack交流群里,各位老师的帮助下终于将Vscode+Platformio环境搭建起来了,这里做一下搭建的详细介绍。首先在电脑上按官方提示,搭建好Arduino的环境。https://github.com/SpenceKonde/DxCoreFqejT112N6t0YpDdVd-iR7zOSRrKFgmfLRmvwiX7m8stctfau0uqhdScFl0UC3GJ468qjC9s6a4gybqi2hfZ在Arduino中搭建好开发环境后,确保能够编译代码了,再在Vscode中进行配置。在C:\Users\aramy\.platformio\platforms\atmelmegaavr 用压缩包(github上下载的)atmelmegaavr.zip替换。再把toolchain-atmelavr.zip替换工具链。
FvDRNhX7049smLQPiFU_jglv2YmB新建一个AV64DD32的项目,修改配置文件:Platformio.ini

[env:AVR64DD32]
platform = atmelmegaavr
; board = AVR64DD32
framework = arduino
board = curiosity_nano_da

; change microcontroller
board_build.mcu = avr64dd32

; change MCU frequency
board_build.f_cpu = 24000000L

monitor_speed = 115200

简单的测试程序:main.c

#include <Arduino.h>
#define F_CPU 24000000
#define LED PIN_PF5
void setup()
{
  CCP=CCP_IOREG_gc;
  CLKCTRL.OSCHFCTRLA=CLKCTRL_FREQSEL_24M_gc;
  Serial1.begin(115200);
  pinMode(LED, OUTPUT);
  sei();
}

void loop()
{
  digitalWrite(LED, HIGH); // turn the LED on (HIGH is the voltage level)
  Serial1.println("hello world!");
  delay(3000);                     // wait for a second
  digitalWrite(LED, LOW);  // turn the LED off by making the voltage LOW
  Serial1.println("I am come here!");
  delay(1000);                     // wait for a second
}

可以编译,如果报错:
Fq4fYuG-g8YUiMAxB2ypWRR7NiUE

将错误提示的文件直接修改为:
Fh2QH_YkV4UtHogLymfGuaQDB85x

就可以编译上传了。不过串口需要外接模块使用。在老师的提醒下,使用模拟串口,输出到PD4,PD5完美解决了环境问题。

任务实现:FoZTkmSPScdQq25aDMQXYSLLms_Z有了开发环境,接下来就简单很多了。LCD1602屏幕是以前屯下来的老东东了。现在貌似用的不多了。LCD1602有16个管脚,驱动起来挺不容易的,印象中最少要用4条数据线去驱动。学着网上的教程,做了个IIC转并口的模块,Arduino下有对应的库,这里就直接调用LiquidCrystal_I2C库函数成功使用IIC来驱动起LCD1602了。
FsPvKDzzZUQv4sZBJauC1cDWXHHJ
DFRobot的MEMS麦克风,看介绍是一个数字麦克风,但是输出的依然是模拟信号。使用ADC的函数直接读取。因为是采集声音信息。所以不能够使用单一的信号AD值。这里我使用了256个数据。每间隔125u秒就采集一次,这样就模拟了8000Hz的采样率。然后将采集到的256个数据进行比较,取出最大值做显示。

//通过ADC读取麦克风的数据,使用8000的采样率
uint16_t vbuf[256];
uint16_t maxvoice;  //最大振幅声音
float  fenbei;
void readVoice(){
  uint16_t i=0;
  maxvoice = 0;
  for(;i<256;i++){
    vbuf[i]=analogRead(PIN_PD7);
    if(vbuf[i]>maxvoice) maxvoice=vbuf[i];
    delayMicroseconds(125);
  }
}


在网上找了一个声压公式。声压级(SPL)是最常用的声学参量,是指实测声压(P)与参考声压(P0)的比值之常用对数再乘以20的值,单位为分贝,其公式如下:声压级(分贝)= 20×lgP/P0。但对这个分贝值的计算始终是不太明白,计算出来的结果也是感觉怪怪的。不能很好地理解分贝值到底如何计算的。这里还遇到一个问题,LiquidCrystal_I2C库中显示函数print在显示浮点数时总是显示一个“?”,查看源代码,这里print没有实现浮点数的显示,所以在LCD1602上就只显示分贝的整数部分。

char str[6];
void loop()
{
  readVoice();
  //计算分贝值
  fenbei = 20 * log10(maxvoice/8); //转换分贝
  lcd.setCursor(5, 0);
  sprintf(str,"%4d",maxvoice);      //显示最大的声音值
  lcd.print(str);

  lcd.setCursor(5, 1);
  sprintf(str,"%d",int(fenbei));      //显示音强
  lcd.print(str);

  mySerial.print(maxvoice);
  mySerial.print("    ");
  mySerial.println(fenbei);

  delay(400);
}

Fgpjjp1AKzC6nV7aF7xk5ymb8za7

心得体会
感谢funpack带来的这期活动。 现在的8位单片机也如此有趣。既能支持C,也能跑Arduino。在交流群的老师带领下,开心地学习了一块开发板的使用!

附件下载
avr_eetree.zip
团队介绍
折腾小能手
团队成员
aramy
单片机业余爱好者,瞎捣鼓小能手。
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号