本文在 “cc2640r2f led控制" 基础上修改 以PWM 形式控制 LED
工程创建 略过
一、修改控制引脚配置文件
CC2640R2_LAUNCHXL.h 修改默认配置引脚如下
CC2640R2_LAUNCHXL.c 修改PWM 默认对应引脚值
二、修改 led.c 文件如下
#include <ti/sysbios/knl/Clock.h> #include "util.h" #include "board.h" /*************************** LED 引脚 *************************************/ //static PIN_State led_state; //static const PIN_Config led_pins[] = { // LED_R | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, // LED_G | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, // LED_B | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, // PIN_TERMINATE //}; static PWM_Handle g_rled_pwm_handle = NULL; static PWM_Handle g_gled_pwm_handle = NULL; static PWM_Handle g_bled_pwm_handle = NULL; #define pwm_led_hz (10000)//100hz /*static*/ void led_gpio_init(void){ //if(!PIN_open(&led_state, led_pins)){ // PIN_open(&led_state, led_pins); //} PWM_Params g_pwm_params; PWM_init(); PWM_Params_init(&g_pwm_params); g_pwm_params.periodUnits = PWM_PERIOD_US; g_pwm_params.periodValue= 10000; g_pwm_params.dutyUnits = PWM_DUTY_US; g_pwm_params.dutyValue = 0; g_rled_pwm_handle = PWM_open(CC2640R2_LAUNCHXL_PWM0, &g_pwm_params); g_gled_pwm_handle = PWM_open(CC2640R2_LAUNCHXL_PWM1, &g_pwm_params); g_bled_pwm_handle = PWM_open(CC2640R2_LAUNCHXL_PWM2, &g_pwm_params); PWM_start(g_rled_pwm_handle); PWM_start(g_gled_pwm_handle); PWM_start(g_bled_pwm_handle); } static void gpio_set_value(PIN_Id id, unsigned char val, uint32_t duty){ //PIN_setOutputValue(&led_state, id, val); uint32_t dutyValue; PWM_Handle p_handle; dutyValue = (val == 0) ? 0: duty; if(id == LED_R){ p_handle = g_rled_pwm_handle; }else if(id == LED_G){ p_handle = g_gled_pwm_handle; }else if(id == LED_B){ p_handle = g_bled_pwm_handle; } PWM_stop(p_handle); PWM_setDuty(p_handle, dutyValue); PWM_start(p_handle); } /*******************************************************************/ static Clock_Struct led_period_clock; #define LED_PERIOD_TIME (100) //100ms static unsigned char led_cur_state = 0; typedef struct led_ctr_{ unsigned int gpio; //对应GPIO引脚 unsigned char state; //引脚当前状态 unsigned char _pd; // unsigned short count; //1~0xFFFE 闪烁次数,0xFFFF-不间断闪,0-切换当前状态, unsigned short period; //闪烁周期 unsigned short times; //当前时间计数,100ms为单位 uint32_t duty; //PWM 占空比 }led_ctr; #define LED_NUM_MAX (3) led_ctr g_led_ctr[LED_NUM_MAX] = { {LED_R, 0, 0, 0, 0}, {LED_G, 0, 0, 0, 0}, {LED_B, 0, 0, 0, 0} }; static void SDI_led_process(UArg arg){ unsigned char i; unsigned char n = 0; for(i=0; i<LED_NUM_MAX; i++){ if(g_led_ctr[i].times > 1){ g_led_ctr[i].times--; }else if(g_led_ctr[i].times == 1){ g_led_ctr[i].times = 0; g_led_ctr[i].state ^= 0x01; gpio_set_value(g_led_ctr[i].gpio, g_led_ctr[i].state, g_led_ctr[i].duty); if(g_led_ctr[i].count){ if(g_led_ctr[i].count != 0xFFFF) g_led_ctr[i].count--; g_led_ctr[i].times = g_led_ctr[i].period; } }else{ } if(g_led_ctr[i].times || g_led_ctr[i].count) n++; } if(!n){ Util_stopClock(&led_period_clock); led_cur_state = 0; } }
/* led: 对应的引脚 count: 闪烁次数 times_100ms:闪烁频率 以100ms为单位 onoff:开始为亮/灭 duty: pwm占空比 */ void SDI_led_indication(unsigned int led, unsigned char count, unsigned short times_100ms, unsigned char onoff, uint32_t duty){ unsigned char i=0; static unsigned char led_api_init = 0; //引脚判断 for(i=0; i<LED_NUM_MAX; i++){ if(led == g_led_ctr[i].gpio){ break; } } if(i == LED_NUM_MAX) return; //设置参数 if(count != 0){ g_led_ctr[i].count = (count == 0xFF) ? 0xFFFF: ((count - 1) << 1); g_led_ctr[i].period = times_100ms; g_led_ctr[i].times = times_100ms; }else{ g_led_ctr[i].count = 0; g_led_ctr[i].period = 0; g_led_ctr[i].times = 0; //g_led_ctr[i].duty = 0; } g_led_ctr[i].duty = duty * 100; g_led_ctr[i].state = onoff; //初始化LED if(!led_api_init){ led_api_init = 1; //led_gpio_init(); Util_constructClock(&led_period_clock, SDI_led_process, LED_PERIOD_TIME, LED_PERIOD_TIME, false, NULL); } //执行控制 if(!led_cur_state){ Util_startClock(&led_period_clock); led_cur_state = 1; } gpio_set_value(g_led_ctr[i].gpio, g_led_ctr[i].state, g_led_ctr[i].duty); }
三、控制使用示例
simple_peripheral_oad_onchip.c 文件如下函数增加测试
四、编译烧录,复位后测试引脚上波形如下