【驱动】KOP9967(高度集成化多通道智能驱动器集成电路)驱动
时间:2023-01-07 19:30:00
KOP9967(高度集成的多通道智能驱动集成电路)驱动
关于kop基于9967的驱动hc32l136k8ta环境,kop9967 datasheet rev020版本。
不详细描述性能和参数,直接上代码。驱动只提供8路继电器的驱动 以及128ms蜂鸣器驱动没有提到周期电平翻转维护。
.c文件
#include "KOP9967_drive.h" uint8_t T_Timer = 5;//KOP9967周期T relaydef relayCondef; /************************************************** ** 函数名称: void KOP9967IO_Init(void) ** 功能描述:kop9967 io初始化 ** 输 入: void ** 输 出: void ***************************************************/ void KOP9967IO_Init(void) { stc_gpio_config_t stcGpioCfg; ///< 打开GPIO钟门控制外设 Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); ///< 端口方向配置->输出 stcGpioCfg.enDir = GpioDirOut; ///< 端口驱动能力配置->高驱动能力 stcGpioCfg.enDrv = GpioDrvL; ///< 端口输入/输出值寄存器总线控制模式配置->AHB stcGpioCfg.enCtrlMode = GpioAHB; Gpio_Init(KOP9967GPIO_PORT, KOP9967GPIO_PIN, &stcGpioCfg); } /************************************************** ** 函数名称: void Ris_Edge(en_gpio_port_t enPort, en_gpio_pin_t enPin,uint8_t Cycle) ** 功能描述:连续输出高电平 ** 输 入: enPort IO Port口 enPin IO Pin脚 Cycle 持续时间 ** 输 出: ***************************************************/ void Ris_Edge(en_gpio_port_t enPort, en_gpio_pin_t enPin,uint16_t Cycle) { static uint16_t Cycle_Ris = 0; if(Cycle == 0) { Gpio_SetIO(enPort, enPin);//高电平输出 } else { while(Cycle_Ris < Cycle) { Gpio_SetIO(enPort, enPin);//高电平输出 Cycle_Ris ; } Cycle_Ris = 0; } } /************************************************** ** 函数名称: void Fall_Edge(en_gpio_port_t enPort, en_gpio_pin_t enPin,uint8_t Cycle) ** 功能描述:连续输出低电平 ** 输 入: enPort IO Port口 enPin IO Pin脚 Cycle 持续时间 ** 输 出: ***************************************************/ void Fall_Edge(en_gpio_port_t enPort, en_gpio_pin_t enPin,uint16_t Cycle) { static uint16_t Cycle_Fall = 0; if(Cycle == 0) { Gpio_ClrIO(enPort, enPin);//低电平输出 } else { while(Cycle_Fall < Cycle) { Gpio_ClrIO(enPort, enPin);//低电平输出 Cycle_Fall ; } Cycle_Fall = 0; } } /************************************************** ** 函数名称:void Out_Zero(void) ** 功能描述:输出 0 ** 输 入: ** 输 出: ***************************************************/ void Out_Zero(void) { static uint8_t Period_State_Zero = 0x01; while(Period_State_Zero < 0x04) { switch(Period_State_Zero) { case 0x01: Ris_Edge(KOP9967GPIO_PORT, KOP9967GPIO_PIN,T_Timer); Period_State_Zero = 0x02; break; case 0x02: Fall_Edge(KOP9967GPIO_PORT, KOP9967GPIO_PIN,T_Timer); Period_State_Zero = 0x03; break; case 0x03: Fall_Edge(KOP9967GPIO_PORT, KOP9967GPIO_PIN,T_Timer); Period_State_Zero = 0x04; break; default:break; } } Period_State_Zero = 0x01; } /************************************************** ** 函数名称:void Out_One(void) ** 功能描述:输出 1 ** 输 入: ** 输 出: ***************************************************/ void Out_One(void) { static uint8_t Period_State_One = 0x01; while(Period_State_One < 0x04) { switch(Period_State_One) { case 0x01: Ris_Edge(KOP9967GPIO_PORT, KOP9967GPIO_PIN,T_Timer); Period_State_One = 0x02; break; case 0x02: Ris_Edge(KOP9967GPIO_PORT, KOP9967GPIO_PIN,T_Timer); Period_State_One = 0x03; break; case 0x03: Fall_Edge(KOP9967GPIO_PORT, KOP9967GPIO_PIN,T_Timer); Period_State_One = 0x04; break; default:break; } } Period_State_One = 0x01; } /************************************************** ** 函数名称:void Out_One(void) ** 功能描述:输出 1 ** 输 入: ** 输 出: ***************************************************/ void relayKOP9967_ControlHandler(uint8_t maskval) { uint8_t i,j=0; rt_base_t level; /*关全局中断*/#erro 非RT-Thread os 删除此行代码 level = rt_hw_interrupt_disable()//避免多层嵌套临界区异常 //level进入临界段前保存 PRIMASK 的值 Ris_Edge(KOP9967GPIO_PORT, KOP9967GPIO_PIN,1); Fall_Edge(KOP9967GPIO_PORT, KOP9967GPIO_PIN,1); /*[Ld]*/ Ris_Edge(KOP9967GPIO_PORT, KOP9967GPIO_PIN,T_Timer); Ris_Edge(KOP9967GPIO_PORT, KOP9967GPIO_PIN,T_Timer); for(i=0;i<9;i ) Fall_Edge(KOP9967GPIO_PORT, KOP9967GPIO_PIN,T_Timer); /*[0]*/ Out_Zero(); /*[1]*/ Out_One(); /*[0]*/ Out_Zero(); /*[1]*/ Out_One(); /*[DA[0:15]]*/ for(i=0;i<8;i ) { switch(i) { case 0: { Out_One();//D0 保留位 //[1]:P7 输出低电平,[0]: P7 输出高阻态 if(maskval & 1<
锁存继电器状态并且周期越小越好 暂定10ms ** 输 入:void ** 输 出:void ***************************************************/ void relayControl_KOP9967_Update(relaydef *relay) { static uint8_t tmp = 0; static uint8_t cnt = 0; if(relay->updateSW == R_UPDATE)//发生更新 { cnt += 1; if(cnt > 150)//1.5s { cnt = 0; relay->updateSW = R_CONTINUE; relayKOP9967_ControlHandler(relay->updateTY); } else { !!/*此处的产生的周期电平翻转对于在实时性要求非较高时适用 但对于外设宽裕的条件下应采用硬件产生的方式*/ /*code start*/ tmp ^= 1; Gpio_WriteOutputIO(KOP9967GPIO_PORT,KOP9967GPIO_PIN,tmp); /*code end*/ } } else//驱动中配置最长保持时间为128ms 所以需要在这个时间内完成翻转 { cnt = 0; !!/*此处的产生的周期电平翻转对于在实时性要求非较高时适用 但对于外设宽裕的条件下应采用硬件产生的方式*/ /*code start*/ tmp ^= 1; Gpio_WriteOutputIO(KOP9967GPIO_PORT,KOP9967GPIO_PIN,tmp); /*code end*/ } }
#erro 此处贴出硬件产生的方式 当然可以使用pwm的方式 ##注意pwm的周期应小于2cly(上文提到的2*128ms)
此处和上文的软件翻转二选一!
!!
void TIM1_IRQHandler(void)
{
static volatile uint8_t tmp = 0;
rt_interrupt_enter();
if(TRUE == Bt_GetIntFlag(TIM1,BtUevIrq))
{
Bt_ClearIntFlag(TIM1,BtUevIrq);
tmp ^= 1;
Gpio_WriteOutputIO(KOP9967GPIO_PORT,KOP9967GPIO_PIN,tmp);
}
rt_interrupt_leave();
}
.h文件
#ifndef KOP9967_DRIVE_H
#define KOP9967_DRIVE_H
#include "gpio.h"
#include "app_task.h"
#define KOP9967GPIO_PORT GpioPortC
#define KOP9967GPIO_PIN GpioPin4
#define R_UPDATE 1
#define R_CONTINUE 0
typedef enum
{
relay_heat=0x80,
relay_lowspeed=0x40,
relay_midspeed=0x20,
relay_highspeed=0x10,
relay_cold=0x08,
relay_hot=0x04,
}updatetyenum;
typedef struct
{
uint8_t updateSW;
updatetyenum updateTY;
}relaydef;
extern relaydef relayCondef;
void KOP9967IO_Init(void);
void Ris_Edge(en_gpio_port_t enPort, en_gpio_pin_t enPin,uint16_t Cycle);
void Fall_Edge(en_gpio_port_t enPort, en_gpio_pin_t enPin,uint16_t Cycle);
void Out_Zero(void);
void Out_One(void);
void relayKOP9967_ControlHandler(uint8_t maskval);
void relayControl_KOP9967_Update(relaydef *relay);
#endif