泰凌微Telink pwm的一个坑

发布时间:2024年01月03日

泰凌微芯片输出PWM期间不能进入suspend
在这里插入图片描述
我的灯是低亮 所以代码中是 rgb_pwm_io_t[index].duty = APP_PWM_MAX_VALUE - duty;
头文件

#ifndef APP_RGB_PWM_H_
#define APP_RGB_PWM_H_

#define PWM_ID_R				PWM3_ID // zxk 20230426
#define PWM_ID_G				PWM2_ID
#define PWM_ID_B				PWM1_ID

//PWW口定义
#define IO_LED_PWM_R			GPIO_PB7
#define IO_LED_PWM_G			GPIO_PB6
#define IO_LED_PWM_B			GPIO_PB5

#define PWM_CLOCK_HZ			(CLOCK_SYS_CLOCK_HZ/4)
//定义PWM的最大值
#define APP_PWM_MAX_VALUE		255

void app_pwm_init(void);

u8 is_rgb_led_busy(void);
void rgb_flash_led_task(void);

void set_dpi_rgb_led_evt(u8 dpi);
void set_low_bat_led_evt(void);

void test_app_pwm(void);
#endif

c文件

#include "AAA_public_config.h"

#define RED_LED_INDEX			0
#define GREEN_LED_INDEX			1
#define BLUE_LED_INDEX			2
#define MAX_RGB_LED_IND			2

#define RGB_PWM_LED_OFF			0
#define RGB_PWM_LED_ON			1

static void red_pwm_ctrl(u8 on_off);
static void green_pwm_ctrl(u8 on_off);
static void blue_pwm_ctrl(u8 on_off);

enum rgb_io_mode{
	rgb_pwm_mode,
	rgb_gpio_mode = AS_GPIO,
};

struct rgb_io_pwm_map_t {
	const char ind;
	enum rgb_io_mode mode;
	unsigned char duty;
	const pwm_id pwm_ind;
	const GPIO_PinTypeDef pin;
	const gpio_func_e fun;
};

static struct rgb_io_pwm_map_t rgb_pwm_io_t[3] = {
	{
		.ind = RED_LED_INDEX,
		.mode = rgb_gpio_mode,
		.duty = APP_PWM_MAX_VALUE,
		.pwm_ind = PWM_ID_R,
		.pin = IO_LED_PWM_R,
		.fun = PIN_PWM_R_FUNC,
	},
	{
		.ind = GREEN_LED_INDEX,
		.mode = rgb_gpio_mode,
		.duty = APP_PWM_MAX_VALUE,
		.pwm_ind = PWM_ID_G,
		.pin = IO_LED_PWM_G,
		.fun = PIN_PWM_G_FUNC,
	},
	{
		.ind = BLUE_LED_INDEX,
		.mode = rgb_gpio_mode,
		.duty = APP_PWM_MAX_VALUE,
		.pwm_ind = PWM_ID_B,
		.pin = IO_LED_PWM_B,
		.fun = PIN_PWM_B_FUNC,
	}
};
static MY_FLASH_LED_T s_rgbLed[3] = {
	{ .ctrl_led = red_pwm_ctrl, .duty = APP_PWM_MAX_VALUE,},
	{ .ctrl_led = green_pwm_ctrl, .duty = APP_PWM_MAX_VALUE,},
	{ .ctrl_led = blue_pwm_ctrl, .duty = APP_PWM_MAX_VALUE,},
};
// ==========================================================================================
static void set_rgb_io_mode(unsigned char ind, unsigned char io_mode)
{
	pwm_id pwm_ind = rgb_pwm_io_t[ind].pwm_ind;
	GPIO_PinTypeDef pin = rgb_pwm_io_t[ind].pin;
	gpio_func_e func = rgb_pwm_io_t[ind].fun;
	if(ind > BLUE_LED_INDEX){
		return;
	}
	switch(io_mode)
	{
		case rgb_gpio_mode:
			pwm_set_cmp(pwm_ind,APP_PWM_MAX_VALUE);
			pwm_stop(pwm_ind);

			gpio_set_func(pin,AS_GPIO);
			gpio_set_input_en(pin,0);
			gpio_set_output_en(pin,1);
			gpio_setup_up_down_resistor(pin,PM_PIN_UP_DOWN_FLOAT);

			rgb_pwm_io_t[ind].mode = rgb_gpio_mode;
			gpio_write(pin, RGB_LED_OFF_LEVEL);
			printf("set gpio [%d] pin:0x%02x, pwm_ind:%d.\n",ind,pin,pwm_ind);
			break;
		default:
			gpio_write(pin, RGB_LED_ON_LEVEL);
			gpio_set_func(pin, func);

			pwm_set_mode(pwm_ind, PWM_NORMAL_MODE);
			pwm_set_phase(pwm_ind, 0);   			//no phase at pwm beginning
			pwm_set_cycle_and_duty(pwm_ind, (u16)APP_PWM_MAX_VALUE,(u16)rgb_pwm_io_t[ind].duty);

			rgb_pwm_io_t[ind].mode = rgb_pwm_mode;
			pwm_start(pwm_ind);
			pwm_set_cmp(PWM_ID_G,rgb_pwm_io_t[ind].duty);
			printf("set pwm [%d] pin:0x%02x, duty:%d, pwm_ind:%d, fun:%d.\n",ind,pin,rgb_pwm_io_t[ind].duty,pwm_ind,func);
			break;
	}
}
static void red_pwm_ctrl(u8 on_off)
{
	if((RGB_PWM_LED_ON == on_off) && rgb_pwm_io_t[RED_LED_INDEX].mode == rgb_pwm_mode){
		pwm_set_cmp(PWM_ID_R,rgb_pwm_io_t[RED_LED_INDEX].duty);
		return;
	}
	if((RGB_PWM_LED_OFF == on_off) && (rgb_pwm_io_t[RED_LED_INDEX].mode == rgb_gpio_mode)){
		gpio_write(rgb_pwm_io_t[RED_LED_INDEX].pin, RGB_LED_OFF_LEVEL);
		return;
	}
	rgb_pwm_io_t[RED_LED_INDEX].duty = s_rgbLed[RED_LED_INDEX].duty;
	set_rgb_io_mode(RED_LED_INDEX, (on_off==RGB_PWM_LED_ON)?rgb_pwm_mode:rgb_gpio_mode);
}

static void green_pwm_ctrl(u8 on_off)
{
	if((RGB_PWM_LED_ON == on_off) && rgb_pwm_io_t[GREEN_LED_INDEX].mode == rgb_pwm_mode){
		pwm_set_cmp(PWM_ID_G,rgb_pwm_io_t[GREEN_LED_INDEX].duty);
		return;
	}
	if((RGB_PWM_LED_OFF == on_off) && (rgb_pwm_io_t[GREEN_LED_INDEX].mode == rgb_gpio_mode)){
		gpio_write(rgb_pwm_io_t[GREEN_LED_INDEX].pin, RGB_LED_OFF_LEVEL);
		return;
	}
	rgb_pwm_io_t[GREEN_LED_INDEX].duty = s_rgbLed[GREEN_LED_INDEX].duty;
	set_rgb_io_mode(GREEN_LED_INDEX, (on_off==RGB_PWM_LED_ON)?rgb_pwm_mode:rgb_gpio_mode);
}

static void blue_pwm_ctrl(u8 on_off)
{
	if((RGB_PWM_LED_ON == on_off) && rgb_pwm_io_t[BLUE_LED_INDEX].mode == rgb_pwm_mode){
		pwm_set_cmp(PWM_ID_B,rgb_pwm_io_t[BLUE_LED_INDEX].duty);
		return;
	}
	if((RGB_PWM_LED_OFF == on_off) && (rgb_pwm_io_t[BLUE_LED_INDEX].mode == rgb_gpio_mode)){
		gpio_write(rgb_pwm_io_t[BLUE_LED_INDEX].pin, RGB_LED_OFF_LEVEL);
		return;
	}
	rgb_pwm_io_t[BLUE_LED_INDEX].duty = s_rgbLed[BLUE_LED_INDEX].duty;
	set_rgb_io_mode(BLUE_LED_INDEX, (on_off==RGB_PWM_LED_ON)?rgb_pwm_mode:rgb_gpio_mode);
}

//初始化PWM用于LED的RGB驱动
void app_pwm_init(void)
{
	//设置PWM的时钟源
	pwm_set_clk(CLOCK_SYS_CLOCK_HZ,PWM_CLOCK_HZ);

	set_rgb_io_mode(RED_LED_INDEX, rgb_gpio_mode);
	set_rgb_io_mode(GREEN_LED_INDEX, rgb_gpio_mode);
	set_rgb_io_mode(BLUE_LED_INDEX, rgb_gpio_mode);
}
// ==========================================================================================


// 设置指定颜色灯用pwm模式闪灯
static void set_rgb_pwm_flash(u8 index, u16 cnt, u16 on_time, u16 off_time, u8 duty)
{
	if((s_rgbLed[index].ctrl_led == NULL) || (index > MAX_RGB_LED_IND))
		return;

	if((!on_time) || (!cnt) || (!duty)){
		cnt = 0;
		duty = 0;
		on_time = 0;
		printf("Close ind: ...... %d.\n",index);
	}
	rgb_pwm_io_t[index].duty 	= APP_PWM_MAX_VALUE - duty;

	s_rgbLed[index].duty 		= APP_PWM_MAX_VALUE - duty;
	s_rgbLed[index].cycle 		= cnt;
	s_rgbLed[index].on_time 	= on_time;
	s_rgbLed[index].off_time 	= off_time;
	s_rgbLed[index].start_tick 	= clock_time();

	s_rgbLed[index].ctrl_led(cnt?RGB_PWM_LED_ON:RGB_PWM_LED_OFF);
	printf("--> Set rgb_%d  cnt:%d, on:%d, off:%d.\n",index,s_rgbLed[index].cycle,s_rgbLed[index].on_time,s_rgbLed[index].off_time);
}
// RGB灯的闪灯任务
void  rgb_flash_led_task(void)
{
	u8 index = 0;

	do{
		if(s_rgbLed[index].ctrl_led == NULL)
			continue;
		if(s_rgbLed[index].cycle){	// 先亮后灭
			if(clock_time_exceed(s_rgbLed[index].start_tick, (s_rgbLed[index].on_time + s_rgbLed[index].off_time)*1000)){
				//s_rgbLed[index].ctrl_led(RGB_LED_OFF_LEVEL);	// 一个周期结束
				s_rgbLed[index].start_tick = clock_time();
				s_rgbLed[index].cycle--;
			}
			else if(clock_time_exceed(s_rgbLed[index].start_tick, s_rgbLed[index].on_time*1000)){
				s_rgbLed[index].ctrl_led(RGB_PWM_LED_OFF);	// 在一个周期中灭的时间内
			}
			else{
				s_rgbLed[index].ctrl_led(RGB_PWM_LED_ON);	// 在一个周期中亮的时间内
			}
		}else{
			s_rgbLed[index].ctrl_led(RGB_PWM_LED_OFF);
		}
	}while(++index < 3);
	if(is_rgb_led_busy()){
		reset_idle_status();
	}
}
// 判断现在是否有RGB灯任务在忙碌
u8 is_rgb_led_busy(void)
{
	return (s_rgbLed[RED_LED_INDEX].cycle||s_rgbLed[GREEN_LED_INDEX].cycle||s_rgbLed[BLUE_LED_INDEX].cycle)?1:0;
}
void set_dpi_rgb_led_evt(u8 dpi)
{
	const u8 dpi_rgb_duty[7][3] = {
		// reg    				green   				blue
		{	APP_PWM_MAX_VALUE,	0,						0},						/* 0 */
		{	APP_PWM_MAX_VALUE,	APP_PWM_MAX_VALUE/8,	0},						/* 1 */
		{	APP_PWM_MAX_VALUE/2,APP_PWM_MAX_VALUE/2,	0},						/* 2 */
		{	0,					APP_PWM_MAX_VALUE,		0},						/* 3 */
		{	0,					APP_PWM_MAX_VALUE/2,	APP_PWM_MAX_VALUE/2},	/* 4 */
		{	0,					0,						APP_PWM_MAX_VALUE},		/* 5 */
		{	APP_PWM_MAX_VALUE/2,0,						APP_PWM_MAX_VALUE/2},	/* 6 */
	};
	if(dpi >= 7){
		return;
	}
	printf("\nset dpi:......%d.\n");
	set_rgb_pwm_flash(RED_LED_INDEX, dpi_rgb_duty[dpi][RED_LED_INDEX]?5:0, 200, 300,dpi_rgb_duty[dpi][RED_LED_INDEX]);
	set_rgb_pwm_flash(GREEN_LED_INDEX, dpi_rgb_duty[dpi][GREEN_LED_INDEX]?5:0, 200, 300,dpi_rgb_duty[dpi][GREEN_LED_INDEX]);
	set_rgb_pwm_flash(BLUE_LED_INDEX, dpi_rgb_duty[dpi][BLUE_LED_INDEX]?5:0, 200, 300,dpi_rgb_duty[dpi][BLUE_LED_INDEX]);
}
/**
 * Data 23/12/28
 * Brief test rgb pwm ok.
 */
void test_app_pwm(void)
{
#if 1
	static u32 tick_loop = 0;
	static u8 select = 0;

	//while(1)
	{
	#if (MODULE_32K_WATCHDOG_ENABLE)
		wd_32k_clear();
	#endif
	#if (MODULE_32K_WATCHDOG_ENABLE)
		wd_32k_clear();
	#endif

		if(clock_time_exceed(tick_loop,500*1000)){
			tick_loop = clock_time();
			set_dpi_rgb_led_evt(select);
			select = (select+1)%7;
		}
		rgb_flash_led_task();
	}
#endif
}


文章来源:https://blog.csdn.net/qq_28851611/article/details/135361972
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。