Bootstrap

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

最近开始进行新项目的研发,考虑用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.极度失神经

在这里插入图片描述

;