370|0

10

帖子

2

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第2期】+ 基础任务 点阵LED+DAC正弦波+OPAMP+波形显示 [复制链接]

  本帖最后由 cqut面码 于 2024-9-30 00:39 编辑

1、前言

前面学习了环境的搭建、LED的点亮翻转、以及串口的输出。接着就来学习基础任务里面的一些内容, 驱动12x8点阵LED和用DAC生成正弦波。

 

2、 驱动12x8点阵LED

先放官方的链接https://docs.arduino.cc/tutorials/uno-r4-wifi/led-matrix/,官方给出了详细的这个LED矩阵点亮的实现方式,我们可以通过官方的文档来进行学习,

并完成这个矩阵LED的实验,嵌入式就是得多看看官方资料,不要一个人闭门造车。快速实现了,再去了解原理,深入消化,才不会打击学习的积极性。

 

官方已经给出一个驱动点了这个矩阵LED库函数,我们只需要包含使用就好了。如下是输出一个爱心的框图,详细的各个功能都在代码中进行了注释说明

核心思想就是通过把自己要显示的LED矩阵相关的数据,直接写入就好,实际就是通过IO通过LED矩阵的亮灭。

 

 

画出一个心形的代码如下:

#include "Arduino_LED_Matrix.h"  /*包含官方的驱动库*/
ArduinoLEDMatrix led_matrix;  //实例化一个对象


/*串口初始化函数*/
void uart_init(uint32_t baud)
{
   Serial.begin(baud);  
}


/* 爱心的框图 */
byte frame[8][12] = {
  { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
  { 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
  { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
  { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};


void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT); /* 设置13引脚为输出模式 */
  digitalWrite(13, HIGH); /* 默认输出为高*/
  Serial.begin(115200);
  led_matrix.begin();   //初始化启动这个对象
  led_matrix.renderBitmap(frame, 8, 12);  //把LED矩阵的数据写入
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(500); 
  digitalWrite(13, !digitalRead(13));  /* 每500ms进行一次LED灯的翻转*/
}

 

实际效果如下:

  

3、 用DAC生成正弦波

Arduino UNO R4 WiFi 内置DAC(数模转换器),用于将数字信号转换为模拟信号。这里我们直接用DAC输出一个正弦波,然后用示波器去观察器输出的波形

先看原理图DAC的输出口是哪个,从原理图上可以看到,开发板上引出的DAC引脚为A0,等会我们直接用示波器测量A0即可。

 

 

然后,参考官网的代码 https://docs.arduino.cc/tutorials/uno-r4-wifi/dac/,完成DAC正弦波的输出,代码我们在前面的基础上继续完善,具体如下:

这里只是生成可一个50HZ的sin波形并没有在循环中去改变频率或者波形等其他进操作

#include "Arduino_LED_Matrix.h"  /*包含官方的驱动库*/
#include "analogWave.h" // 包含波形输出的模拟文件

ArduinoLEDMatrix led_matrix;  //实例化一个对象
analogWave wave(DAC);   //实例化一个对象

/*串口初始化函数*/
void uart_init(uint32_t baud)
{
   Serial.begin(baud);  
}


/* 爱心的框图 */
byte frame[8][12] = {
  { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
  { 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
  { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
  { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};


void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT); /* 设置13引脚为输出模式 */
  digitalWrite(13, HIGH); /* 默认输出为高*/
  Serial.begin(115200);
  led_matrix.begin();   //初始化启动这个对象
  led_matrix.renderBitmap(frame, 8, 12);  //把LED矩阵的数据写入
  wave.sine(50);     //产生一个50HZ的sin波形
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(500); 
  digitalWrite(13, !digitalRead(13));  /* 每500ms进行一次LED灯的翻转*/
}

实际示波器测试的效果如下,可以看出最大值为4.6v,最小值为-13mv,频率为49.9HZ左右,波形确实比较难看,锯齿状态还是很严重的,按理说这个板子的12位的DAC性能应不止这样,

应该是内部封装的效果导致一个周期数据输出太少的原因,看来还是得上IDF编程才行。

另外还有一个问题就是,为啥最大值为4.6V,而不是5V,我怀疑是设计缺陷,DAC的参考电压不准,不是5V。时间原因就不去验证了

 

 

4、 使用OPAMP对上面的DAC信号放大

OPAMP 实际用处还是很大的,在性能要求不高的情况下,直接使用板载的OPAMP进行放大信号,可以节约成本,避免外部在接一个运放。

当然OPAMP还有一个作用就是做电压跟随器,电压跟随器具有高输入阻抗和低输出阻抗——这是它们缓冲作用的本质,它们增强信号,从而允许高阻抗源驱动低阻抗负载。

 

这里我们就只展示放大的作用。具官方文档可以参考学习https://docs.arduino.cc/tutorials/uno-r4-wifi/opamp

从前面的实验已经看出了,直接输出的波形已经幅度值已经达到了4.7V,这已经是DAC输出的最大值了。如果我们再在这个基础上去放大这个信号,无疑就会超过4.7V。

就会出现两种情况 1、会出现削波 2、可能损坏电路板。为了后续放大实验方便,我们限制一下幅度值,输出到最大值的1/4即可,便于后续放大波形:

代码很简单,实际就是在setup中多了一个对波形幅值的限制, wave.amplitude(0.25); //设置幅度值为4.7 的1/4

 

#include "Arduino_LED_Matrix.h"  /*包含官方的驱动库*/
#include "analogWave.h" // 包含波形输出的模拟文件

ArduinoLEDMatrix led_matrix;  //实例化一个对象
analogWave wave(DAC);   //实例化一个对象

/*串口初始化函数*/
void uart_init(uint32_t baud)
{
   Serial.begin(baud);  
}


/* 爱心的框图 */
byte frame[8][12] = {
  { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
  { 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
  { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
  { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};


void setup() {
  // put your setup code here, to run once:
  pinMode(13, OUTPUT); /* 设置13引脚为输出模式 */
  digitalWrite(13, HIGH); /* 默认输出为高*/
  Serial.begin(115200);
  led_matrix.begin();   //初始化启动这个对象
  led_matrix.renderBitmap(frame, 8, 12);  //把LED矩阵的数据写入
  wave.sine(50);     //产生一个50HZ的sin波形
  wave.amplitude(0.25); //设置幅度值为4.7 的1/4
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(500); 
  digitalWrite(13, !digitalRead(13));  /* 每500ms进行一次LED灯的翻转*/
}

 

实际示波器实测效果如果下,还是挺符合4.7V的 1/4 波形的。

  

 

好了,有了基础波形,我们就来搭建运放把。额,为了搭建运放的电路,我去找了好久的电阻,建议下次不搞这种,薄膜电阻真的很难找呀,还得找块面包板。

 

运算放大器放大电路示意图如下所示:

 

实际用于两个10K的电阻和洞洞板搭建的电路图如下所示:

 

下面是搭建了2倍放大后的示波器效果图:黄色为放大前的波形图,蓝色为经过放大后的波形图。

 最后附上本次实验的代码:

相对于前面而言,只是添加了一句代码。打开了OPAMP

 OPAMP.begin(OPAMP_SPEED_HIGHSPEED);  //开启放大器

#include "Arduino_LED_Matrix.h"  /*包含官方的驱动库*/
#include "analogWave.h" // 包含波形输出的模拟文件
#include <OPAMP.h>

ArduinoLEDMatrix led_matrix;  //实例化一个对象
analogWave wave(DAC);   //实例化一个对象

/*串口初始化函数*/
void uart_init(uint32_t baud)
{
   Serial.begin(baud);  
}


/* 爱心的框图 */
byte frame[8][12] = {
  { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
  { 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
  { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
  { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};


void setup() {
  // put your setup code here, to run once:
  OPAMP.begin(OPAMP_SPEED_HIGHSPEED);  //开启放大器
  pinMode(13, OUTPUT); /* 设置13引脚为输出模式 */
  digitalWrite(13, HIGH); /* 默认输出为高*/
  Serial.begin(115200);
  led_matrix.begin();   //初始化启动这个对象
  led_matrix.renderBitmap(frame, 8, 12);  //把LED矩阵的数据写入
  wave.sine(50);     //产生一个50HZ的sin波形
  wave.amplitude(0.25); //设置幅度值为4.7 的1/4
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(500); 
  digitalWrite(13, !digitalRead(13));  /* 每500ms进行一次LED灯的翻转*/
}


5、上位机波形展示

我们使用A4 和 A5 引脚分别采集DAC的输出,和经过OPAMP放大之后的信号输出。然后通过串口发送到上位机进行波形的展示。

使用了  analogReadResolution(14); //change to 14-bit resolution 配置ADC的分辨率最高为14bit

使用了   float Rvalue1 = analogRead(A4) * 4.7/16383;  //读取A4的引脚电压 

实际的代码如下:

#include "Arduino_LED_Matrix.h"  /*包含官方的驱动库*/
#include "analogWave.h" // 包含波形输出的模拟文件
#include <OPAMP.h>

ArduinoLEDMatrix led_matrix;  //实例化一个对象
analogWave wave(DAC);   //实例化一个对象

/*串口初始化函数*/
void uart_init(uint32_t baud)
{
   Serial.begin(baud);  
}


/* 爱心的框图 */
byte frame[8][12] = {
  { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
  { 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
  { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
  { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};


void setup() {
  // put your setup code here, to run once:
  OPAMP.begin(OPAMP_SPEED_HIGHSPEED);  //开启放大器
  pinMode(13, OUTPUT); /* 设置13引脚为输出模式 */
  digitalWrite(13, HIGH); /* 默认输出为高*/
  Serial.begin(2000000);
  led_matrix.begin();   //初始化启动这个对象
  led_matrix.renderBitmap(frame, 8, 12);  //把LED矩阵的数据写入
  wave.sine(50);     //产生一个50HZ的sin波形
  wave.amplitude(0.25); //设置幅度值为4.7 的1/4

  //配置ADC的分辨率最高为14bit
  analogReadResolution(14); //change to 14-bit resolution
}


void loop() {
  float Rvalue1 = analogRead(A4) * 4.7/16383;  //读取A4的引脚电压
  float Rvalue2 = analogRead(A5) * 4.7/16383;  //读取A5的引脚电压
  Serial.print(Rvalue1);
  Serial.print(",");
  Serial.println(Rvalue2); 
  delay(2); 
}

最后我们把我们的波形在IDE上自带的串口绘图仪展示出来,可以看到基本上波形2是波形1的2倍数据关系。

 这个实验中,为了方便展示波形,我们把串口的波特率调整到了最高

 

6、源代码以及展示视频


 

 

 

dac_output.7z

857 Bytes, 下载次数: 0

dac_output_opamp.7z

984 Bytes, 下载次数: 0

放大波形+上位机暂展示波形进行了合并

led_matrix.7z

745 Bytes, 下载次数: 0

点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表