基于STM32的智能家具系统(语音识别控制、步进电机、舵机)

智能家具系统分为两个不同版本系列:

①系列一:手机app远程控制、远程检测温湿度显示在app,(云平台)!!!!                   https://blog.csdn.net/m0_59113542/article/details/123737710

②系列二:语音识别控制-------本文章

硬件采购链接:

步进电机及相关驱动 https://m.tb.cn/h.fLxkuAl?tk=MrPE2ToToDL 第三个套餐
舵机 https://m.tb.cn/h.fnz3dn4?tk=VWlc2f8Y0NY 两个都行
风扇 https://m.tb.cn/h.fNySVjC?tk=56Yc2f800lH 第一个套餐
stm32最小系统板 https://m.tb.cn/h.fNy7pcW?tk=XKLr2f8YwWD 第三个套餐
语音识别SU-03T https://m.tb.cn/h.foxjit4?tk=3iQ32ToKaGj 第三个套餐

一、项目介绍

功能:离线语音识别模块SU-03T识别到我们不同的语音命令,改变不同引脚电平的状态,stm32读取引脚电平状态,完成相关的外设驱动。

本系统采用的SU-03T 是一款低成本、低功耗、小体积的离线语音识别模组,能快速应用于智能家 居。

目前市面上多用LD3320语音识别模块,这里先说一下我们为什么SU-03T,而不采用LD3320。

①:LD3320淘宝价格120左右,                SU-03T淘宝价格20左右

②:LD3320是c语音编程,                        SU-03T刷词条,只需简单配置

(这个各有各的好处,c语言编程,麻烦但是比较灵活,,,刷词条,简单,但是有一定的局限性)

③:识别率:!!!!!!!!!!!最重要的一点!!!!!!!!!!

语音识别,玩的不就是识别率吗

虽然现在用LD3320的比较多,但是它的语音识别率。emmm........还真的不敢恭维,我第一次用的时候,怎么喊都不管用,还以为是硬件坏了,捣鼓了一下午才发现,你得慢慢的说,语速得很慢。比如:打~~开~~灯~~光~~,这这这这......

而SU-03T,虽然便宜,但是很神奇,其识别率真的YYDS。

这个时候肯定有人不信了,说:“啊,,这人是不是商家的托啊,怎么可能便宜的还好用”!!本人还真不是托,只是一个踩过多次坑的孩子。我劝大家去淘宝买家秀看看,别看卖家秀,看买家秀!!!!!!!!!!!!LD3320很多买家秀都喊两次才能识别,而SU-03T离很远却能识别!!!!!神奇!!!!!

二、项目原理

智能家具吗,我们不可能真的去改造家里的家具(有钱的当我没说,楼主是很穷),所以我们采用模拟的方式,用单步电机加上一条履带模拟窗帘,舵机模拟开关门,LED灯模拟家里的灯,风扇.....大家还可以发挥想象,加一些其他的外设。

接下来就是各个外设的驱动:                                                                                                            首先是语音识别模块:SU-03T,可以初始化引脚电平,假如说为低吧,当识别到语音的时候可拉高电平,将stm32的某些引脚设置为下拉输入模式,与SU-03T的引脚相连,这不就完成了吗,,so  easy。

舵机是用PWM控制角度的,PWM不同的占空比对应不同的角度。

步进电机在前面的文章有详细的讲解及代码  链接:步进电机的原理及驱动

LED、与风扇就不多说了,无非就是将GPIO的输出高 输出低的问题!

三、程序实现

Servo_motor.c  舵机驱动

#include "Servo_motor.h"
#include "delay.h"

//高级定时器1pwm输出初始化
//arr:自动重装值(周期)  psc:时钟预分频数
void tim1_pwmInit(uint16_t arr, uint16_t psc)
{
  GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // 使能定时器1的外设时钟
 	RCC_APB2PeriphClockCmd(TIM1_CH1_GPIO_CLK, ENABLE);  //使能GPIO外设时钟使能                               	

   //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形
	GPIO_InitStructure.GPIO_Pin = TIM1_CH1_PIN; //TIM_CH1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(TIM1_CH1_PORT, &GPIO_InitStructure);
	
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 80K
	TIM_TimeBaseStructure.TIM_Prescaler = psc; //设置用来作为TIMx时钟频率除数的预分频值  不分频(预分频系数,如系统时钟为72Mhz,psc为7199,则分频后为72M/(7199+1)=10k  ~~~0.1ms,,也就是说一个周期0.1ms,,,,在×arr就得到定时时间了)
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	//TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值(占空比)
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx

  TIM_CtrlPWMOutputs(TIM1,ENABLE);	//MOE 主输出使能	
	
	TIM_Cmd(TIM1, ENABLE);  //使能TIM1
}



void servo_init(void)
{
  tim1_pwmInit(SERVO_TIM_ARR,SERVO_TIM_PSC);
  TIM_SetCompare1(TIM1,150);  //使舵机恢复到中间位置
}



//0.5ms--0°  2.5ms--180°
void servo_angle(uint16_t angle)
{
  uint16_t pulse;
  
  //针对舵机可转角度限辐
  if(angle <= 5)
    angle = 5;
  if(angle >= 175)
    angle = 175;
  //将角度值转换为脉冲值  
  pulse = (uint16_t)(50 + angle * 100/90.0);  //此转换公式需根据pwm的arr及psc配置来做相应变化
  TIM_SetCompare1(TIM1, pulse);
  
}



void servo_debug(void)
{
  uint8_t i;
  for(i = 0; i < 10; ++i)
  {
    delay_ms(500);
    servo_angle(80);  //中间位置
    delay_ms(500);
    servo_angle(175);

  }
}

Servo_motor.h

#ifndef __Servo_motor_H
#define __Servo_motor_H

#include "stm32f10x.h"


// 72M / (719 + 1) = 0.1M 故记一个数的时间为10us  定时周期:(1999 + 1) * 10us = 20ms
#define SERVO_TIM_ARR  1999
#define SERVO_TIM_PSC  719


#define TIM1_CH1_GPIO_CLK    RCC_APB2Periph_GPIOA
#define TIM1_CH1_PORT        GPIOA
#define TIM1_CH1_PIN         GPIO_Pin_8




void servo_init(void);
void servo_angle(uint16_t angle);
void servo_debug(void);
void tim1_pwmInit(uint16_t arr, uint16_t psc);

#endif  //__TIMER_H

ASR.c语音识别

#include "ASR.h"

//初始化PB5和PE5为输出口.并使能这两个口的时钟		    
//LED IO初始化
void ASR_Init(void)
{
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(ASR_LED_CLK, ENABLE);	 //使能PG端口时钟
	
 GPIO_InitStructure.GPIO_Pin = ASR_LED_PIN |ASR_FS_PIN |ASR_stepper_motor_PIN |ASR_Servo_motor_PIN;				            //PA.1、PA.2 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; 		     //输入下拉
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(ASR_LED_PORT, &GPIO_InitStructure);					       

	GPIO_ResetBits(ASR_LED_PORT, ASR_LED_PIN);
	GPIO_ResetBits(ASR_FS_PORT, ASR_FS_PIN);
	GPIO_ResetBits(ASR_stepper_motor_PORT, ASR_stepper_motor_PIN);
	GPIO_ResetBits(ASR_Servo_motor_PORT, ASR_Servo_motor_PIN);	
}
 

ASR.h

#ifndef __ASR_H
#define __ASR_H	 
#include "sys.h"


//led
#define ASR_LED_PIN                   					 GPIO_Pin_1
#define ASR_LED_PORT                   					 GPIOA
#define ASR_LED_CLK                   					 RCC_APB2Periph_GPIOA

//风扇
#define ASR_FS_PIN                    					 GPIO_Pin_2
#define ASR_FS_PORT                   					 GPIOA
#define ASR_FS_CLK                    					 RCC_APB2Periph_GPIOA

//步进电机(窗帘)
#define ASR_stepper_motor_PIN                    GPIO_Pin_3
#define ASR_stepper_motor_PORT                   GPIOA
#define ASR_stepper_motor_CLK                    RCC_APB2Periph_GPIOA

//开关门
#define ASR_Servo_motor_PIN                    	 GPIO_Pin_4
#define ASR_Servo_motor_PORT                   	 GPIOA
#define ASR_Servo_motor_CLK                    	 RCC_APB2Periph_GPIO4


#define LED_read  PAin(1)// PA1
#define FS_read   PAin(2)// PA2
#define BJ_read   PAin(3)// PB3
#define KM_read   PAin(4)// PB4

void ASR_Init(void);//初始化

		 				    
#endif

main.c

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "step_motor.h"
#include "Servo_motor.h"
#include "ASR.h"

 int main(void)
 {	
	static u8 BJ_flag;
	delay_init();	    															  //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 	//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart_init(9600);	 																//串口初始化为115200
	ASR_Init();
 	LED_Init();			    														  //LED端口初始化
	KEY_Init();         														  //初始化与按键连接的硬件接口
	servo_init();
	Step_Motor_GPIO_Init();
	 
	servo_angle(80);      														 //私服电机初始角度(关门状态)
	//STEP_MOTOR_OFF();
 	while(1)
	{
		//判断语音开关灯
		if(LED_read == 1) 
		{
			LED0=0;             //开灯
			LED1=1;
		}
		else
		{
			LED0=1;            //关灯
			LED1=0;
		}
		
		//语音判断开关风扇
		if(FS_read == 1)
		{
			FS=1;
		}
		else
		{
			FS=0;
		}	 
		
		//判断语音开关窗帘
		if((BJ_read == 1)&&(BJ_flag == 0))
		{
			motorNcircle(64,(bool)1);  //步进电机正传
			BJ_flag=1;
		}
		else if((BJ_read == 0)&&(BJ_flag == 1))
		{
			//STEP_MOTOR_OFF();
			motorNcircle(64,(bool)0);  //步进电机反传
			BJ_flag=0;
			
		}
		
		//判断语音开关门
		if(KM_read == 1) 
		{
			servo_angle(175);
			delay_ms(500);
		}
		else
		{
			servo_angle(80);
			delay_ms(500);
		}
  }
}

步进电机的程序就不在这里重复了,上面那个链接里有。

完整工程链接:https://download.csdn.net/download/m0_59113542/85036397

  欢迎大家指正交流,有空可以一起讨论代码啊。

制作不易,感谢大家支持,感谢!!!!!!

  --------------一个正在努力的人
 

猜你喜欢

转载自blog.csdn.net/m0_59113542/article/details/123742383