泰凌微Telink pwm的一个坑

泰凌微芯片输出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		255void 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			1static 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 beginningpwm_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 1static 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();#endifif(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
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内联函数的作用

目的 主要为了提升程序运行速度。 分析 当程序调用一个函数时&#xff0c;程序暂停执行当前指令&#xff0c;跳到函数体处执行&#xff0c;在函数执行完后&#xff0c;返回原来的位置继续执行。如果该函数为内联函数&#xff0c;则不同跳&#xff0c;是因为该内联函数直接插…

Model::unguard()的作用

这是在生成假数据时碰见的&#xff0c;浅查了一下 Model::unguard() 是 Laravel 框架中的一个方法&#xff0c;它的作用是取消对 Eloquent 模型的属性赋值的安全性保护。 在默认情况下&#xff0c;Laravel 的 Eloquent 模型会对属性赋值做一些安全性检查&#xff0c;例如防止…

报告解读:中国新一代终端安全市场洞察,2023

报告解读 中国新一代终端安全市场洞察 2023 安全防御的“最前线” 01 混沌的企业安全 以下来自CSO们最关注的安全热点问题&#xff1a; Q1我们如何看待当下泛化的终端安全&#xff0c;混合的IT环境企业面临的安全变化&#xff1f; IDC&#xff1a;伴随着全球数字化转型的快…

win11操作系统下eNSP 安装及使用

eNSP是华为出品的一款网络设备模拟软件&#xff0c;非常的好用。在这款软件面世之前&#xff0c;博主也曾经使用过思科或其他厂家的模拟软件&#xff0c;要么界面不友好&#xff0c;要么操作很繁琐&#xff0c;并且大部分软件的运行环境配置很复杂&#xff0c;费九牛二虎之力都…

【C语言】作用域 和 生命周期

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…

分布式系统架构设计之分布式数据存储的备份恢复和监控故障排查

七、数据备份和恢复 在分布式数据存储中&#xff0c;数据备份和恢复是保障数据存储系统可靠性和容灾性的重要组成部分。这里会给大家介绍关于数据备份和恢复的关键考虑&#xff1a; 数据备份策略 定期备份&#xff1a;设定定期的数据备份计划&#xff0c;根据业务需求选择合…

深入数组扩展应用

一、字符串反转 例如&#xff1a;‘123abc’----->‘cba321’ 字符串方法实现: var str 123abcvar reversFn function(str) {var newStr for (var i str.length - 1; i > 0; i--) {newStr str[i]}return newStr }console.log(reversFn(str));数组方法实现&#xf…

【通关喜报】腾讯云TDSQL TCP/TCE、云运维tcp 12月认证考试,全员过关,年终冲刺!

2023年12月23日云贝教育有6位学员参加了腾讯云TDSQL-TCP以及TCE认证考试。都取得非常好的成绩~下面我们来看一下各位同学的理论考试和上机考试成绩吧~

我用 Python 自动生成图文并茂的数据分析报告

reportlab是Python的一个标准库&#xff0c;可以画图、画表格、编辑文字&#xff0c;最后可以输出PDF格式。它的逻辑和编辑一个word文档或者PPT很像。有两种方法&#xff1a; 1&#xff09;建立一个空白文档&#xff0c;然后在上面写文字、画图等&#xff1b; 2&#xff09;建…

【银行测试】超细支付功能测试+测试点总结分析(详全)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、支付功能怎么测…

新能源汽车@2023/24:卷价格、拼智能与生态战

【潮汐商业评论/原创】 2023年末尾&#xff0c;受到大众广泛热议的小米汽车发布会“姗姗来迟”&#xff0c;也为“乱战”中的2023新能源汽车市场画上了一个句号。 然而&#xff0c;在雷军整整三个小时看似平和的演讲与技术讲解中&#xff0c;实则在电机、智驾、智舱等核心技术…

vue3按钮点击频率控制

现有一个按钮&#xff0c;如下图 点击时 再次点击 刷新窗口再次点击 刷新窗口依然可以实现点击频率控制。 代码实现&#xff1a; <template><!--<el-config-provider :locale"locale"><router-view/></el-config-provider>--><el…