硬件
STM32F407ZGT6
信号的产生
1.AD9833 产生信号
AD9833介绍
AD9833 是一款低功耗、可编程的、基于DDS 技术的波形发生器芯片,能够产生正弦
波、三角波和方波并从一个端口输出。正弦波输出频率约可达10MHz,三角波输出频率约可达2MHz,方波输出频率约可达100kHz。输出频率和相位可通过程序修改。
工作电压2.3V~5.5V,默认使用+5V。
AD9833 通过一个三线式串行接口写入数据(时钟速率max=40MHz)。
AD9833使用
引脚连接:
AD9833 | 单片机 | IO口模式 |
SDATA | PG10 | OUTPUT |
SCLK | PD5 | OUTPUT |
FSYNC | PD3 | OUTPUT |
配置IO口:
添加驱动文件,头文件路径:
编写代码:
当IO口引脚的 User Label(宏定义)不同时,需要相应地修改驱动文件。
/* mian.c */
#include "ad9833.h"
bsp_InitAD9833(); // 初始化ad9833
AD9833_SelectWave(2); // 设置波形;0矩形波,1三角波,2正弦波,3无输出
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供电。
ADS8688使用
ADS8688 | 单片机 | IO口模式 |
CS | PB3 | OUTPUT |
RST | PB6 | OUTPUT |
DAISY | PA12 | OUTPUT |
SDO | PG8 | INPUT |
CLK | PG6 | OUTPUT |
SDI | PC8 | OUTPUT |
编写代码:
当IO口引脚的 User Label(宏定义)不同时,需要相应地修改驱动文件。
ADS8688手动采集
/* main.c */
#include "ads8688.h"
/* main */
uint16_t value[9];
ADS8688_Init(CH0_EN|CH1_EN|CH2_EN|CH3_EN|CH4_EN|CH5_EN|CH6_EN|CH7_EN);//ADS8688初始化
//设置通道输入范围
Set_CH_Range(CHIR_0,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_1,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_2,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_3,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_4,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_5,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_6,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_7,ADS8688_IR_N2_5V);
MAN_CH_Mode(MAN_CH_0); // 手动模式选择通道
value[0]=Get_MAN_CH_Mode_Data(); // 读取通道数据,ADC值
// 读取通道数据,电压值,单位mv
value[0]=(Get_MAN_CH_Mode_Data()-32768)*CONST_N2_5V_LSB_mV;
ADS8688自动采集
/* main.c */
#include "ads8688.h"
/* main */
uint16_t value[8];
ADS8688_Init(CH0_EN|CH1_EN|CH2_EN|CH3_EN|CH4_EN|CH5_EN|CH6_EN|CH7_EN); // ADS8688初始化
// 设置通道输入范围
Set_CH_Range(CHIR_0,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_1,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_2,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_3,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_4,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_5,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_6,ADS8688_IR_N2_5V);
Set_CH_Range(CHIR_7,ADS8688_IR_N2_5V);
AUTO_RST_Mode();//进入自动扫描模式
// 自动扫描模式,自动扫描并转换8通道。数据存在value数组中,ADC值
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模式。
开启DMA
配置TIM
开启定时器中断。定时器和触发ADC的定时器对应。
通过设置 PSC 和 ARR 来设置ADC触发频率,即采样频率。
PSC = 0
ARR = 时钟频率 / 采样频率
/* main.c */
/* 全局变量 */
uint16_t adc_buff[200];//存放ADC采集的数据
__IO uint8_t AdcConvEnd = 0; // ADC采集完成标志
/* main */
HAL_TIM_Base_Start(&htim3); //开启定时器3
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc_buff, 200); //让ADC1去采集200个数,存放到adc_buff数组里
/* while(1) */
if(1 == AdcConvEnd) // ADC采集完成
{
}
/* stm32f4xx_it.c */
extern uint8_t AdcConvEnd;//引入外部变量
/*
DMA中断服务函数
void DMA2_Stream0_IRQHandler(void)
*/
AdcConvEnd = 1;
信号的处理
1.ARM-DPS库
通过源码添加DSP库
1.工程目录下新建 DSP_LIB文件夹,引用DSP库文件
CUBEMX生成的代码,KEIL内的文件夹不能命名为 DSP_LIB,可以写成DSP
2.添加头文件包含路径
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变换的实现
/* main.c */
#include "arm_math.h"
#include "arm_const_structs.h"
/* 全局变量 */
#define FFT_LENGTH 4096 // FFT变换长度
float fft_inputbuf[FFT_LENGTH*2]; // FFT变换输入数组
float fft_outputbuf[FFT_LENGTH]; // FFT变换输出数组
/* main */
arm_cfft_radix4_instance_f32 scfft;
arm_cfft_radix4_init_f32(&scfft,FFT_LENGTH,0,1);//初始化scfft结构体,设定FFT相关参数
uint32_t MAXindex = 0; // FFT输出最大值的数组下标
float32_t MaxValue = 0; // FFT输出最大值
uint32_t frequency = 0; // 频率
/* while(1) */
/* FFT变换输入数组赋值 */
for(int i=0; i<FFT_LENGTH; i++)
{
// 实部电压值
fft_inputbuf[2*i] = (float)ADC1_ConvertedValue[i] * 3.3 / 4096;
// 虚部0
fft_inputbuf[2*i+ 1] = 0;
}
arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT计算(基4)
arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf,FFT_LENGTH); //把运算结果复数求模得幅值
/* 找出幅值最大的下标,第一个参数是起始地址,这里是[1],所以去掉了[0],即直流分量*/
arm_max_f32(&fft_outputbuf[1], FFT_LENGTH / 2, &MaxValue, &MAXindex);
/* 频率 = 最大幅值的数组下标 * 采样率 / FFT计算点数 */
frequency = (float32_t)MAXindex * (float32_t)SAM_FRE / (float32_t) FFT_LENGTH;
2.排序算法
快速排序
#include <stdio.h>
void bubble_sort(int arr[], int len) {
int i, j, temp;
for (i = 0; i < len - 1; i++)
for (j = 0; j < len - 1 - i; j++)
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
int main() {
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, len);
int i;
for (i = 0; i < len; i++)
printf("%d ", arr[i]);
return 0;
}
信号的显示
1.串口屏显示
串口屏显示参数、文字用文本控件就行,显示波形用波形控件。
淘晶驰资料中心 — 淘晶驰资料中心 1.1.0-2023-07-15 12:32:54 文档 (tjc1688.com)
配置单片机
配置 USART2 ,设置波特率,开启中断。
配置串口屏
设置串口屏波特率,与单片机相同。
添加字库
添加控件:
文本控件
内存占用设置为全局访问。
波形控件
内存占用设置为全局访问。
/* main.c */
#include "string.h"
#include "stdio.h"
char temp[30];
/* 文本控件 objname = t0*/
sprintf(temp, "t0.txt=\"abc\"\xff\xff\xff");
HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);
/* 文本控件 objname = t1*/
sprintf(temp, "t1.txt=\"ww\"\xff\xff\xff");
HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);
/* 波形控件 objname = s0*/
// 发送要传输的数据量 数据量最多不超过1024个 ,数据取值范围[0, 255]
sprintf(temp, "addt s0.id,0,100\xff\xff\xff");
HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);
HAL_Delay(100);
// 透传数据
for(int i=0; i<100; i++)
{
sprintf(temp, "%c", i);
HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);
}
// 发送透传结束指令
sprintf(temp, "\x01\xff\xff\xff");
HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);
HAL_Delay(1000);
// 清除波形控件s0的0通道数据,不能跨页面使用
sprintf(temp, "cle s0.id,0\xff\xff\xff");
HAL_UART_Transmit(&huart2, (uint8_t *)temp, strlen(temp), 1000);
2.蓝牙和上位机显示
配置蓝牙
蓝牙5V供电
按住按钮上电,进入AT模式
搜索端口,获取模块信息。
修改模块信息:设备名称,连接密码,波特率。
更新模块信息。
配置单片机
配置 USART3 ,设置波特率,开启中断。
导入蓝牙数据包文件
添加头文件路径
设置发送和接收数据包结构
bool byte short int float 五种类型
用 int 和 float 类型即可。
#include "Bluetooth.h"
TxPack txpack;//蓝牙发送数据包
/* 蓝牙数据包赋值 */
txpack.floats[0] = Thd;//THD
sendValuePack(&txpack); // 发送蓝牙数据包
配置上位机
创建上位机工程
设置数据包格式
添加控件,显示参数用 文本 ; 显示波形用 Y-T一维波形。
选中控件后,连接数据