驱动---1.DAC8552实现三角波输出

news2024/12/26 23:23:07

最近开始进行新项目的研发,考虑用DAC做一个前级输出,选择了DAC8552这个器件的一个模块,用了野火的指南者做主控,芯片是STM32F103VET6,主频是72MHz。

一、器件手册重要信息提取

1.DAC8552具有十六位的分辨率、双通道输出、通电后复位为零刻度、供电电压是2.7V-5.5V,轨到轨输出,在供电电压为5V的时候输出频率可以达到30MHz。
2.器件引脚说明

在这里插入图片描述
<1>2引脚,作为参考的基准电压,也就是和电压输出范围有关系的.计算公式如下:
VREF就是基准电压的大小
在这里插入图片描述
<2>5引脚SYNC相当于SPI的片选线,下降时也就是低电平时,启动输入移位寄存器,数据在SCLK的下降边沿进行传输。8位控制字节和16位数据字的操作由24个下降沿的SCLK时钟边缘触发(除非在该边缘之前SYNC被置为高电平,在这种情况下,SYNC的上升沿作为中断信号,写序列被DAC8552忽略)。

3.短路电流大小

在这里插入图片描述

4.数据输出的时序

高位在前三个字节二十四位数据,第一个字节高八位是控制字节、第二个字节和第三个字节十六位是数据。
在这里插入图片描述

5.高八位的控制说明

在这里插入图片描述
DB23和DB22 00
DB21和DB20 00两个通道都不加载 11同时加载DACA和DACB 01加载DACA并输出在完成后达到指定值 10加载DACB并输出在完成后达到指定值
DB19 0或1都行,一般情况下我会取0
D18 0=A 1=B 0:写入数据缓冲区A 1:写入数据缓冲区B
DB17和DB16 两个都取0就是正常模式
DB0-DB15 两个字节十六位的数据

6.手册中比较重要内容的截图

可能有重复地方加深一下印象
在这里插入图片描述
在这里插入图片描述

7.手册通信举例

示例重点看一下LDB\LDA\Buffer Select三个位,基本就搞明白哪个通道输出不输出了。
在项目开发中,我直接使用的事示例2的第一个,通过DACA去做输出。
<1>示例1:通过缓冲区B写入数据缓冲区A,同时通过DAC B加载DAC A
写入数据缓冲区A
在这里插入图片描述
写入数据缓冲区B,同时加载DAC A和DAC B
在这里插入图片描述
<2>示例2:将新数据依次加载到DAC A和DAC B
写入数据缓冲区A并加载DAC A:DAC A输出在完成后稳定到指定值:
在这里插入图片描述
写入数据缓冲区B并加载DAC B:DAC B输出在完成后达到指定值:
在这里插入图片描述
示例3:同时断电DAC A至1kΩ,断电DAC B至100kΩ
对数据缓冲区A写入减电命令
在这里插入图片描述
将断电命令写入数据缓冲区B,同时加载DAC A和DAC B
在这里插入图片描述
示例4:DAC A和DAC B依次断电高阻抗
将断电命令写入数据缓冲区A并加载DAC A: DAC A输出= Hi-Z:
在这里插入图片描述
将断电命令写入数据缓冲区B和加载DAC B: DAC B输出= Hi-Z:
在这里插入图片描述

二、项目说明

1.项目需求

使用该器件主要做一级的三角波输出,后级作用与处理在这里不进行详细说明。目标波形参数如下:五种三角波
在这里插入图片描述

2.关于输出计算问题

在这里插入图片描述
我的硬件设计中,基准电压是5V,因此要输出相应的电压大小,算出对应的D值即可,在设计中我直接设定D值为15000了,这是为了满足我的项目。

3.软硬件说明

因为是做立项测试,先用了野火的指南者开发板和该模块进行通信,使用HAl库的编程思想。

三、开发记录

1HAL库的设定

<1>RCC的设定
在这里插入图片描述
<2>SYS的设定
在这里插入图片描述
<3>USART的设定
在这里插入图片描述
<4>定时器2的设定
10us进入一次定时器2中断
在这里插入图片描述
<5>SPI设定
这个需要注意一下,DAC的最高通信速率是30M,我在这里设定了18M。
通信中是下降沿读取数据,因此CPOL和CPHA分别设定为LOW 2Edge
在这里插入图片描述
<6>NVIC
在这里插入图片描述
<7>芯片引脚图<7>芯片引脚图
在这里插入图片描述

四、编程

按键切换五种三角波状态,直接把main.c粘贴进来了,野火的原理图可以直接去网上搜就可以了

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi1;

TIM_HandleTypeDef htim2;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
//满偏的时候是准确的一半,但是下面就是不完全精准了
uint16_t DAC_Tx=0;	//理论上对应的是2V,减半为1V。0.996	28000
uint32_t TIM_FLAG=0;
//1-5对应五种模式	0对应空状态
uint8_t Triange_Mode=0;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM2_Init(void);
/* USER CODE BEGIN PFP */
void ADC8552_Data(uint16_t *ADC8552_Data);
void Scan_Mode(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	//第一个字节:0	0	0 1 0 0 0 0		0x10
	//第二个和第三个字节	发送一个1V的电压对应的二进制数据
	//13000 对应差不多0.98V	0011	0010	1100	1000	0x32	0xB8
//	uint8_t SPI1_Receive[]={0x10,0xFF,0xFF};

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_SPI1_Init();
  MX_USART1_UART_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	//开启定时器2
	HAL_TIM_Base_Start_IT(&htim2);
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		//三角波说明	一共五个波形
		//			 状态						t宽					t升					t降					t止
		//参数1:神经失用				1ms					1ms					0						20ms
		//参数2:轻度失神经			10-50ms			10-50ms			1ms					50-150ms
		//参数3:中度失神经			50-150ms		50-150ms		30-100ms		500-1000ms
		//参数4:重度失神经			150-300ms		150-300ms		60-200ms		1000-3000ms
		//参数5:极重度失神经		400-600ms		400-600ms		200-300ms		1000-5000ms
		Scan_Mode();
//		while(1);
  }
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/**
  * @brief SPI1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SPI1_Init(void)
{

  /* USER CODE BEGIN SPI1_Init 0 */

  /* USER CODE END SPI1_Init 0 */

  /* USER CODE BEGIN SPI1_Init 1 */

  /* USER CODE END SPI1_Init 1 */
  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SPI1_Init 2 */

  /* USER CODE END SPI1_Init 2 */

}

/**
  * @brief TIM2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM2_Init(void)
{

  /* USER CODE BEGIN TIM2_Init 0 */

  /* USER CODE END TIM2_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};

  /* USER CODE BEGIN TIM2_Init 1 */

  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 72-1;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 10-1;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */

  /* USER CODE END TIM2_Init 2 */

}

/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{

  /* USER CODE BEGIN USART1_Init 0 */

  /* USER CODE END USART1_Init 0 */

  /* USER CODE BEGIN USART1_Init 1 */

  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */

  /* USER CODE END USART1_Init 2 */

}

/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(DAC855X_SYNC_GPIO_Port, DAC855X_SYNC_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin : DAC855X_SYNC_Pin */
  GPIO_InitStruct.Pin = DAC855X_SYNC_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(DAC855X_SYNC_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : KEY1_MODE_Pin */
  GPIO_InitStruct.Pin = KEY1_MODE_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(KEY1_MODE_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pin : LED_Pin */
  GPIO_InitStruct.Pin = LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(LED_GPIO_Port, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 0);
  HAL_NVIC_EnableIRQ(EXTI0_IRQn);

}

/* USER CODE BEGIN 4 */
//传递数据	第一个字节是数据的高八位,第二个字节是数据的低八位
void ADC8552_Data(uint16_t *ADC8552_Data)
{
		uint8_t SPI_Tx[3]={0x10,0,0};
		//数据的低八位
		SPI_Tx[2]=(uint8_t)(*ADC8552_Data)|0x00;
//		HAL_UART_Transmit(&huart1,&SPI_Tx[2],1,1000);
		//数据的高八位
		SPI_Tx[1]=(uint8_t)(*ADC8552_Data>>8)|0x00;
//		HAL_UART_Transmit(&huart1,&SPI_Tx[1],1,1000);
//		SPI_Tx[2]=0x66;
//		SPI_Tx[1]=0x66;
		//控制字节
//		SPI_Tx[0]=0x10;
//		HAL_UART_Transmit(&huart1,&SPI_Tx[0],1,1000);
		//将传递进来的数据进行分字节处理
			
		//开启DAC的片选
		HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_RESET); 
		//发送第一个字节数据
		HAL_SPI_Transmit(&hspi1,&SPI_Tx[0],1,1000);
		//发送第二个字节数据
		HAL_SPI_Transmit(&hspi1,&SPI_Tx[1],1,1000);		
		//发送第三个字节数据		
		HAL_SPI_Transmit(&hspi1,&SPI_Tx[2],1,1000);	
		//关闭DAC的片选
		HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_SET); 
}
//按键实现模式的切换
void Scan_Mode(void)
{
		//三角波说明	一共五个波形
		//			 状态						t宽					t升					t降					t止							示波器状态
		//参数1:神经失用				1ms					1ms					0						20ms						1V---1ms
		//参数2:轻度失神经			10-50ms			10-50ms			1ms					50-150ms
		//参数3:中度失神经			50-150ms			50-150ms			30-100ms			500-1000ms
		//参数4:重度失神经			150-300ms		150-300ms		60-200ms			1000-3000ms
		//参数5:极重度失神经		400-600ms		400-600ms		200-300ms		1000-5000ms	
		//神经失用模式
		if(Triange_Mode==1)
		{
			if(TIM_FLAG<=100)
			{
				ADC8552_Data(&DAC_Tx);
			}
			else	if((TIM_FLAG>100)&&(TIM_FLAG<2100))
			{
				DAC_Tx=0;
				ADC8552_Data(&DAC_Tx);
			}
			else if((TIM_FLAG>=2100))
			{
				TIM_FLAG=0;
			}			
		}	
		else if(Triange_Mode==2)//轻度失神经
		{
			if(TIM_FLAG<=1100)	//包括上升和下降
			{
				ADC8552_Data(&DAC_Tx);
			}
			else	if((TIM_FLAG>1100)&&(TIM_FLAG<6100))
			{
				DAC_Tx=0;
				ADC8552_Data(&DAC_Tx);
			}
			else if((TIM_FLAG>=6100))
			{
				TIM_FLAG=0;
			}						
		}
		else if(Triange_Mode==3)//中度失神经
		{
			if(TIM_FLAG<=8000)	//包括上升和下降
			{
				ADC8552_Data(&DAC_Tx);
			}
			else	if((TIM_FLAG>8000)&&(TIM_FLAG<58000))
			{
				DAC_Tx=0;
				ADC8552_Data(&DAC_Tx);
			}
			else if((TIM_FLAG>=58000))
			{
				TIM_FLAG=0;
			}				
		}
		else if(Triange_Mode==4)//重度失神经	
		{
			if(TIM_FLAG<=21000)	//包括上升和下降
			{
				ADC8552_Data(&DAC_Tx);
			}
			else	if((TIM_FLAG>21000)&&(TIM_FLAG<121000))
			{
				DAC_Tx=0;
				ADC8552_Data(&DAC_Tx);
			}
			else if((TIM_FLAG>=121000))
			{
				TIM_FLAG=0;
			}						
		}
		else if(Triange_Mode==5)//极重度失神经
		{
			if(TIM_FLAG<=60000)	//包括上升和下降
			{
				ADC8552_Data(&DAC_Tx);
			}
			else	if((TIM_FLAG>60000)&&(TIM_FLAG<160000))
			{
				DAC_Tx=0;
				ADC8552_Data(&DAC_Tx);
			}
			else if((TIM_FLAG>=160000))
			{
				TIM_FLAG=0;
			}							
		}
}
//进行一些说明
//目前这种编写方法相当于把幅值和波形以及固定了,如果做成产品应该怎么修改编程思想呢?
//1.关于幅值的说明
//关于幅值,就是对应治疗模式下的强度改变,欧姆定律决定了在R不变的情况下V和I的关系。
//可以增加一个二级处理,把中断出来的DAC_Tx进行二次加工,对应着不同的强度,处理好后在
//通过DAC去做传递,如果涉及到小数,可以全部改成double,最后做个强制类型转换,这样会让
//波形更加丝滑。
//2.关于波形,其他设备的波形都是固定的,如果设备想要增加不同参数模式,那就按着之前的
//方法去增加就可以了。

//定时器2,每10us进入一次	
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	//满偏值暂时设定为150*100=15000/65536*5≈1.10-1.15V之间
	//K1做成开始停止	K2做成功能切换
	TIM_FLAG++;
	//神经失用模式	1ms宽  1ms上升 0ms下降 20ms暂停
	if((Triange_Mode==1)&&(TIM_FLAG<=100))
	{
		DAC_Tx+=150;//上升
	}
	else if((Triange_Mode==2)&&(TIM_FLAG<=1100))//轻度失神经	10ms宽	10ms上升1ms下降50ms暂停
	{
		if(TIM_FLAG<=1000)DAC_Tx+=15;//1000*15	上升
		else if((TIM_FLAG>1000)&&(TIM_FLAG<=1100))DAC_Tx-=150;//下降
	}
	else if((Triange_Mode==3)&&(TIM_FLAG<=8000))//中度失神经
	{
		//50ms宽50ms上升30ms下降500ms暂停
		if(TIM_FLAG<=5000)DAC_Tx+=3;//5000*3	上升
		else if((TIM_FLAG>5000)&&(TIM_FLAG<=8000))DAC_Tx-=5;//下降  
	}
	else if((Triange_Mode==4)&&(TIM_FLAG<=21000))//重度失神经
	{
		//50ms宽50ms上升30ms下降500ms暂停 		
		if(TIM_FLAG<=15000)DAC_Tx+=1;//1000*15	上升
		else if((TIM_FLAG>15000)&&(TIM_FLAG<=21000)&&(TIM_FLAG%2==0))DAC_Tx-=5;//下降 
	}
	else if((Triange_Mode==5)&&(TIM_FLAG<=60000))//重度失神经
	{
		//50ms宽50ms上升30ms下降500ms暂停 		
		if((TIM_FLAG<=40000)&&(TIM_FLAG%8==0))DAC_Tx+=3;//1000*15	上升
		else if((TIM_FLAG>40000)&&(TIM_FLAG<=60000)&&(TIM_FLAG%4==0))DAC_Tx-=3;//下降 
	}
}
//按键外部中断,实现模式的切换
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	//模式切换
	Triange_Mode+=1;
	if(Triange_Mode==6)Triange_Mode=0;
	//每次按键切换定时器累加值以及电压幅值都进行清零处理
	TIM_FLAG=0;
	DAC_Tx=0;
	HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */


五、目标实现

观察信号幅值以及宽度大小,因为是拿杜邦线连的会发现干扰噪声很多,正常连接线噪声会少很多,如果感觉干扰过大可以加些滤波。

1.神经失用

在这里插入图片描述

2.轻度失神经

在这里插入图片描述

3.中度失神经

在这里插入图片描述

4.重点失神经

在这里插入图片描述

5.极度失神经

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2257582.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虚幻引擎生存建造系统

先做一个建造预览模式&#xff0c;按下按键B后进入建造预览模式 首先创建自定义事件Preview Loop 用射线追踪摆放物体预览位置&#xff0c;并做一个预览材质 增强输入设置按键 每帧判断是否进入建造模式 预览模式制作成功&#xff01; 接着做点击左键放置物品&#xff0…

IP研究 | 大数据洞察黄油小熊的爆火之路

一只来自泰国的小熊在国内红成了顶流。 今年&#xff0c;黄油小熊以烘焙店“打工人”的超萌形象迅速走红&#xff0c;2个月内火遍中国的社交媒体&#xff0c;泰国门店挤满飘洋过海求合影的中国粉丝&#xff0c;根据数说故事全网大数据洞察&#xff0c;黄油小熊2024年度的线上声…

深度学习案例:DenseNet + SE-Net

本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 一 回顾DenseNet算法 DenseNet&#xff08;Densely Connected Convolutional Networks&#xff09;是一种深度卷积神经网络架构&#xff0c;提出的核心思想是通过在每一层与前面所有层进行直接连接…

【java学习笔记】Set接口实现类-LinkedHashSet

一、LinkedHashSet的全面说明 &#xff08;就是把数组不同位置的链表当成一个节点然后相连&#xff09;

【大模型系列篇】LLaMA-Factory大模型微调实践 - 从零开始

前一次我们使用了NVIDIA TensorRT-LLM 大模型推理框架对智谱chatglm3-6b模型格式进行了转换和量化压缩&#xff0c;并成功部署了推理服务&#xff0c;有兴趣的同学可以翻阅《NVIDIA TensorRT-LLM 大模型推理框架实践》&#xff0c;今天我们来实践如何通过LLaMA-Factory对大模型…

【C++】LeetCode:LCR 078. 合并 K 个升序链表

题干&#xff1a; 给定一个链表数组&#xff0c;每个链表都已经按升序排列。 请将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 解法&#xff1a;优先队列 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *ne…

数据结构和算法-04二叉树-04

广度优先的实现力扣中常见的二叉树相关问题及基本解决方案 tips&#xff1a; 在解决问题时&#xff0c;先确保问题能解决&#xff0c;再去考虑效率&#xff0c;这是解题的关键&#xff0c;切不可为追求效率而变成了技巧性解答。 广度优先 广度优先(层序遍历)遍历的方式是按层次…

DMA代码部分

第一个程序的接线图 OLED ShowHexNum(2,1,(uint32_t)&ADC1->DR,8); 这样可以看AD的DR寄存器的的地址(固定的)了 可以跑一下然后和手册对比 先查ADC1的地址 再在外设的总表里面, 查一下DR相对于上面地址的偏移量 所以其地址为4001 244C 研究一下外设寄存器的地址是怎么…

spdlog高性能日志系统

spdlog高性能日志系统 spdlog 是一个快速、简单、功能丰富的 C 日志库&#xff0c;专为现代 C 开发设计。它支持多种日志后端&#xff08;如控制台、文件、syslog 等&#xff09;&#xff0c;并提供灵活的格式化和线程安全的日志输出。 1. 特点 极高的性能&#xff1a;大量的编…

FPGA在线升级 -- Multiboot

简介 本章节主要描述关于如何从Golden Image转换到Multiboot Image程序。 升级方案 Golden Image转换到Multiboot Image的方法主要又两种 1、使用ICAPE2 原语&#xff1b; 2、在XDC文件中加入升级约束命令&#xff1b; 以上两种方案都可以实现在线升级&#xff0c;第一种升级…

守护进程化

目录 一、进程组 二、会话 &#xff08;1&#xff09;什么是会话 &#xff08;2&#xff09;如何创建一个会话 三、守护进程 一、进程组 之前我们学习过进程&#xff0c;其实每一个进程除了有一个进程 ID(PID)之外 还属于一个进程组。进程组是一个或者多个进程的集合&…

QML插件扩展

https://note.youdao.com/ynoteshare/index.html?id294f86c78fb006f1b1b78cc430a20d74&typenote&_time1706510764806

RabbitMQ七种工作模式之 RPC通信模式, 发布确认模式

文章目录 六. RPC(RPC通信模式)客户端服务端 七. Publisher Confirms(发布确认模式)1. Publishing Messages Individually(单独确认)2. Publishing Messages in Batches(批量确认)3. Handling Publisher Confirms Asynchronously(异步确认) 六. RPC(RPC通信模式) 客⼾端发送消息…

ArcGIS字符串补零与去零

我们有时候需要 对属性表中字符串的补零与去零操作 我们下面直接视频教学 下面看视频教学 ArcGIS字符串去零与补零 推荐学习 ArcGIS全系列实战视频教程——9个单一课程组合 ArcGIS10.X入门实战视频教程&#xff08;GIS思维&#xff09; ArcGIS之模型构建器&#xff08;Mod…

前端面试如何出彩

1、原型链和作用域链说不太清&#xff0c;主要表现在寄生组合继承和extends继承的区别和new做了什么。2、推荐我的两篇文章&#xff1a;若川&#xff1a;面试官问&#xff1a;能否模拟实现JS的new操作符、若川&#xff1a;面试官问&#xff1a;JS的继承 3、数组构造函数上有哪些…

大模型应用编排工具Dify之构建专属FQA应用

1.前言 ​ 通过 dify可以基于开源大模型的能力&#xff0c;并结合业务知识库、工具API和自定义代码等构建特定场景、行业的专属大模型应用。本文通过 dify工作室的聊天助手-工作流编排构建了一个基于历史工作日志回答问题的助手&#xff0c;相比原始的大模型答复&#xff0c;通…

前端node环境安装:nvm安装详细教程(安装nvm、node、npm、cnpm、yarn及环境变量配置)

需求&#xff1a;在做前端开发的时候&#xff0c;有的时候 这个项目需要 node 14 那个项目需要 node 16&#xff0c;我们也不能卸载 安装 。这岂不是很麻烦。这个时候 就需要 一个工具 来管理我们的 node 版本和 npm 版本。 下面就分享一个 nvm 工具 用来管理 node 版本。 这个…

c基础加堆练习题

1】思维导图&#xff1a; 2】在堆区空间连续申请5个int类型大小空间&#xff0c;用来存放从终端输入的5个学生成绩&#xff0c;然后显示5个学生成绩&#xff0c;再将学生成绩升序排序&#xff0c;排序后&#xff0c;再次显示学生成绩。显示和排序分别用函数完成 要求&#xff…

嵌入式Linux 设备树 GPIO详解 示例分析 三星 NXP RK

GPIO设备树用于在Linux内核中定义与GPIO相关的硬件资源&#xff0c;它使操作系统可以识别、配置和使用GPIO引脚。设备树中通常会指定GPIO控制器的基地址、GPIO引脚的中断配置、时钟和其他相关信息。 目录 RK相关案例代码 NXP相关案例代码 三星相关案例代码 在设备树中&…

【日记】不想随礼欸(926 字)

正文 今天忙了一天。感觉从早上就开始在救火。客户经理迎接检查&#xff0c;要补资料&#xff0c;找我们问这样要那样&#xff0c;我自己的事情几乎完全开展不了。虽说也没什么大事就是了。 晚上行长还让我重装系统…… 难绷。看来这个爹味新行长懂得还挺多。 中午趁着不多的休…