台式振动按摩仪(超声、电机、电刺激、人机交互)

一.电刺激部分

   E_S连接MCU的IO口 控制HEF4011BT工作与否,当三级管导通时,C41处输出震荡波,震荡频率由C19和R3决定。

  C41隔直通交,滤除部分直流

  Q2和Q3形成一个直推图腾柱,增大推动能力,使得后端MOS管可正常处于深度打开状态

XL2596Vout处经R22形成一个负反馈  

E端接IO口输出PWM,占空比越大时,等效输入电压越大,再通过三极管,此时电路形成小电流控大流。增大占空比即可增大输出电压,同时后端输出电压变化,经变压器、电极后输出到人体

二.变压器电路简述

  电感线圈本身会有阻抗,这点不容忽视,原边阻值即限流电阻阻值+自身感抗,副边同理。

  当电极短路时,相当副边负载0欧姆,初级线圈自身电感感抗也会变为0,此时所有的能量经续流二极管经限流电阻消耗掉,并不会对人体造成伤害。

  三.超声接入信号预处理

  四.电机模块

   采用L9110S电机驱动芯片,M_IN1and M_IN2接IO口输出PWM,同样可以通过占空比控制转速,2路信号可控正反转。(5V小电机)

   外部可接两个机械限位开关,使得导药到极限位置时暂停。

 五.超声驱动模块

原理与电机驱动近似

六.迪文屏人机交互

    组态界面迪文官方有专门的教程,不做过多描述。

此处连接要注意串接电阻大小

七.代码部分

   MCU使用的是STM32F103C8T6

   GPIO、定时器、串口和硬件IIC的基础配置此处不做讲解,考虑到迪文屏的数据量可能比较大,串口信息传递部分我是使用DMA,

void MX_DMA_Init(void)
{

  //开启DMA时钟
  __HAL_RCC_DMA1_CLK_ENABLE();
  
  //开启中断,使能DMA
  HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
  HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);

}


void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart,uint16_t Size)
 {
	 if (huart==&huart3)
	 {  
		  //HAL_UART_Transmit_DMA(&huart3,ReceiveData,Size);
		 
		  HAL_UARTEx_ReceiveToIdle_DMA(&huart3,ReceiveData,sizeof(ReceiveData));
		  __HAL_DMA_DISABLE_IT(&hdma_usart3_rx,DMA_IT_HT);
		  Instruct(); 
    } 
	}

void Instruct (void)//这个函数当时为了判断上位机发送数据,写的是一言难尽
{
	                             if(ReceiveData[0] ==0x5A)
																	{  
																		if(ReceiveData[1] ==0xA5)
																		{ 
																			if(ReceiveData[2] ==0x06)
																			{ 
																				if(ReceiveData[3] ==0x83)
																				{ 
																					if(ReceiveData[4] ==0x20)
																					 { 
																						if(ReceiveData[5] ==0x00)
																						 { 
																							 if(ReceiveData[6] ==0x01)
																								{ 
																									if(ReceiveData[7] ==0x00)
																									 { 
																											if(ReceiveData[8] ==0x01)
																											{ 
																												 GG =1;//电机回退                                                        	
                                                         BB=0;      
                                                         HAL_UART_Transmit_DMA(&huart3,MotorArray,8);
                                                 																												
																											}
																											else if(ReceiveData[8] ==0x00)
																											{
																												 GG =0;//电机回退停止	 																										 
																											}}}}}}}}}

输入捕获测频率并反馈到迪文屏显示

void capture(void)//输入捕获测频率
{
	switch(captyre_bit)
	{
		case 0:
		captyre_bit++;	  
		TIM_RESET_CAPTUREPOLARITY(&htim4,TIM_CHANNEL_1);//清空状态
		TIM_SET_CAPTUREPOLARITY(&htim4,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);//捕获高电平
		HAL_TIM_IC_Start_IT(&htim4,TIM_CHANNEL_1);
		break;
		
		
		case 3:
			high_time = captyre_buf[1] - captyre_buf[0];//高电平时间
		  printf("%d",captyre_buf[1]);
		  printf("%d",captyre_buf[0]);
		  printf("%d",high_time);
		  HAL_Delay(1000);
		  captyre_bit=0;
		break;
		
	}
}
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//输入捕获中断函数
{
	if(htim->Instance == TIM4)//判断是否定时器4产生
	{
		switch(captyre_bit)
		{
			case 1:
				   captyre_buf[0] = HAL_TIM_ReadCapturedValue(&htim4,TIM_CHANNEL_1);//读取捕获值
			     captyre_bit++;
			break;
			
			
			case 2:
				   captyre_buf[1] = HAL_TIM_ReadCapturedValue(&htim4,TIM_CHANNEL_1);//读取捕获值
			     HAL_TIM_IC_Stop_IT(&htim4,TIM_CHANNEL_1);
			     captyre_bit++;
			break;
			
		}	
	}
}

PWM档位调节

void ultrasound(void)//超声功率档位调节 频率1~20Hz  1.30%  2.60%   3.100%
{
	switch(c)
	{

		case 1:__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_1,30);
		       __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,0);
           break;
		
		case 2:__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_1,60);
		       __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,0);
           break;
		
		case 3:__HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_1,80);
		       __HAL_TIM_SetCompare(&htim3,TIM_CHANNEL_2,0);
	         break;

	}
	
}

main函数

int main(void)
{
  /* USER CODE BEGIN 1 */
  uint8_t  ZZTArray[]={ZTH,ZTL,ZL,ZW,ZAH,ZAL,ZTime,ZMinute,ZSecond};
  HAL_GPIO_WritePin(GPIOA,GPIO_PIN_0,GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_11,GPIO_PIN_SET);//电刺激初始停止
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET);//芯片状态灯
  /* 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_DMA_Init();
  MX_TIM1_Init();
  MX_USART3_UART_Init();
  MX_TIM2_Init();
  MX_CRC_Init();
  MX_I2C1_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  MX_USART2_UART_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
	 
   HAL_UARTEx_ReceiveToIdle_DMA(&huart3,ReceiveData,sizeof(ReceiveData));
   __HAL_DMA_DISABLE_IT(&hdma_usart3_rx,DMA_IT_HT);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
		
  while (1)
  { 
		
		
										capture();
										
										if(AA==1 && DD==1)//电极
										{
											ElectrodeStart();
											Electrode();
										}
										else 
										 {
										 ElectrodeStop();
										 }
										 
							 
									if( DD==1)//电机
									{
														if(BB==1)//电机回退后重新开始若卡住,delay500ms
														{
															MotorStart();
															Motor();
														}
														else if(GG==1)
														{
															MotorStart();
															Motor_rollback();
															
														}
														else if( GG==0 )
														{

															MotorStop();
														}
									}
									else if(DD==0)
									{
										          MotorStop();
										
									}
							 							
							if(CC==1 && DD==1)//超声 默认连续模式
							{
								
								    ultrasoundStart();
										ultrasound();			
								
							}
							else 
							 {
							 ultrasoundStop();
							 }	 	 
		printf("%d",a);
		printf("%d",b);
		printf("%d",c);
		printf("%d",AA);
		printf("%d",BB);
		printf("%d",CC);
		printf("%d",DD);
					 						 
    //串口发送计时数据	
		  HAL_Delay(1000);			 
      if(DD==1)
			{						
					WordTime();
					ZZTArray[6]=ZTime;
					ZZTArray[7]=ZMinute;
					ZZTArray[8]=ZSecond;
					HAL_UART_Transmit_IT(&huart3,ZZTArray,9);
			}
      else
			{ 
				  ZTime=0;
				  ZMinute=0;
				  ZSecond=0;
					ZZTArray[6]=0;
					ZZTArray[7]=0;
					ZZTArray[8]=0;
				  HAL_UART_Transmit_IT(&huart3,ZZTArray,9);
			}
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

       这是本人23年毕业后入职做的第一个商业性项目,代码写的和那个啥一样,硬件部分也并没有考虑成本,介于公司的产权,本人并不能将实际产品发出供大家参考。以它来作为我在CSDN的初始篇,后续也会发一些其他的项目以及一些踩过的坑和小技巧,欢迎大家提出宝贵意见,评论区留言我也会答复。在此再次感谢带我入门并启蒙嵌入式的杨博士。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值