小言_互联网的博客

涂鸦智能颈部按摩仪设计——功能模式实现(嵌入式)

504人阅读  评论(0)

一、前言

按摩仪主要有物理按摩和电脉冲两种,本项目为电脉冲类型,其原理是通过电极感应金属片,用脉冲技术对颈椎进行刺激,从而缓解颈椎酸痛。
市场上按摩仪的常见功能主要有敲打、锤击、揉捏、针灸、推拿、刮痧、恒温热敷等,本项目中实现了舒缓、活力、锤击拍打、刮痧、智能五个模式。

1、原理图

各种模式的实现是通过P9和P24两个IO口控制三极管的通断从而产生电脉冲来实现。

2、波形图

P9和P24分别产生正占空比为26.5%,周期为1ms的PWM波,但不能同时为高电平,否则会烧毁三级管(需特别注意)。
一次产生四束PWM波后等待30ms再次产生四束波,循环往复即可实现舒缓模式的功能效果。

图中一个脉冲中有四束PWM波,其波形如上图所示。脉冲与脉冲之间的时间为30ms。

3、各模式实现原理

舒缓、活力、锤击拍打、刮痧、智能五个模式是通过脉冲之间的时间间隔来实现的,如下表:

模式 脉冲时间间隔
舒缓模式 30ms
活力模式 20ms
锤击拍打模式 40ms
刮痧模式 50ms
智能模式 随机产生20 30 40 50ms
4、功能代码

相关引脚初始化

void pattern_pin_init(void)
{
   
    gpio_set_func(PATTERN_PIN_A, AS_PWM1_N);
    gpio_set_func(PATTERN_PIN_B, AS_PWM5);
    gpio_set_func(HEAT_PIN, AS_GPIO);

    gpio_set_output_en(PATTERN_PIN_A, 1);
    gpio_set_output_en(PATTERN_PIN_B, 1);
    gpio_set_output_en(HEAT_PIN, 1);

    gpio_write(PATTERN_PIN_A, 0);
    gpio_write(PATTERN_PIN_B, 0);
//    gpio_write(HEAT_PIN, 1);

	//PWM0 1ms cycle  26.5% duty 	1000Hz  
	pwm_set_mode(PWM1_ID, PWM_NORMAL_MODE);
	pwm_set_clk(CLOCK_SYS_CLOCK_HZ, CLOCK_SYS_CLOCK_HZ);
	pwm_set_phase(PWM1_ID, 0);   //no phase at pwm beginning
	pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
	pwm_polo_enable(PWM1_ID, 1);	//to enable the pwm polarity
	pwm_start(PWM1_ID);

	//PWM5 1ms cycle  26.5% duty	1000Hz  
	pwm_set_mode(PWM5_ID, PWM_NORMAL_MODE);
	pwm_set_clk(CLOCK_SYS_CLOCK_HZ, CLOCK_SYS_CLOCK_HZ);
	pwm_set_phase(PWM5_ID, 0);   //no phase at pwm beginning
	pwm_set_cycle_and_duty(PWM5_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );

}

由于GPIO_PC1(PATTERN_PIN_A)与档位调节GPIO_PC2(BOOST_PIN)都用到了PWM功能且GPIO_PC1(PATTERN_PIN_A)引脚仅支持PWM_0通道,所以GPIO_PC2(BOOST_PIN)使用PWM_0通道,GPIO_PC1(PATTERN_PIN_A)使用AS_PWM1_N通道,这里我们只需要pwm_polo_enable(PWM1_ID, 1)将PWM极性改变一下就可以了。

控制PWM个数以及脉冲时间间隔都是通过延时来实现的难免会有误差,大家有更好的实现方式也可以提出来一起交流。由于SDK没有涉及到RTOS所以整个程序是跑在裸机上的,因此该函数执行时需放在while(1)大循环里面。

void switching_pattern(unsigned char pat)
{
   
	if (pat > 4) {
   
		TUYA_APP_LOG_ERROR("*********No such model!!!**********");
	}

	switch (pat) {
   
	case relieve:
		pwm_start(PWM5_ID);
		sleep_us(450);		// 延时480us,防止同时置高烧毁三极管
		pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );
		sleep_us(5 * TIME_MS);
		pwm_stop(PWM5_ID);
		pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
		sleep_us(30 * TIME_MS);
		break;

	case vitality:
		pwm_start(PWM5_ID);
		sleep_us(450);
		pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );
		sleep_us(5 * TIME_MS);
		pwm_stop(PWM5_ID);
		pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
		sleep_us(20 * TIME_MS);
		break;

	case hammering:
		pwm_start(PWM5_ID);
		sleep_us(450);
		pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );
		sleep_us(5 * TIME_MS);
		pwm_stop(PWM5_ID);
		pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
		sleep_us(40 * TIME_MS);
		break;

	case scraping_therapy:
		pwm_start(PWM5_ID);
		sleep_us(450);
		pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );
		sleep_us(5 * TIME_MS);
		pwm_stop(PWM5_ID);
		pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
		sleep_us(50 * TIME_MS);
		break;

	case intelligent:
		pwm_start(PWM5_ID);
		sleep_us(450);
		pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (265 * CLOCK_SYS_CLOCK_1US) );
		sleep_us(5 * TIME_MS);
		pwm_stop(PWM5_ID);
		pwm_set_cycle_and_duty(PWM1_ID, (u16) (1000 * CLOCK_SYS_CLOCK_1US),  (u16) (0 * CLOCK_SYS_CLOCK_1US) );
		sleep_us(((rand() % 4 + 2) * 10) * TIME_MS);	// 随机延时20/30/40/50ms
		break;
	default:
		break;
	}
	return;
}

转载:https://blog.csdn.net/sandwich_iot/article/details/117225800
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场