驱动---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.极度失神经

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch入门之HTTP基础操作

RESTful REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。Web 应用程序最重要的 REST 原则是&#xff0c;客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在…

计算机启动过程 | Linux 启动流程

注&#xff1a;本文为“计算机启动、 Linux 启动”相关文章合辑。 替换引文部分不清晰的图。 探索计算机的启动过程 Aleksandr Goncharov 2023/04/21 很多人对计算机的启动方式很感兴趣。只要设备开启&#xff0c;这就是魔法开始和持续的地方。在本文中&#xff0c;我们将概…

【数据分享】1901-2023年我国省市县三级逐年最低气温数据(Shp/Excel格式)

之前我们分享过1901-2023年1km分辨率逐月最低气温栅格数据和Excel和Shp格式的省市县三级逐月最低气温数据&#xff0c;原始的逐月最低气温栅格数据来源于彭守璋学者在国家青藏高原科学数据中心平台上分享的数据&#xff01;基于逐月栅格数据我们采用求年平均值的方法得到逐年最…

Hash、HASHTABLE底层原理【Redis对象篇】

&#x1f3c6; 作者简介&#xff1a;席万里 ⚡ 个人网站&#xff1a;https://dahua.bloggo.chat/ ✍️ 一名后端开发小趴菜&#xff0c;同时略懂Vue与React前端技术&#xff0c;也了解一点微信小程序开发。 &#x1f37b; 对计算机充满兴趣&#xff0c;愿意并且希望学习更多的技…

YOLOv11改进,YOLOv11添加GSConv卷积+Slim-neck,助力小目标检测,二次创新C3k2结构

实时目标检测在工业和研究领域中具有重要意义。在边缘设备上,巨大的模型难以满足实时检测的要求,而由大量深度可分离卷积(depth-wise separable convolution)构建的轻量级模型又无法达到足够的精度。作者引入了一种新的轻量级卷积技术——GSConv,以减轻模型重量同时保持精…

利用Java爬虫MinC根据ID获取商品详情的完整指南

在当今数字化时代&#xff0c;获取商品详情数据对于市场分析、价格监控和竞争对手分析至关重要。Java作为一种强大且广泛使用的编程语言&#xff0c;非常适合开发复杂的爬虫系统。本文将详细介绍如何利用Java编写爬虫程序来根据商品ID获取商品详情&#xff0c;并提供完整的代码…

IP地址中的网络号:定义、作用与重要性

在计算机网络中&#xff0c;IP地址是每台设备的唯一标识。它由网络号和主机号两部分组成&#xff0c;其中网络号用于标识一个特定的网络&#xff0c;而主机号则用于区分该网络内的不同设备。网络号的正确分配和管理&#xff0c;是IP网络互联互通的基础。本文将带您走进网络号的…

java_连接数据库的方法_后端处理_前端调用_打通整体思路

参考&#xff1a;14 尚上优选项目-平台管理端-权限管理模块-开发角色管理接口&#xff08;上&#xff09;_哔哩哔哩_bilibili 第一步. 定义数据 在数据库中定义好数据&#xff08;如role表格&#xff09;&#xff0c;在java后端定义好对应的实体类&#xff08;Role类&#xf…

PHP富文本编辑器eWebEditor实战指南

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;eWebEditor是一个基于PHP的开源在线文本编辑器&#xff0c;提供类似Word的用户界面&#xff0c;简化了网页文本的创建和编辑过程。它广泛适用于博客、论坛、CMS等平台的内容管理&#xff0c;具备富文本编辑、表格…

docker nginx 部署vue 实例

1.安装docker https://blog.csdn.net/apgk1/article/details/144354588 2. 安装nginx docker 安装 nginx-CSDN博客 3. 复制 nginx-test 实例的一些文件到宿主机中&#xff0c;目前已 /home/jznh/路径演示 3.1 在/home/jznh/ 创建 conf html logs 三个文件夹&#xff0c;…

一个直接看央视频道的软件,可直接安装到TV

优点 打开无广告&#xff0c;直接自动默认打开央视频道加载速度快&#xff0c;切换频道响应快&#xff0c;不用转圈圈画质清晰&#xff0c;画质清晰无雪花频道多&#xff0c;差不多上百个频道 软件截图 下载链接 跳转原文下载

JavaEE之多线程的风险以及如何避免

上文我们了解了单线程以及线程的一些基本常见方法&#xff0c;但是多线程在一些方面会存在安全问题&#xff0c;此文我们来为多线程的安全 保驾护航&#xff01;&#xff01; 详情请见下文 1. 多线程带来的风险——线程安全 1.1 观察线程不安全 /*** 使用两个线程&#xff0c…

【OpenCV】直方图

理论 可以将直方图视为图形或曲线图&#xff0c;从而使您对图像的强度分布有一个整体的了解。它是在X轴上具有像素值(不总是从0到255的范围)&#xff0c;在Y轴上具有图像中相应像素数的图。 这只是理解图像的另一种方式。通过查看图像的直方图&#xff0c;您可以直观地了解该…

MoeCTF2024-Web题解

目录 1、弗拉格之地的入口 2、垫刀之路01: MoeCTF&#xff1f;启动&#xff01; 3、ez_http 4、ProveYourLove 5、弗拉格之地的挑战 6、ImageCloud前置 7、垫刀之路02: 普通的文件上传 8、垫刀之路03: 这是一个图床 9、垫刀之路05: 登陆网站 10、垫刀之路06: pop bas…

python学opencv|读取图像(六)读取图像像素RGB值

【1】引言 前序已经掌握了如何获取灰度图像的像素&#xff0c;文章链接为&#xff1a; python学opencv|读取图像&#xff08;五&#xff09;读取灰度图像像素-CSDN博客 实际上像素就像一个坐标轴&#xff0c;约束了图像的大小。 但实际上我们在学习过程中&#xff0c;对于同…

ThingsBoard规则链节点:RabbitMQ 节点详解

ThingsBoard 是一个开源的物联网平台&#xff0c;允许开发者快速构建IoT产品。它提供了设备连接、数据收集、处理和可视化等功能。为了实现高效的数据处理和消息传递&#xff0c;ThingsBoard 集成了多种消息队列服务&#xff0c;其中就包括了RabbitMQ。 RabbitMQ 是一个广泛使用…

如何创建基于udp的客户端和服务端

1.先创建好udpServer.hpp、udpServer.cc、udpClient.hpp、udpClient.cc的框架。 #pragma once #include <string> #include <iostream> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <cerrno> #include…

TCP 2

文章目录 Tcp状态三次握手四次挥手理解TIME WAIT状态 如上就是TCP连接管理部分 流量控制滑动窗口快重传 延迟应答原理 捎带应答总结TCP拥塞控制拥塞控制的策略 -- 每台识别主机拥塞的机器都要做 面向字节流和粘包问题tcp连接异常进程终止机器重启机器掉电/网线断开 Tcp状态 建…

ChatGPT Pro是什么

ChatGPT Pro 和 ChatGPT Plus 的区别主要体现在功能范围、适用场景和目标用户上。 ChatGPT Plus 功能 • 价格&#xff1a;20美元/月。 • 目标用户&#xff1a;针对个人用户设计。 • 主要特点&#xff1a; • 在高峰期响应速度更快。 • 使用高级模型&#xff08;如 GPT-4…

【开源免费】基于Vue和SpringBoot的桂林旅游景点导游平台(附论文)

博主说明&#xff1a;本文项目编号 T 079 &#xff0c;文末自助获取源码 \color{red}{T079&#xff0c;文末自助获取源码} T079&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…