234 lines
14 KiB
C
234 lines
14 KiB
C
|
#include "generic/gpio.h"
|
|||
|
#include "asm/includes.h"
|
|||
|
#include "asm/pwm_led.h"
|
|||
|
#include "system/timer.h"
|
|||
|
#include "board_config.h"
|
|||
|
|
|||
|
#ifdef CONFIG_BOARD_AC696X_DEMO
|
|||
|
//注意事项:
|
|||
|
//1.使用该模块需确认 TCFG_PWMLED_ENABLE 和 UI中的pwm_led 都处于DISABLE状态
|
|||
|
//2.进入蓝牙模式时需要在蓝牙初始化完成后(BT_STATUS_INIT_OK)再设置灯效,蓝牙初始化过程会影响pwm_led模块
|
|||
|
//3.一个pwm周期内最多只能进行4次IO口反转,能够实现双闪动作,如果需要进行更多的闪动则需要配合PWM的中断来实现
|
|||
|
//
|
|||
|
//
|
|||
|
//=============周期灯========================================================================================================================================
|
|||
|
//
|
|||
|
// __第一次反转后状态保持时间__ __第三次反转后状态保持时间__
|
|||
|
// holdtime1_ms | holdtime2_ms | holdtime3_ms | holdtime4_ms | cycle_ms减去所有hondtime
|
|||
|
//高亮灯:__初始状态保持时间__| |__第二次反转后状态保持时间__| |___最后电平持续时间,持续到周期结束_______
|
|||
|
//低亮灯:_____________________ ______________________________ ___________________________________________
|
|||
|
// | | | |
|
|||
|
// |__________________________| |__________________________|
|
|||
|
// |<---------------------------------------------整个PWM亮灭周期(中断周期):cycle_ms--------------------------------------------------------------->|
|
|||
|
//
|
|||
|
//1.PMW周期从灭灯开始,高亮灯初始电平为低,低亮灯初始电平为高
|
|||
|
//
|
|||
|
//===========================================================================================================================================================
|
|||
|
//struct pwm_cycle_pattern{
|
|||
|
// u32 cycle_ms; //PWM产生的一个亮灭周期,单位ms
|
|||
|
// u32 holdtime1_ms; //初始状态保持时间,等于0时接近于PWM周期从亮灯开始
|
|||
|
// u32 holdtime2_ms; //第一次反转后状态保持时间,等于0时关闭
|
|||
|
// u32 holdtime3_ms; //第二次反转后状态保持时间,等于0时关闭
|
|||
|
// u32 holdtime4_ms; //第三次反转后状态保持时间,等于0时关闭
|
|||
|
// u16 led_L_bright; //低电平灯亮度设置
|
|||
|
// u16 led_H_bright; //高电平灯亮度设置
|
|||
|
// u8 led_type; //LED类型 0:低亮 1:高亮
|
|||
|
// u8 shift_duty; //每隔shift_duty个周期后输出电平取反,亮度设置不变,也就是说当前灯的图案会切换到两外一个灯上,用于周期变色处理,等于0时功能关闭
|
|||
|
//};
|
|||
|
//=============呼吸灯========================================================================================================================================
|
|||
|
//
|
|||
|
// _最高亮度保持时间__ __
|
|||
|
// __| led_H_holdtime |__ __|
|
|||
|
// breathe_interval __| |__ breathe_interval __|
|
|||
|
//高亮灯:____________呼吸间隔________| breathe_time |____________呼吸间隔________|
|
|||
|
// |<----------呼吸时间----------->|
|
|||
|
// |<---PWM周期(中断周期) = breathe_interval + breathe_time---->|
|
|||
|
//
|
|||
|
//低亮灯:
|
|||
|
//
|
|||
|
//===========================================================================================================================================================
|
|||
|
//struct pwm_breathe_pattern{
|
|||
|
// u32 breathe_interval; //呼吸间隔,LED处于灭灯状态,PWM初始化后经过一个呼吸间隔后才开始第一次呼吸动作。
|
|||
|
// u16 breathe_time; //呼吸时间(灭->最亮->灭), 设置范围: 500ms以上;
|
|||
|
// u32 led_L_holdtime; //低电平灯最高亮度保持时间,呼吸时间-保持时间=渐变时间 (0 ~ 100ms);
|
|||
|
// u32 led_H_holdtime; //高电平灯最高亮度保持时间,呼吸时间-保持时间=渐变时间 (0 ~ 100ms);
|
|||
|
// u16 led_L_bright; //低电平灯呼吸到最亮的亮度设置(0 ~ 500);
|
|||
|
// u16 led_H_bright; //高电平灯呼吸到最亮的亮度设置(0 ~ 500);
|
|||
|
// u8 led_type; //LED类型 1:高亮 0:低亮
|
|||
|
// u8 shift_duty; //每隔shift_duty个周期后输出电平取反,亮度设置不变,也就是说当前灯的呼吸效果会切换到两外一个灯上,用于周期变色处理,等于0时功能关闭
|
|||
|
//};
|
|||
|
|
|||
|
|
|||
|
extern void pwm_cycle_pattern_init(struct pwm_cycle_pattern *pattern);
|
|||
|
extern void pwm_breathe_pattern_init(struct pwm_breathe_pattern *pattern);
|
|||
|
extern void pwmled_pwm_init();
|
|||
|
extern void led_pwm_clear_pending();
|
|||
|
extern void led_pwm_isr_en(u8 en);
|
|||
|
extern void led_pin_set_enable(u8 gpio);
|
|||
|
extern void led_pin_set_disable(u8 disable_pin);
|
|||
|
|
|||
|
extern void pwm_ledL_off_Nms(int off_ms);
|
|||
|
extern void pwm_ledL_four_flash_test();
|
|||
|
|
|||
|
volatile u8 pwm_isr_state;
|
|||
|
volatile u32 pwm_isr_cnt;
|
|||
|
|
|||
|
enum {
|
|||
|
four_flash_cnt = 0,
|
|||
|
four_flash_interval,
|
|||
|
change_PWM_IO,
|
|||
|
};
|
|||
|
//===========================================================================================================================================================
|
|||
|
//pwm周期中断函数
|
|||
|
//
|
|||
|
//===========================================================================================================================================================
|
|||
|
___interrupt
|
|||
|
void pwm_cycle_isr_func()
|
|||
|
{
|
|||
|
led_pwm_clear_pending();
|
|||
|
switch (pwm_isr_state) {
|
|||
|
case four_flash_cnt:
|
|||
|
pwm_isr_cnt++;
|
|||
|
if (pwm_isr_cnt == 4) {
|
|||
|
pwm_ledL_off_Nms(2000);//闪动4次之后切换到灭灯周期
|
|||
|
}
|
|||
|
break;
|
|||
|
case four_flash_interval:
|
|||
|
pwm_ledL_four_flash_test();//灭灯周期结束后切换到4闪周期
|
|||
|
break;
|
|||
|
case change_PWM_IO:
|
|||
|
pwm_isr_cnt++;
|
|||
|
if (pwm_isr_cnt == 2) { //进行PWM IO口切换动作
|
|||
|
led_pin_set_disable(IO_PORTA_00);
|
|||
|
led_pin_set_enable(IO_PORTA_01);
|
|||
|
} else if (pwm_isr_cnt >= 4) {
|
|||
|
pwm_isr_cnt = 0;
|
|||
|
led_pin_set_disable(IO_PORTA_01);
|
|||
|
led_pin_set_enable(IO_PORTA_00);
|
|||
|
}
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
//===========================================================================================================================================================
|
|||
|
//高亮灯,每隔1秒进行一次双闪示例
|
|||
|
//
|
|||
|
// __第一次反转后状态保持时间__ __第三次反转后状态保持时间__
|
|||
|
// holdtime1_ms | holdtime2_ms | holdtime3_ms | holdtime4_ms | cycle_ms减去所有hondtime
|
|||
|
//高亮灯:__初始状态保持时间__| |__第二次反转后状态保持时间__| |___最后电平持续时间,持续到周期结束_______
|
|||
|
// |<---------------------------------------------整个PWM亮灭周期(中断周期):cycle_ms--------------------------------------------------------------->|
|
|||
|
//
|
|||
|
//
|
|||
|
//===========================================================================================================================================================
|
|||
|
void pwm_ledH_double_flash_test()
|
|||
|
{
|
|||
|
struct pwm_cycle_pattern pattern = {0};
|
|||
|
pattern.cycle_ms = 1000; //每隔1秒进行一次动作,需要设置PWM周期为1000ms
|
|||
|
pattern.holdtime1_ms = 10; //设置初始灭灯状态的保持时间,主要作用是产生PWM中断之后能在灭灯状态下进行相关设置,时间到则IO反转进入亮灯状态。
|
|||
|
pattern.holdtime2_ms = 100; //设置第一次亮灯保持时间,时间到则IO反转进入灭灯状态。
|
|||
|
pattern.holdtime3_ms = 100; //设置第一次灭灯保持时间,即两次亮灯的时间间隔,时间到则IO反转进入亮灯状态。
|
|||
|
pattern.holdtime4_ms = 100; //设置第二次亮灯保持时间,时间到则IO反转进入灭灯状态并持续要周期结束。
|
|||
|
pattern.led_L_bright = 0; //只操作高亮灯时,低亮灯亮度设置为0。
|
|||
|
pattern.led_H_bright = 500; //设置高亮灯的亮度。
|
|||
|
pattern.led_type = 1; //设置亮灯类型:0:低亮 1:高亮 2:两灯跳变效果
|
|||
|
pattern.shift_duty = 0; //关闭周期取反功能
|
|||
|
|
|||
|
pwm_cycle_pattern_init(&pattern); //根据配置好的pwm周期图案进行初始话并启动PWM_LED模块
|
|||
|
led_pwm_isr_en(0); //关闭pwm中断
|
|||
|
}
|
|||
|
//===========================================================================================================================================================
|
|||
|
//PMW周期图案加周期中断实现低亮灯周期4闪例子
|
|||
|
//
|
|||
|
//低亮灯:___holdtime1_ms______ ____
|
|||
|
// | |
|
|||
|
// |____holdtime1_ms:200ms____|
|
|||
|
// |<--整个PWM亮灭周期(中断周期):cycle_ms:400ms->|
|
|||
|
//
|
|||
|
//实现方法:
|
|||
|
// 1.画出单闪的PWM图案和一个灭灯的PWM图案
|
|||
|
// 2.使能PWM中断计算4次pwm单闪后切换到灭灯PWM周期
|
|||
|
// 3.灭灯PWM周期结束后再切换到4个单闪周期
|
|||
|
//===========================================================================================================================================================
|
|||
|
void pwm_ledL_off_Nms(int off_ms)
|
|||
|
{
|
|||
|
struct pwm_cycle_pattern pattern = {0};
|
|||
|
pattern.cycle_ms = off_ms; //设置灭灯时间,时间到产生pwm中断
|
|||
|
pattern.holdtime1_ms = 0;
|
|||
|
pattern.holdtime2_ms = 0;
|
|||
|
pattern.holdtime3_ms = 0;
|
|||
|
pattern.holdtime4_ms = 0;
|
|||
|
pattern.led_L_bright = 0;
|
|||
|
pattern.led_H_bright = 0;
|
|||
|
pattern.led_type = 0;
|
|||
|
pattern.shift_duty = 0;
|
|||
|
|
|||
|
pwm_cycle_pattern_init(&pattern);
|
|||
|
pwm_isr_state = four_flash_interval;//设置灭灯周期结束后进行闪动切换处理
|
|||
|
pwm_isr_cnt = 0;
|
|||
|
led_pwm_isr_en(1);
|
|||
|
}
|
|||
|
|
|||
|
void pwm_ledL_four_flash_test()
|
|||
|
{
|
|||
|
struct pwm_cycle_pattern pattern = {0};
|
|||
|
pattern.cycle_ms = 400; //设置4闪过程中的亮灭周期,每闪动一次周期是400ms
|
|||
|
pattern.holdtime1_ms = 10; //设置周期开始时灭灯保持时间
|
|||
|
pattern.holdtime2_ms = 200; //设置每个闪动周期的亮灯时间200ms
|
|||
|
pattern.holdtime3_ms = 0; //
|
|||
|
pattern.holdtime4_ms = 0; //
|
|||
|
pattern.led_L_bright = 500; //设置低亮灯亮度
|
|||
|
pattern.led_H_bright = 0; //
|
|||
|
pattern.led_type = 0; //
|
|||
|
pattern.shift_duty = 0; //
|
|||
|
|
|||
|
pwm_cycle_pattern_init(&pattern); //根据配置好的pwm周期图案进行初始话并启动PWM_LED模块
|
|||
|
pwm_isr_state = four_flash_cnt; //设置pwm中断时进行4闪的计数处理
|
|||
|
pwm_isr_cnt = 0;
|
|||
|
led_pwm_isr_en(1); //使能pwm中断
|
|||
|
}
|
|||
|
//===========================================================================================================================================================
|
|||
|
//PWM呼吸图案加周期中断处理,实现两个IO口推4灯轮流呼吸例子
|
|||
|
//
|
|||
|
// _最高亮度保持时间__ __
|
|||
|
// __| led_H_holdtime |__ __|
|
|||
|
// breathe_interval __| |__ breathe_interval __|
|
|||
|
//高亮灯:____________呼吸间隔________| breathe_time |____________呼吸间隔________|
|
|||
|
// |<----------呼吸时间----------->|
|
|||
|
// |<---PWM周期(中断周期) = breathe_interval + breathe_time---->|
|
|||
|
//
|
|||
|
//实现方法:
|
|||
|
// 1.画出单个灯的呼吸图案
|
|||
|
// 2.打开双灯模式和设置状态周期互换实现第二个灯的切换
|
|||
|
// 3.产生两次PWM中断后切换IO口,进行第三和第四个灯的呼吸效果
|
|||
|
//===========================================================================================================================================================
|
|||
|
void pwm_four_led_breathe_test()
|
|||
|
{
|
|||
|
struct pwm_breathe_pattern pattern = {0};
|
|||
|
pattern.breathe_interval = 1000; //设置呼吸间隔为1000ms,实现每次灭灯间隔1s后进行一次呼吸动作。
|
|||
|
pattern.breathe_time = 2000; //设置呼吸时间为2000ms,2秒内实现 灭->最亮->灭
|
|||
|
pattern.led_H_bright = 500; //设置呼吸时间内高亮灯最高亮度
|
|||
|
pattern.led_H_holdtime = 100; //设置呼吸时间内高亮灯最高亮度维持时
|
|||
|
pattern.led_L_bright = 500; //设置呼吸时间内低亮灯最高亮度
|
|||
|
pattern.led_L_holdtime = 100; //设置呼吸时间内低亮灯最高亮度维持时
|
|||
|
pattern.led_type = 2; //推双灯模式
|
|||
|
pattern.shift_duty = 1; //每个周期进行双灯状态互换
|
|||
|
|
|||
|
pwm_breathe_pattern_init(&pattern);
|
|||
|
pwm_isr_state = change_PWM_IO;
|
|||
|
pwm_isr_cnt = 0;
|
|||
|
led_pwm_isr_en(1);
|
|||
|
}
|
|||
|
//===========================================================================================================================================================
|
|||
|
//pwm初始化函数,用户使用该API时需要在 app_main() 调用该函数进行模块初始化
|
|||
|
//
|
|||
|
//===========================================================================================================================================================
|
|||
|
void app_pwmled_init()
|
|||
|
{
|
|||
|
request_irq(IRQ_PWM_LED_IDX, 1, pwm_cycle_isr_func, 0); //初始化PWM中断函数
|
|||
|
led_pin_set_enable(IO_PORTA_00); //初始化PWM IO口
|
|||
|
pwmled_pwm_init(); //初始化PWM模块
|
|||
|
}
|
|||
|
|
|||
|
#endif
|