仅提供参考文件:
1、需要修改gpio引脚
2、需要根据平台实现软件定时器接口,启动,停止,回调,三个API。
3、根据平台优化相关错误即可
/*
* pwm_drv.c
*
* Created on: 2021年3月3日
* Author: Administrator
*/
#include "pwm_drv.h"
#include "appled.h"
enum {
PWM_LED = 0x00,
PWM_CHANNELS = 0x01
};
UserPwm_t userPwm[PWM_CHANNELS];
//定时器定义
EmberEventControl emberAfPluginBulbPwmDriverBlinkEventControl;
enum {
PWM_OUTPUT_ON = 0x00,
PWM_OUTPUT_OFF = 0x01,
PWM_BLINKING_ON = 0x02,
PWM_BLINKING_OFF = 0x03,
PWM_BLINK_PATTERN = 0x04,
};
static void pwmOutputOn(uint16_t time, UserPwm_t *p)
{
p->turnOn();
p->state = PWM_OUTPUT_ON;
if (time > 0) {
emberEventControlSetDelayMS(*(p->eventControl),
((uint32_t) time) * SECONDS_TO_MILLISECONDS);
} else {
emberEventControlSetInactive(*(p->eventControl));
}
}
static void pwmOutputOff(uint16_t time, UserPwm_t *p)
{
p->turnOff();
p->state = PWM_OUTPUT_OFF;
if (time > 0) {
emberEventControlSetDelayMS(*(p->eventControl),
((uint32_t) time) * SECONDS_TO_MILLISECONDS);
} else {
emberEventControlSetInactive(*(p->eventControl));
}
}
static void pwmBlink(uint16_t count, uint16_t blinkTime, UserPwm_t *p)
{
p->blinkTime = blinkTime;
p->turnOff();
p->state = PWM_BLINKING_OFF;
emberEventControlSetDelayMS(*(p->eventControl),
p->blinkTime);
p->count = count;
}
static void pwmTurnHigh(void)
{
HalSetledOnOff(BSP_LED1_PORT,BSP_LED1_PIN,true);
}
static void pwmTurnLow(void)
{
HalSetledOnOff(BSP_LED1_PORT,BSP_LED1_PIN,false);
}
static void pwmRunStop(void)
{
}
static void pwmRunStart(void)
{
}
// For example, if we wished to create an SOS pattern, we would
// program the following array:
// pattern[20] = {500, 100, 500, 100, 500, 100, 100, 100, 100, 100, 100, 100,
// 500, 100, 500, 100, 500, 100};
// Where the gpio would be on in a sequences of 500 and 100 mS intervals, and
// the gpio would be off for 100 mS in between the on intervals.
static void pwmRunPattern(uint16_t count,
uint16_t length,
uint16_t *pattern,
UserPwm_t *p)
{
uint16_t i;
if (length < 2) {
return;
}
p->turnOn();
p->state = PWM_BLINK_PATTERN;
if (length > PWM_PATTERN_MAX_LENGTH) {
length = PWM_PATTERN_MAX_LENGTH;
}
p->patternLength = length;
p->count = count;
for (i = 0; i < p->patternLength; i++) {
p->pattern[i] = pattern[i];
}
emberEventControlSetDelayMS(*(p->eventControl),
p->pattern[0]);
p->patternIndex = 1;
}
void pwmeventHandler(UserPwm_t *p)
{
emberEventControlSetInactive(*(p->eventControl));
switch (p->state) {
case PWM_OUTPUT_ON:
p->turnOff();
p->stop();
break;
case PWM_OUTPUT_OFF:
p->turnOn();
p->stop();
break;
case PWM_BLINKING_ON:
p->turnOff();
if (p->count == 0) {
p->state = PWM_OUTPUT_OFF;
p->stop();
break;
}
if (p->count != PWM_DRIVER_RUN_FOREVER) {
p->count--;
}
if (p->count > 0) {
p->state = PWM_BLINKING_OFF;
emberEventControlSetDelayMS(*(p->eventControl),
p->blinkTime);
} else {
p->state = PWM_OUTPUT_OFF;
p->stop();
}
break;
case PWM_BLINKING_OFF:
p->turnOn();
p->state = PWM_BLINKING_ON;
emberEventControlSetDelayMS(*(p->eventControl),
p->blinkTime);
break;
case PWM_BLINK_PATTERN:
if (p->count == 0) {
p->turnOff();
p->state = PWM_OUTPUT_OFF;
p->stop();
break;
}
if (p->patternIndex % 2 == 1) {
p->turnOff();
} else {
p->turnOn();
}
emberEventControlSetDelayMS(*(p->eventControl),
p->pattern[p->patternIndex]);
p->patternIndex++;
if (p->patternIndex >= p->patternLength) {
p->patternIndex = 0;
if (p->count != PWM_DRIVER_RUN_FOREVER) {
p->count--;
}
}
break;
default:
break;
}
}
void PwmDriverRunPattern(uint16_t count,
uint16_t length,
uint16_t *pattern)
{
pwmRunPattern(count, length, pattern, &(userPwm[PWM_LED]));
}
void PwmDriverBlink(uint16_t count, uint16_t blinkTime)
{
pwmBlink(count, blinkTime, &(userPwm[PWM_LED]));
}
void PwmDriverOutputOn(uint16_t time)
{
pwmOutputOn(time, &(userPwm[PWM_LED]));
}
void PwmDriverOutputOff(uint16_t time)
{
pwmOutputOff(time, &(userPwm[PWM_LED]));
}
// ******** APIs and Event Functions *************
void emberAfPluginBulbPwmDriverBlinkEventHandler(void)
{
pwmeventHandler(&(userPwm[PWM_LED]));
}
void PwmDriverInit(void)
{
userPwm[PWM_LED].turnOn = pwmTurnHigh;
userPwm[PWM_LED].turnOff = pwmTurnLow;
userPwm[PWM_LED].start = pwmRunStart;
userPwm[PWM_LED].stop = pwmRunStop;
userPwm[PWM_LED].eventControl = &(emberAfPluginBulbPwmDriverBlinkEventControl);
}
// sequence on -> off ->on -> off ->...
void testpwm(void)
{
PwmDriverInit();
uint16_t pattern[18] = {500, 100, 500, 100, 500, 100, 100, 100, 100, 100, 100, 100,500, 100, 500, 100, 500, 100};
PwmDriverRunPattern(2,sizeof(pattern),pattern);
//PwmDriverBlink(10,500);
//PwmDriverOutputOff(2000);
//PwmDriverOutputOn(2000);
}
/*
* pwm_drv.h
*
* Created on: 2021年3月3日
* Author: Administrator
*/
#ifndef EXTERNAL_COPIED_FILES_PWM_DRV_H_
#define EXTERNAL_COPIED_FILES_PWM_DRV_H_
#include <stdio.h>
#include "app/framework/include/af.h"
#define SECONDS_TO_MILLISECONDS (1)
#define PWM_PATTERN_MAX_LENGTH (20)
#define PWM_DRIVER_RUN_FOREVER (0xffff)
typedef struct {
uint8_t state;
uint16_t count;
uint16_t blinkTime;
uint16_t pattern[PWM_PATTERN_MAX_LENGTH];
uint16_t patternLength;
uint16_t patternIndex;
void (*turnOn)(void);
void (*turnOff)(void);
void (*start)(void);
void (*stop)(void);
EmberEventControl *eventControl;
} UserPwm_t;
void PwmDriverInit(void);
void PwmDriverRunPattern(uint16_t count,
uint16_t length,
uint16_t *pattern);
void PwmDriverBlink(uint16_t count, uint16_t blinkTime);
void PwmDriverOutputOn(uint16_t time);
void PwmDriverOutputOff(uint16_t time);
void testpwm(void);
#endif /* EXTERNAL_COPIED_FILES_PWM_DRV_H_ */