当前位置:   article > 正文

信号发生与测量装置_ad9833怎么输出正弦波

ad9833怎么输出正弦波

硬件

STM32F407ZGT6

4638fb894313473eab660f625cd8246e.png

信号的产生

1.AD9833 产生信号

        AD9833介绍

        AD9833 是一款低功耗、可编程的、基于DDS 技术的波形发生器芯片,能够产生正弦
波、三角波和方波并从一个端口输出。正弦波输出频率约可达10MHz,三角波输出频率约可达2MHz,方波输出频率约可达100kHz。输出频率和相位可通过程序修改。

        工作电压2.3V~5.5V,默认使用+5V。

        AD9833 通过一个三线式串行接口写入数据(时钟速率max=40MHz)。

a2cd001e7fa4416aba2e9bb73c902391.png

AD9833使用

引脚连接:

AD9833单片机IO口模式
SDATAPG10OUTPUT
SCLKPD5OUTPUT
FSYNCPD3OUTPUT

配置IO口:

ddff8cd306a34229b420d3f5cce7489c.png

 添加驱动文件,头文件路径:

d819656636214274b05f854a3ff53681.png

 编写代码:

        当IO口引脚的 User Label(宏定义)不同时,需要相应地修改驱动文件。

  1. /* mian.c */
  2. #include "ad9833.h"
  3. bsp_InitAD9833(); // 初始化ad9833
  4. AD9833_SelectWave(2); // 设置波形;0矩形波,1三角波,2正弦波,3无输出
  5. AD9833_SetFreq(1000); // 设置频率,单位HZ

2.DAC+TIM+DMA 产生信号

(104条消息) STM32cubemx教程 DAC+TIM+DMA_stm32 定时器dma dac cubemx_四臂西瓜的博客-CSDN博客

信号的测量

1.ADS8688 测量信号

ADS8688介绍

        ADS8688是8通道ADC模块。基于16位逐次逼近ADC。模拟SPI通信。

        5V供电。

328b2d85d8464edfada6c71596287517.png

ADS8688使用

ADS8688单片机IO口模式
CSPB3OUTPUT
RSTPB6OUTPUT
DAISYPA12OUTPUT
SDOPG8INPUT
CLKPG6OUTPUT
SDIPC8OUTPUT

e3035e545c7949f6a6e659c7a25591fd.png

编写代码:

        当IO口引脚的 User Label(宏定义)不同时,需要相应地修改驱动文件。

ADS8688手动采集

  1. /* main.c */
  2. #include "ads8688.h"
  3. /* main */
  4. uint16_t value[9];
  5. ADS8688_Init(CH0_EN|CH1_EN|CH2_EN|CH3_EN|CH4_EN|CH5_EN|CH6_EN|CH7_EN);//ADS8688初始化
  6. //设置通道输入范围
  7. Set_CH_Range(CHIR_0,ADS8688_IR_N2_5V);
  8. Set_CH_Range(CHIR_1,ADS8688_IR_N2_5V);
  9. Set_CH_Range(CHIR_2,ADS8688_IR_N2_5V);
  10. Set_CH_Range(CHIR_3,ADS8688_IR_N2_5V);
  11. Set_CH_Range(CHIR_4,ADS8688_IR_N2_5V);
  12. Set_CH_Range(CHIR_5,ADS8688_IR_N2_5V);
  13. Set_CH_Range(CHIR_6,ADS8688_IR_N2_5V);
  14. Set_CH_Range(CHIR_7,ADS8688_IR_N2_5V);
  15. MAN_CH_Mode(MAN_CH_0); // 手动模式选择通道
  16. value[0]=Get_MAN_CH_Mode_Data(); // 读取通道数据,ADC值
  17. // 读取通道数据,电压值,单位mv
  18. value[0]=(Get_MAN_CH_Mode_Data()-32768)*CONST_N2_5V_LSB_mV;

ADS8688自动采集

  1. /* main.c */
  2. #include "ads8688.h"
  3. /* main */
  4. uint16_t value[8];
  5. ADS8688_Init(CH0_EN|CH1_EN|CH2_EN|CH3_EN|CH4_EN|CH5_EN|CH6_EN|CH7_EN); // ADS8688初始化
  6. // 设置通道输入范围
  7. Set_CH_Range(CHIR_0,ADS8688_IR_N2_5V);
  8. Set_CH_Range(CHIR_1,ADS8688_IR_N2_5V);
  9. Set_CH_Range(CHIR_2,ADS8688_IR_N2_5V);
  10. Set_CH_Range(CHIR_3,ADS8688_IR_N2_5V);
  11. Set_CH_Range(CHIR_4,ADS8688_IR_N2_5V);
  12. Set_CH_Range(CHIR_5,ADS8688_IR_N2_5V);
  13. Set_CH_Range(CHIR_6,ADS8688_IR_N2_5V);
  14. Set_CH_Range(CHIR_7,ADS8688_IR_N2_5V);
  15. AUTO_RST_Mode();//进入自动扫描模式
  16. // 自动扫描模式,自动扫描并转换8通道。数据存在value数组中,ADC值
  17. Get_AUTO_RST_Mode_Data(value,8);

2.ADC+TIM+DMA 测量信号

(104条消息) STM32HAL ADC+TIM+DMA采集交流信号 基于cubemx_cubemx adc dma tim_四臂西瓜的博客-CSDN博客

配置ADC和DMA

        ADC配置为外部触发 ; 开启 DMA,DMA配置为normal模式。

e12c6c97a10141df879cba251507637d.png

 开启DMA

99a2625c22aa4f62902ae22264983543.png

配置TIM

        开启定时器中断。定时器和触发ADC的定时器对应。

        通过设置 PSC 和 ARR 来设置ADC触发频率,即采样频率。

4dcde51293314b3f8debe7381ce49394.png

 PSC = 0

ARR = 时钟频率 / 采样频率

  1. /* main.c */
  2. /* 全局变量 */
  3. uint16_t adc_buff[200];//存放ADC采集的数据
  4. __IO uint8_t AdcConvEnd = 0; // ADC采集完成标志
  5. /* main */
  6. HAL_TIM_Base_Start(&htim3); //开启定时器3
  7. HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_buff, 200); //让ADC1去采集200个数,存放到adc_buff数组里
  8. /* while(1) */
  9. if(1 == AdcConvEnd) // ADC采集完成
  10. {
  11. }
  1. /* stm32f4xx_it.c */
  2. extern uint8_t AdcConvEnd;//引入外部变量
  3. /*
  4. DMA中断服务函数
  5. void DMA2_Stream0_IRQHandler(void)
  6. */
  7. AdcConvEnd = 1;

信号的处理

1.ARM-DPS库

通过源码添加DSP库

1.工程目录下新建 DSP_LIB文件夹,引用DSP库文件

CUBEMX生成的代码,KEIL内的文件夹不能命名为 DSP_LIB,可以写成DSP

6d7895305d9a4ae1b0cc914039e5478d.png

8e35a235ec084a8a98e5bf0167f8ad43.png

2.添加头文件包含路径

f9491d6731a44ab7ba670270269b3355.png

3.添加全局宏定义

在 Define里设置全局宏定义

标准库,覆盖原来的:

STM32F40_41xxx,USE_STDPERIPH_DRIVER,ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING

CUBEMX生成,在原来的基础上添加:       

,ARM_MATH_CM4,__CC_ARM,ARM_MATH_MATRIX_CHECK,ARM_MATH_ROUNDING

DSP库的使用

FFT变换

FFT变换的原理的用途

        FFT(快速傅里叶变换)是一种用于将时域信号转换为频域信号的算法。它通过对时域信号进行傅里叶变换,将信号的频谱分解成不同频率的分量。

        FFT 可以用于频谱分析,滤波,数据分析。

FFT变换的实现

  1. /* main.c */
  2. #include "arm_math.h"
  3. #include "arm_const_structs.h"
  4. /* 全局变量 */
  5. #define FFT_LENGTH 4096 // FFT变换长度
  6. float fft_inputbuf[FFT_LENGTH*2]; // FFT变换输入数组
  7. float fft_outputbuf[FFT_LENGTH]; // FFT变换输出数组
  8. /* main */
  9. arm_cfft_radix4_instance_f32 scfft;
  10. arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//初始化scfft结构体,设定FFT相关参数
  11. uint32_t MAXindex = 0; // FFT输出最大值的数组下标
  12. float32_t MaxValue = 0; // FFT输出最大值
  13. uint32_t frequency = 0; // 频率
  14. /* while(1) */
  15. /* FFT变换输入数组赋值 */
  16. for(int i=0; i<FFT_LENGTH; i++)
  17. {
  18. // 实部电压值
  19. fft_inputbuf[2*i] = (float)ADC1_ConvertedValue[i] * 3.3 / 4096;
  20. // 虚部0
  21. fft_inputbuf[2*i+ 1] = 0;
  22. }
  23. arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT计算(基4)
  24. arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH); //把运算结果复数求模得幅值
  25. /* 找出幅值最大的下标,第一个参数是起始地址,这里是[1],所以去掉了[0],即直流分量*/
  26. arm_max_f32(&fft_outputbuf[1], FFT_LENGTH / 2, &MaxValue, &MAXindex);
  27. /* 频率 = 最大幅值的数组下标 * 采样率 / FFT计算点数 */
  28. frequency = (float32_t)MAXindex * (float32_t)SAM_FRE / (float32_t) FFT_LENGTH;

2.排序算法

快速排序

  1. #include <stdio.h>
  2. void bubble_sort(int arr[], int len) {
  3.         int i, j, temp;
  4.         for (i = 0; i < len - 1; i++)
  5.                 for (j = 0; j < len - 1 - i; j++)
  6.                         if (arr[j] > arr[j + 1]) {
  7.                                 temp = arr[j];
  8.                                 arr[j] = arr[j + 1];
  9.                                 arr[j + 1] = temp;
  10.                         }
  11. }
  12. int main() {
  13.         int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
  14.         int len = sizeof(arr) / sizeof(arr[0]);
  15.         bubble_sort(arr, len);
  16.         int i;
  17.         for (i = 0; i < len; i++)
  18.                 printf("%d ", arr[i]);
  19.         return 0;
  20. }

信号的显示

1.串口屏显示

串口屏显示参数、文字用文本控件就行,显示波形用波形控件

淘晶驰资料中心 — 淘晶驰资料中心 1.1.0-2023-07-15 12:32:54 文档 (tjc1688.com)

配置单片机

配置 USART2 ,设置波特率,开启中断。

d01df8f1503c4cf49216d7b4ffd020c3.png

d39aa9995192476096284424b4d8df37.png

配置串口屏 

8814d9399ae44e068f3ae72277efd0d0.png

 设置串口屏波特率,与单片机相同。

a6942c0f5c7b434cb979fb73f201e1df.png

 添加字库

60caee7a99f94d0489e59be3f1c84ea2.png

添加控件

文本控件

内存占用设置为全局访问。

62010530a16b4790b84d5232c8021b5c.png

波形控件

内存占用设置为全局访问。

1e92864a457541a29adb536340199e03.png

  1. /* main.c */
  2. #include "string.h"
  3. #include "stdio.h"
  4. char temp[30];
  5. /* 文本控件 objname = t0*/
  6. sprintf(temp, "t0.txt=\"abc\"\xff\xff\xff");
  7. HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);
  8. /* 文本控件 objname = t1*/
  9. sprintf(temp, "t1.txt=\"ww\"\xff\xff\xff");
  10. HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);
  11. /* 波形控件 objname = s0*/
  12. // 发送要传输的数据量 数据量最多不超过1024个 ,数据取值范围[0, 255]
  13. sprintf(temp, "addt s0.id,0,100\xff\xff\xff");
  14. HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);
  15. HAL_Delay(100);
  16. // 透传数据
  17. for(int i=0; i<100; i++)
  18. {
  19. sprintf(temp, "%c", i);
  20. HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);
  21. }
  22. // 发送透传结束指令
  23. sprintf(temp, "\x01\xff\xff\xff");
  24. HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);
  25. HAL_Delay(1000);
  26. // 清除波形控件s0的0通道数据,不能跨页面使用
  27. sprintf(temp, "cle s0.id,0\xff\xff\xff");
  28. HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);

2.蓝牙和上位机显示

配置蓝牙

蓝牙5V供电

20ab8a29f1a04b9fa6c923aeef826363.png

按住按钮上电,进入AT模式

搜索端口,获取模块信息。

修改模块信息:设备名称,连接密码,波特率。

更新模块信息。 

0562d5d80dd94577845293946ead2b51.png

配置单片机

配置 USART3 ,设置波特率,开启中断。

ed49fde9e89f4e419ab369af921427d8.png

5202b6a9937e41b4bce6273686cef927.png

导入蓝牙数据包文件

adc353ac55b04b45acadfd253915ac9e.png

 3ac1aee5758d40a8841a6218084e2348.png

添加头文件路径

 bacc5d1e132d4b39aa97c6f88ce7a339.png

 设置发送和接收数据包结构

bool byte short int float 五种类型

用 int 和 float 类型即可。

59e6e50d00294ca38b9406d04bf4999f.png

  1. #include "Bluetooth.h"
  2. TxPack txpack;//蓝牙发送数据包
  3. /* 蓝牙数据包赋值 */
  4. txpack.floats[0] = Thd;//THD
  5. sendValuePack(&txpack); // 发送蓝牙数据包

配置上位机

创建上位机工程

0c78ea631cad4edba6acbf271d925cd6.jpeg

 设置数据包格式

 2583ec7060644e3fa370b3be449d4f22.jpeg

 添加控件,显示参数用 文本 ; 显示波形用 Y-T一维波形。

024e6daa1a8443448e0b3f115c62b373.png

 选中控件后,连接数据

c4405bfa9b1c4a579a5735c5391c2c22.jpeg

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/959319
推荐阅读
相关标签
  

闽ICP备14008679号