最近在使用中微CMS8S3680/69xx系列8位单片机来进行电源控制软件开发。
总体觉得这款单片机简单易用,特别是它的数字功能可以映射到任意脚,甚至包括程序的烧录脚,对于PCB布局特别灵活。另外它的存储器资源也是很丰富的,16K字节ROM,256字节RAM以及512字节的XRAM,对于一般的程序是绰绰有余了。编程方面它也有库函数包装好了相关的寄存器设置,无论是使用库函数还是直接设置寄存器都能快速构建应用。详细情况及资料下载可以访问其官方网站:中微半导-CMS79F11x
本次编写的一个程序也是电源控制方面的,软件没有时序要求,比较简单,功能需求大致如下(只说明了各个引脚的功能):
引脚 | 引脚特性 | 网络名 | 功能 | 功能要求 |
1 | / | GND | 地 | |
2 | A/D采样 | 12VS | 检测12V输出电压 | 输出10.8V-12.6V为正常(2.5-2.8V) 输出>13V,4脚出高(打嗝保护)(3V保护,2.8V恢复正常) 输出<10V为异常(2.31V保护,2.5V恢复正常) |
3 | 输出 | 12V_JLOFF | 12V均流关断信号 | 12V输出正常时,输出高电平 12V输出异常时,输出低电平 (默认出低电平,检测2脚状态) |
4 | 输出 | 12V_OFF | 12V关机信号 | 关机:输出高电平(打嗝保护,间隔时间3.5S) 开机:输出低电平,默认低电平 (默认出低电平,检测2脚、7脚) |
5 | A/D采样 | OT2 | 过温保护+风扇调速 | 型号:TTC3A104J4193LY 过温保护点为105℃,恢复点为85℃ 保护时关闭两路输出 |
6 | A/D采样 | DSCK | 检测53V过流保护、过压保护 | 检测为高,关闭53V输出 检测为低,恢复53V输出 |
7 | A/D采样 | 12V_OCP/ | 检测12V过流保护 | 检测为高,关闭12V输出; 检测为低,恢复12V输出 |
8 | A/D采样 | F_F | 风扇故障检测 | 检测高电平,风扇故障 检测低电平,风扇解除故障 |
9 | 输出 | FAN_F | 风扇故障告警 | 检测风扇故障:出高 检测风扇正常:出低,默认出高 |
10 | 输出 | FAN_PWM | 风扇PWM信号 | 根据OT2温度进行风扇调速 |
11 | 输出 | OUT_LED_R | 亮红灯 | 12V /53V输出异常出高(电源风扇异常、输出过压、输出限流、输出短路、电源过温保护) 输出正常出低,默认出高 |
12 | 输出 | OUT_LED_G | 亮绿灯 | 输出正常,出高亮绿灯 输出异常出低,默认出低 |
13 | A/D采样 | PG_IN | 检测53V输出正常 | 正常为高 异常为低 |
14 | 输出 | 53V_OFF1 | 53V输出关机信号 | 关闭输出,出高(打嗝保护,间隔时间3.5S) 恢复输出,出低 |
15 | / | DSDA | 数据 | / |
16 | VDD | 供电脚 | / |
单片机原理图部分如下:
源程序如下:
1、main.c:主程序,所有程序逻辑的控制基本都是在这里,以下几个函数大致说明一下:
ADC_Process():主要用于检测12V输出的电压和NTC贴片电阻进行过温检测;
Process_1MS():1毫秒任务处理,主要IO滤波和54V输出异常检测;
Process_10MS():10毫秒任务处理,用于过流/过压打嗝的定时计数;
OCP_Process():12V和54V输出过流打嗝标志位设置和清除;
Task_Manager():根据设置的标志位对输出的通断进行控制以及各个告警信号的输出控制;
Adjust_FAN_Duty():根据温度变化来设置风扇控制的PWM占空比。温度越高占空比越高,反之占空比越低;
/*******************************************************************************
* Copyright (C) 2019 China Micro Semiconductor Limited Company. All Rights Reserved.
*
* This software is owned and published by:
* CMS LLC, No 2609-10, Taurus Plaza, TaoyuanRoad, NanshanDistrict, Shenzhen, China.
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with CMS
* components. This software is licensed by CMS to be adapted only
* for use in systems utilizing CMS components. CMS shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. CMS is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/****************************************************************************/
/** \file main.c
**
**
**
** History:
**
*****************************************************************************/
/****************************************************************************/
/* include files
*****************************************************************************/
#include "cms8s6990.h"
#include "demo_timer.h"
#include "demo_adc.h"
#include "demo_epwm.h"
#include "main.h"
/****************************************************************************/
/* Local pre-processor symbols('#define')
*****************************************************************************/
/****************************************************************************/
/* Global variable definitions(declared in header file with 'extern')
*****************************************************************************/
volatile uint8_t cFlag_1ms = 0; //1ms timeout flag
volatile uint8_t cDelay_10ms = 0; //10 milli-seconds overflow flag
volatile uint8_t cFlag_2ms = 0; //2 milli-seconds timeout for ADC filtering
volatile uint8_t c2mS_Nct = 0; //2 milli-seconds counter
uint16_t u16FanDuty = 0; //the duty cycle of the FAN
ALARM_STATUS AlarmStatus;
//IO check
uint8_t v54_ocp_delay = 0; //when V54 OCP occurs, we need to delay about 40 milli-second and then start the hiccup
uint8_t v54_on_time = 0;
uint8_t v12_on_time = 0;
uint16_t io_filter_cnt = 0;
uint8_t pg_in_L =0, pg_in_H =0;
uint8_t fan_fail_L =0, fan_fail_H =0;
/*===================================================================
Burp related variables
====================================================================*/
uint8_t cBurpOnDelay1=0; //ON state duration in a hiccup period of 12V output
//uint8_t cDelay1On=0;
uint16_t cDelay1Burp=0; //OFF state duration in a hiccup period
uint8_t cBurpOn1Flag=0; //OFF time is timeout and switches to ON state
uint8_t cBurpOnDelay2=0; //54V hiccup
uint16_t cDelay2Burp=0;
uint8_t cBurpOn2Flag=0;
/****************************************************************************/
/* Local type definitions('typedef')
*****************************************************************************/
/****************************************************************************/
/* Local variable definitions('static')
*****************************************************************************/
//System clock setting
uint32_t Systemclock = 24000000;
/****************************************************************************/
/* Local function prototypes('static')
*****************************************************************************/
/**
*@name: AD_Filter
*@description: AD filtering, mainly the 12V voltage filtering
*@params: none
*@return: none
*/
//static void AD_Filter(void)
//{
//}
/**
*@name: IO_Status_Check
*@description: Check all the IO status and set the flags accordingly
*@params: none
*@return: none
*/
static void IO_Status_Check(void)
{
if(PG_IN == 1) pg_in_H++; //1: noral, 0: error
else pg_in_L++;
if(FAN_FAIL == 0) fan_fail_L++; //0: Fan works correctly
else fan_fail_H++;
if (io_filter_cnt >= IO_FILTER_CNT)
{
if (pg_in_H >= IO_FILTER_VALID_CNT && AlarmStatus.alarm.V54_FAILED == 1)//54V status
{
AlarmStatus.alarm.V54_FAILED = 0;
}
else if (pg_in_L >= IO_FILTER_VALID_CNT && AlarmStatus.alarm.V54_FAILED == 0)
{
AlarmStatus.alarm.V54_FAILED = 1;
}
if (fan_fail_L >= IO_FILTER_VALID_CNT && AlarmStatus.alarm.FAN_FAILED == 1)//fan check
{
AlarmStatus.alarm.FAN_FAILED = 0;
}
else if (fan_fail_H >= IO_FILTER_VALID_CNT && AlarmStatus.alarm.FAN_FAILED == 0)
{
AlarmStatus.alarm.FAN_FAILED = 1;
}
io_filter_cnt = 0;
pg_in_L =0;
pg_in_H =0;
fan_fail_L =0;
fan_fail_H =0;
}
else
{
io_filter_cnt++;
}
}
/**
*@name: State_Switching_Manager
*@description: switch all the states according to the power-supply status
e.g. if the VAC is over-voltage, we need to shut off the main output
*@params: none
*@return: none
*/
//static void State_Switching_Manager(void)
//{
//}
/**
*@name: V12V_OCP_Burp_Process
*@description: 12V OCP process
*@params: none
*@return: none
*/
static void V12_OCP_Burp_Process(void)
{
//if(V12_OCP)//check the OCP pin,1: OCP, 0: normal ,and at the same we check the V12 output status
if(V12_OCP || AlarmStatus.alarm.V12_OVP)
{
if(V12_OCP)
{
if(cBurpOn1Flag >= 3) cBurpOn1Flag = 3;//still OCP, 20-30 milli-seconds filtering
}
else //OVP occurred, set the counter without any delay
{
cBurpOn1Flag = 3;
}
}
else
{
cBurpOn1Flag = 0;
}
if(cBurpOn1Flag >= 3)//OCP occurs
{
if(AlarmStatus.alarm.OCP_V12 == 0) //the first time the OCP occurs
{
if(cBurpOnDelay1 == 0)//decreased in the 10 milli-seconds routine, total 50 milli-seconds
{
AlarmStatus.alarm.OCP_V12 = 1;
AlarmStatus.alarm.OCP_BURP_V12 = 1;
}
}
}
if(cDelay1Burp>=BURP_LAST_TIME)//3 seconds period
{
cDelay1Burp = 0;
AlarmStatus.alarm.OCP_V12 = 0;
AlarmStatus.alarm.OCP_BURP_V12 = 0;
}
/*
//if(V12_OCP)//check the OCP pin,1: OCP, 0: normal ,and at the same we check the V12 output status
if(V12_OCP || AlarmStatus.alarm.V12_OVP)
{
if(cBurpOn1Flag >= 3) cBurpOn1Flag = 3;//still OCP, 20-30 milli-seconds filtering
}
else
{
cBurpOn1Flag = 0;
}
if(cBurpOn1Flag >= 3)//OCP occurs
{
if(AlarmStatus.alarm.OCP_V12 == 0) //the first time the OCP occurs
{
if(cBurpOnDelay1 == 0)//decreased in the 10 milli-seconds routine, total 50 milli-seconds
{
AlarmStatus.alarm.OCP_V12 = 1;
AlarmStatus.alarm.OCP_BURP_V12 = 1;
}
}
}
if(cDelay1Burp>=BURP_LAST_TIME)//3 seconds period
{
cDelay1Burp = 0;
AlarmStatus.alarm.OCP_V12 = 0;
AlarmStatus.alarm.OCP_BURP_V12 = 0;
}
*/
}
/**
*@name: V54_OCP_Burp_Process
*@description: 54V OCP process
*@params: none
*@return: none
*/
static void V54_OCP_Burp_Process(void)
{
if(V54_OCP)//check the OCP pin,1: OCP, 0: normal
{
if(cBurpOn2Flag >= 3) //filtering to make sure that the OCP really occurs
{
cBurpOn2Flag = 3;//still OCP, 20-30 milli-seconds filtering
/*
if(AlarmStatus.alarm.V54_JL_FINISHED == 0)
{
if(v54_ocp_delay >= V54_JL_TIMEOUT)
{
AlarmStatus.alarm.V54_JL_FINISHED = 1;
}
}*/
}
}
else
{
cBurpOn2Flag = 0;
/*
if(v54_on_time >= V54_ON_TIME)//the OCP is dissolved completely
{
v54_ocp_delay = 0;
}
AlarmStatus.alarm.V54_JL_FINISHED = 0; //don't need any delay
*/
}
if(cBurpOn2Flag >= 3)//once OCP occurs, we need to delay some time before starting hiccup
{
if(AlarmStatus.alarm.OCP_V54 == 0) //the first time the OCP occurs
{
if(cBurpOnDelay2 == 0)//decreased in the 10 milli-seconds service routine, total 50 milli-seconds
{
AlarmStatus.alarm.OCP_V54 = 1;
AlarmStatus.alarm.OCP_BURP_V54 = 1;
}
}
}
if(cDelay2Burp>=BURP_LAST_TIME)//3 seconds period
{
cDelay2Burp = 0;
AlarmStatus.alarm.OCP_V54 = 0;
AlarmStatus.alarm.OCP_BURP_V54 = 0;
}
}
/**
*@function name: GPIO_Config
*@description:
*@parameters: None
*@return: None
#define PG_IN (P31) //input, 54V output signal, 1: normal, 0:error
#define V12_JL (P04) //output, V12 JL signal, 1: if V12 is OK, else: 0
#define V54_ON (P32) //output, 54V ON/OFF control, 0: OFF, 1: ON
#define V12_ON (P13) //output, 12V ON/OFF control, 0: OFF, 1: ON
#define FAN_OK (P24) //output, FAN signal, 0: normal, 1: exception
#define V54_OCP (P21) //input, 54V OCP, 0: normal, 1: OCP
#define V12_OCP (P22) //input, 12V OCP, 0: normal, 1: OCP
#define LED_GREEN (P30) //output, LED, 1: normal, 0: exception
#define LED_RED (P26) //output, LED, 0: normal, 1: exception
#define FAN_FAIL (P23) //input, fan status, 0: normal, 1: exception
*/
static void GPIO_Config(void)
{
//P31: PG_IN, 54V warning signal, input mode
GPIO_SET_MUX_MODE(P31CFG, GPIO_MUX_GPIO);
GPIO_ENABLE_INPUT(P3TRIS, GPIO_PIN_1);
//P04: 12V JL OFF, output mode
GPIO_SET_MUX_MODE(P04CFG, GPIO_MUX_GPIO);
GPIO_ENABLE_OUTPUT(P0TRIS, GPIO_PIN_4);
//P32: V54 ON/OFF control, output mode
GPIO_SET_MUX_MODE(P32CFG, GPIO_MUX_GPIO);
GPIO_ENABLE_OUTPUT(P3TRIS, GPIO_PIN_2);
//P13: V12 ON/OFF control, output mode
GPIO_SET_MUX_MODE(P13CFG, GPIO_MUX_GPIO);
GPIO_ENABLE_OUTPUT(P1TRIS, GPIO_PIN_3);
//P24: FAN_OK, output mode
GPIO_SET_MUX_MODE(P24CFG, GPIO_MUX_GPIO);
GPIO_ENABLE_OUTPUT(P2TRIS, GPIO_PIN_4);
//P21: V54 OCP, output mode
GPIO_SET_MUX_MODE(P21CFG, GPIO_MUX_GPIO);
GPIO_ENABLE_INPUT(P2TRIS, GPIO_PIN_1);
//P22: 12V_OCP, intput mode
GPIO_SET_MUX_MODE(P22CFG, GPIO_MUX_GPIO);
GPIO_ENABLE_INPUT(P2TRIS, GPIO_PIN_2);
//P30: green LED, shut off by default
GPIO_SET_MUX_MODE(P30CFG, GPIO_MUX_GPIO);
GPIO_ENABLE_OUTPUT(P3TRIS, GPIO_PIN_0);
//P26: REG LED, shut off by default
GPIO_SET_MUX_MODE(P26CFG, GPIO_MUX_GPIO);
GPIO_ENABLE_OUTPUT(P2TRIS, GPIO_PIN_6);
//P23: fan exception, intput mode
GPIO_SET_MUX_MODE(P23CFG, GPIO_MUX_GPIO);
GPIO_ENABLE_INPUT(P2TRIS, GPIO_PIN_3);
//set the default status of all output signals
V12_JL = 0;
LED_RED = 1;
LED_GREEN = 0;
FAN_OK = 1; //FAN is error by default
V12_ON = 1;//12V is OFF
V54_ON = 1;//54V is OFF
}
/**
*@name: Process_1MS
*@description: 1 milli-second task polling, including the I/O status check
*@params: none
*@return: none
*/
static void Process_1MS(void)
{
if (cFlag_1ms == 0)
{
return;
}
cFlag_1ms = 0;
IO_Status_Check();
}
/**
*@name: Process_10MS
*@description: 10 milli-seconds timeout process used to process the OCP check
*@params: none
*@return: none
*/
static void Process_10MS(void)
{
if(cDelay_10ms >= 10)
{
cDelay_10ms = 0;
if(cBurpOnDelay1!=0) cBurpOnDelay1--;
if(cBurpOnDelay2!=0) cBurpOnDelay2--;
//once in OCP state we count-up
if(AlarmStatus.alarm.OCP_V12 && cDelay1Burp < 1200) cDelay1Burp++;
if(AlarmStatus.alarm.OCP_V54 && cDelay2Burp < 1200) cDelay2Burp++;
if(cBurpOn1Flag < 10) ++cBurpOn1Flag;
if(cBurpOn2Flag < 10) ++cBurpOn2Flag;
if(AlarmStatus.alarm.V54_FAILED == 0 && AlarmStatus.alarm.OCP_BURP_V54 == 0)//check whether the V54 OCP is dissolved
{
if(++v54_on_time >= V54_ON_TIME)
{
v54_on_time = V54_ON_TIME;
}
}
if(AlarmStatus.alarm.V12_FAILED == 0 && AlarmStatus.alarm.OCP_BURP_V12 == 0)//check whether the V12 OCP is dissolved
{
if(++v12_on_time >= V12_ON_TIME)
{
v12_on_time = V12_ON_TIME;
}
}
/*
if(cBurpOn2Flag>=3)//ONLY when 54V OCP occurs can we up-count variable v54_ocp_delay
{
if(++v54_ocp_delay >= V54_JL_TIMEOUT) //wait for the JL to be finished
{
v54_ocp_delay = V54_JL_TIMEOUT;
}
}
if(AlarmStatus.alarm.V54_ON_LINE == 1 && AlarmStatus.alarm.OCP_BURP_V54 == 0)//check whether the V54 OCP is dissolved
{
if(++v54_on_time >= V54_ON_TIME)
{
v54_on_time = V54_ON_TIME;
}
}
*/
}
}
/**
*@name: OCP_Process
*@description: the OCP service routine for V12 and V54
*@params: none
*@return: none
*/
static void OCP_Process(void)
{
V12_OCP_Burp_Process();
V54_OCP_Burp_Process();
}
/**
*@name: Task_Manager
*@description: the output control and all the warnings process
*@params: none
*@return: none
*/
static void Task_Manager(void)
{
/*if(v12_ad_value >= V12_NORMAL_AD && AlarmStatus.alarm.V12_FAILED == 1) //12V output error check
{
AlarmStatus.alarm.V12_FAILED = 0;
}
else if(v12_ad_value <= V12_ERROR_AD && AlarmStatus.alarm.V12_FAILED == 0)
{
AlarmStatus.alarm.V12_FAILED = 1;
}*/
if(v12_ad_value <= V12_UVP_AD && AlarmStatus.alarm.V12_UVP == 0) //12V UVP check
{
AlarmStatus.alarm.V12_UVP = 1;
}
else if(v12_ad_value >= V12_UVP_RECOVERED_AD && AlarmStatus.alarm.V12_UVP == 1)
{
AlarmStatus.alarm.V12_UVP = 0;
}
if(v12_ad_value >= V12_OVP_AD && AlarmStatus.alarm.V12_OVP == 0) //12V OVP check
{
AlarmStatus.alarm.V12_OVP = 1;
}
else if(v12_ad_value <= V12_OVP_RECOVERED_AD && AlarmStatus.alarm.V12_OVP == 1)
{
AlarmStatus.alarm.V12_OVP = 0;
}
if(AlarmStatus.alarm.V12_UVP == 0 && AlarmStatus.alarm.V12_OVP == 0) //12V output error check
{
AlarmStatus.alarm.V12_FAILED = 0;
}
else
{
AlarmStatus.alarm.V12_FAILED = 1;
}
if(otp_ad_value >= T2OTP && AlarmStatus.alarm.OTP2 == 0) //OTP check
{
AlarmStatus.alarm.OTP2 = 1;
}
else if(otp_ad_value <= T2OTPHYS && AlarmStatus.alarm.OTP2 == 1)
{
AlarmStatus.alarm.OTP2 = 0;
}
if(AlarmStatus.alarm.V12_FAILED == 0)//12V JL OFF signal, 0: 12V has error, 1: 12V works well
{
V12_JL = 1;
}
else
{
V12_JL = 0;
}
if(AlarmStatus.alarm.FAN_FAILED == 0)//FAN warning signal, 1: error, 0: normal
{
FAN_OK = 0;
}
else
{
FAN_OK = 1;
}
/*
If there are no OCP and OTP, turn ON the output directly.
Once OCP occurs, we turn OFF the outpuT for about 3.5 second, and then turn ON it for about 100 milli-seconds.
Unless otherwise stated, other outputs have the same mechanism as the first channel.
*/
if((AlarmStatus.alarm.OTP2 == 0) && (AlarmStatus.alarm.OCP_BURP_V12 == 0))
{
V12_ON = 0; //turn ON 12V
cDelay1Burp = 0;
}
else
{
V12_ON = 1; //turn OFF 12V
cBurpOnDelay1 = 10;
v12_on_time = 0;
}
if((AlarmStatus.alarm.OTP2 == 0) && (AlarmStatus.alarm.OCP_BURP_V54 == 0))
{
V54_ON = 0; //turn ON 54V
cDelay2Burp = 0;
}
else
{
V54_ON = 1; //turn OFF 54V
cBurpOnDelay2 = 10;
v54_on_time = 0;
}
//If there is any warning or exception, turn on the RED LED
//and turn off the GREEN LED. Turn on the green LED in other cases.
if(((AlarmStatus.allbits & WARNING_FLAG) != 0x0000) || (v12_on_time < V12_ON_TIME) || (v54_on_time < V54_ON_TIME))
{
LED_GREEN = 0;
LED_RED = 1;
}
else //green LED is ON
{
LED_GREEN = 1;
LED_RED = 0;
}
}
/**
*@name: Watchdog_Manager
*@description: clear the watchdog overflowing timer
*@params: none
*@return: none
*/
static void Watchdog_Manager(void)
{
WDT_ClearWDT();
}
/******************************************************************************
** \brief WDT_Config
** \param [in]
**
** \return none
** \note
******************************************************************************/
static void WDT_Config(void)
{
//(1)feed the watchdog
WDT_ClearWDT();
/*
(2)set the clock and timeout
*/
WDT_ConfigOverflowTime(WDT_CLK_67108864); // Fsys=24Mhz -> Twdt = 67108864/24 = 2796.202ms
/*
(3)enable the overflow interrupt
*/
WDT_EnableOverflowInt();
IRQ_SET_PRIORITY(IRQ_WDT, IRQ_PRIORITY_HIGH);
IRQ_ALL_ENABLE();
}
/******************************************************************************
** \brief initialize the warning flags
** \param [in]
**
** \return none
** \note
******************************************************************************/
static void Init_Flags(void)
{
AlarmStatus.alarm.V12_UVP = 1;
AlarmStatus.alarm.V12_OVP = 1;
AlarmStatus.alarm.V12_FAILED = 1;
AlarmStatus.alarm.V54_FAILED = 1;
AlarmStatus.alarm.FAN_FAILED = 1;
AlarmStatus.alarm.OTP2 = 1;
}
/******************************************************************************
** \brief adjust the duty cycle of the FAN according to the temperature
** \param [in] value, the duty cycle
**
** \return none
** \note
******************************************************************************/
static void Adjust_FAN_Duty(void)
{
//set a minumum duty cycle if the temperature is less than or equal to 30 degree, 20%
if(TMP_OUT <= 30)
{
u16FanDuty = 1200;
}
else if(TMP_OUT >= 70)//set the maximum duty cycle, 100%
{
u16FanDuty = 6000;
}
else //2% duty cycle per step
{
u16FanDuty = (uint8_t)(6000- (8400-(120 * TMP_OUT)));//linear duty cycle according to the temperature
}
if(u16FanDuty > 6000)//can't exceed the maximum duty cycle
{
u16FanDuty = 6000;
}
if(u16FanDuty < 1200)//at least 20% duty cycle
{
u16FanDuty = 1200;
}
Adjust_EPWM_Duty(u16FanDuty);
}
/****************************************************************************/
/* Function implementation - global ('extern') and local('static')
*****************************************************************************/
/*****************************************************************************
** \brief main
**
** \param [in] none
**
** \return 0
*****************************************************************************/
int main(void)
{
GPIO_Config();
ADC_Config();
EPWM_Config();
TMR1_Config();
Init_Flags();
WDT_Config();
SYS_EnableWDTReset();
while (1)
{
ADC_Process();
Process_1MS();
Process_10MS();
OCP_Process();
Task_Manager();
Adjust_FAN_Duty();
Watchdog_Manager();
}
//return 0;//unreachable
}
2、main.h:头文件
/**
* @file main.h
* @author Nations Solution Team
* @version v1.0.0
*
* @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved.
*/
#ifndef __MAIN_H__
#define __MAIN_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "cms8s6990.h"
#define BURP_LAST_TIME 350 //turn off the 54V and 12V for about 3.5 seconds once OCP
#define V54_ON_TIME 50 //If the 54V output works normally about 500 milli-seconds, then we think that the OCP is dissolved.
#define V12_ON_TIME 50 //If the 12V output works normally about 500 milli-seconds, then we think that the OCP is dissolved.
#define V54_JL_TIMEOUT 4 //delay 40 milli-seconds once V54 OCP occurs
#define BURP_PS_ON_TIME 100 //turn on the 54V and 12V output for about 100 milli-seconds
#define IO_FILTER_CNT 20 //IO filter count
#define IO_FILTER_VALID_CNT 20 //IO valid count of filter
#define WARNING_FLAG 0x00FF //warning bits to be examined
/*
==========================================================================================================================
IO Pin Macros
==========================================================================================================================
*/
#define PG_IN (P31) //input, 54V output signal, 1: normal, 0:error
#define V12_JL (P04) //output, V12 JL signal, 1: if V12 is OK, else: 0
#define V54_ON (P32) //output, 54V ON/OFF control, 0: OFF, 1: ON
#define V12_ON (P13) //output, 12V ON/OFF control, 0: OFF, 1: ON
#define FAN_OK (P24) //output, FAN signal, 0: normal, 1: exception
#define V54_OCP (P21) //input, 54V OCP, 0: normal, 1: OCP
#define V12_OCP (P22) //input, 12V OCP, 0: normal, 1: OCP
#define LED_GREEN (P30) //output, LED, 1: normal, 0: exception
#define LED_RED (P26) //output, LED, 0: normal, 1: exception
#define FAN_FAIL (P23) //input, fan status, 0: normal, 1: exception
extern volatile uint8_t cFlag_1ms;
extern volatile uint8_t cDelay_10ms;
extern volatile uint8_t cFlag_2ms;
extern volatile uint8_t c2mS_Nct;
struct ALARM
{
unsigned V12_FAILED : 1; //12V status
unsigned V54_FAILED : 1; //54V status
unsigned FAN_FAILED : 1; //FAN status
unsigned OTP2 : 1; //OTP
unsigned OCP_V12 : 1; //12V OCP
unsigned OCP_V54 : 1; //54V OCP
unsigned OCP_BURP_V12 : 1;
unsigned OCP_BURP_V54 : 1;
unsigned V12_UVP : 1;
unsigned V12_OVP : 1;
unsigned : 1;
unsigned : 1;
unsigned : 1;
unsigned : 1;
unsigned : 1;
unsigned : 1;
};
union ALARM_STATUS_UNION {
struct ALARM alarm;
uint16_t allbits;
};
typedef union ALARM_STATUS_UNION ALARM_STATUS;
typedef enum
{
FAILED = 0,
PASSED = !FAILED
} Status;
extern ALARM_STATUS AlarmStatus;
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H__ */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
3、demo_timer.c:定时器1的1毫秒定时设置
/*******************************************************************************
* Copyright (C) 2019 China Micro Semiconductor Limited Company. All Rights Reserved.
*
* This software is owned and published by:
* CMS LLC, No 2609-10, Taurus Plaza, TaoyuanRoad, NanshanDistrict, Shenzhen, China.
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with CMS
* components. This software is licensed by CMS to be adapted only
* for use in systems utilizing CMS components. CMS shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. CMS is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/****************************************************************************/
/** \file demo_timer.c
**
**
**
** History:
**
*****************************************************************************/
/****************************************************************************/
/* include files
*****************************************************************************/
#include "demo_timer.h"
#include "main.h"
/****************************************************************************/
/* Local pre-processor symbols('#define')
****************************************************************************/
#define TIMER_1MS 2000
/****************************************************************************/
/* Global variable definitions(declared in header file with 'extern')
****************************************************************************/
/****************************************************************************/
/* Local type definitions('typedef')
****************************************************************************/
/****************************************************************************/
/* Local variable definitions('static')
****************************************************************************/
/****************************************************************************/
/* Local function prototypes('static')
****************************************************************************/
/****************************************************************************/
/* Function implementation - global ('extern') and local('static')
****************************************************************************/
/******************************************************************************
** \brief TMR1_Config
** \param [in]
**
** \return none
** \note
******************************************************************************/
void TMR1_Config(void)
{
//(1)设置Timer的运行模式
TMR_ConfigRunMode(TMR1, TMR_MODE_TIMING, TMR_TIM_16BIT);
//(2)设置Timer 运行时钟
TMR_ConfigTimerClk(TMR1, TMR_CLK_DIV_12);//Fsys = 24Mhz,Ftimer = 2Mhz,Ttmr=0.5us
//(3)设置Timer周期
TMR_ConfigTimerPeriod(TMR1, (65536 - TIMER_1MS) >> 8, 65536 - TIMER_1MS); // 2000*0.5us = 1000us,递增计数
//(4)开启中断
TMR_EnableOverflowInt(TMR1);
//(5)设置Timer中断优先级
IRQ_SET_PRIORITY(IRQ_TMR1, IRQ_PRIORITY_LOW);
IRQ_ALL_ENABLE();
//(6)开启Timer
TMR_Start(TMR1);
}
4、demo_adc.c:主要是ADC检测及NTC贴片电阻不同阻值下对应的AD值表,然后程序根据AD值表获取相应的温度信息。AD取样每两毫秒进行一次,12V输出电压共检测16次,温度值检测共8次,然后取平均值。
/*******************************************************************************
* Copyright (C) 2019 China Micro Semiconductor Limited Company. All Rights Reserved.
*
* This software is owned and published by:
* CMS LLC, No 2609-10, Taurus Plaza, TaoyuanRoad, NanshanDistrict, Shenzhen, China.
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with CMS
* components. This software is licensed by CMS to be adapted only
* for use in systems utilizing CMS components. CMS shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. CMS is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/****************************************************************************/
/** \file demo_adc.c
**
**
**
** History:
**
*****************************************************************************/
/****************************************************************************/
/* include files
*****************************************************************************/
#include "demo_adc.h"
#include <math.h>
/****************************************************************************/
/* Local pre-processor symbols('#define')
****************************************************************************/
/****************************************************************************/
/* Global variable definitions(declared in header file with 'extern')
****************************************************************************/
extern volatile uint8_t cFlag_2ms;
#define SAMPLE_COUNT 15 //sample count
uint16_t sample_cnt = 0; //sampled count
uint8_t channel = 0; //current ADC channel
//===================================================================================
//Unless stated otherwise, the following variables are similar to those that ACS uses
//===================================================================================
uint32_t sample_ad_sum = 0;
uint16_t v12_ad_value = 0;
uint16_t otp_ad_value = 0;
signed int TMP_OUT = 0; //the actual temperature needed in fan duty cycle adjust
xdata uint16_t ARP_CWF4200[136] = {0x29,
0x2C,
0x2E,
0x31,
0x34,
0x38,
0x3B,
0x3F,
0x42,
0x47,
0x4B,
0x4F,
0x54,
0x59,
0x5E,
0x64,
0x6A,
0x70,
0x76,
0x7D,
0x84,
0x8B,
0x93,
0x9B,
0xA4,
0xAC,
0xB6,
0xBF,
0xC9,
0xD4,
0xDF,
0xEA,
0xF6,
0x103,
0x110,
0x11D,
0x12B,
0x13A,
0x149,
0x158,
0x169,
0x179,
0x18B,
0x19C,
0x1AF,
0x1C2,
0x1D6,
0x1EB,
0x1FF,
0x215,
0x22B,
0x243,
0x25A,
0x272,
0x28B,
0x2A5,
0x2BF,
0x2DA,
0x2F6,
0x312,
0x32F,
0x34C,
0x36A,
0x389,
0x3A8,
0x3C8,
0x3E9,
0x40A,
0x42B,
0x44D,
0x46F,
0x492,
0x4B6,
0x4D9,
0x4FE,
0x522,
0x547,
0x56C,
0x591,
0x5B7,
0x5DD,
0x603,
0x629,
0x64F,
0x675,
0x69C,
0x6C2,
0x6E8,
0x70E,
0x735,
0x75A,
0x780,
0x7A6,
0x7CC,
0x7F1,
0x816,
0x83A,
0x85F,
0x883,
0x8A7,
0x8CB,
0x8ED,
0x910,
0x932,
0x954,
0x975,
0x995,
0x9B6,
0x9D6,
0x9F5,
0xA14,
0xA32,
0xA50,
0xA6D,
0xA89,
0xAA6,
0xAC0,
0xADB,
0xAF5,
0xB0E,
0xB27,
0xB40,
0xB58,
0xB70,
0xB87,
0xB9E,
0xBB5,
0xBCB,
0xBE1,
0xBF6,
0xC0B,
0xC1F,
0xC33,
0xC47,
0xC5A,
0xC6D
};
/****************************************************************************/
/* Local type definitions('typedef')
****************************************************************************/
/****************************************************************************/
/* Local variable definitions('static')
****************************************************************************/
/****************************************************************************/
/* Local function prototypes('static')
****************************************************************************/
/****************************************************************************/
/* Function implementation - global ('extern') and local('static')
****************************************************************************/
/******************************************************************************
** \brief ADC_Config
** \param [in]
**
** \return none
** \note
******************************************************************************/
void ADC_Config(void)
{
uint8_t temp = 20;
//set the run mode of the ADC
//set the ADC clock divided by 16 of the system clock, the conversion is left-alignment
//ADC_ConfigRunMode(ADC_CLK_DIV_256, ADC_RESULT_LEFT);
//====please refer to the user manual page 175====
ADC_ConfigRunMode(ADC_CLK_DIV_16, ADC_RESULT_LEFT);
//set ADC channels used
GPIO_SET_MUX_MODE(P17CFG, GPIO_P17_MUX_AN20);//OTP check
GPIO_SET_MUX_MODE(P05CFG, GPIO_P05_MUX_AN5);//12V output voltage check
channel = CH_V12;
ADC_EnableChannel(channel);
while (temp-- != 0);
//set the interrupt, here we don't need the interrupt
//ADC_EnableInt();
//IRQ_SET_PRIORITY(IRQ_ADC,IRQ_PRIORITY_HIGH);
//IRQ_ALL_ENABLE();
//start and enable the ADC, set ADEN bit to 1
ADC_Start();
}
/**
*@name: TTC05104_ADBinary_Search
*@description: get the index of the table NTC_ADArray according to the ADC value
order by ASC
*@params: ad_value: the sampled ADC value
*@return: the final AD value
*/
static uint8_t ARP_CWF4200_ADBinary_Search(uint16_t ad_value)
{
int start=0; //start index
int end = 135; //max index
int mid = 0; //the index we need
while(start<=end)
{
mid=(start+end)/2;//get the middle index
if(mid==135) break;//the maximum index
if(ad_value==ARP_CWF4200[mid]) break; //we get the right index
if((ad_value>ARP_CWF4200[mid])&&(ad_value<ARP_CWF4200[mid+1])) break;
if(ad_value>ARP_CWF4200[mid]) //the index we need is in the second part
start = mid+1;
else if(ad_value<ARP_CWF4200[mid])
end = mid-1;
}
return mid;//get the index
}
/*
* function name: Cal_Temperature
* description: convert the ADC value to temperature
* params: ad_value: NTC AD value
* return: the actual temperature multiplied by 100
*/
signed int Cal_Temperature(uint16_t ad_value)
{
float temperature=0.00;
signed short search_temperature=0;
uint8_t temp=ARP_CWF4200_ADBinary_Search(ad_value);
if(temp < 135)
{
search_temperature=temp-30;
temperature=search_temperature+(float)(ARP_CWF4200[temp]-ad_value)/(float)(ARP_CWF4200[temp]-ARP_CWF4200[temp+1]);
//temperature*=10;
}
else
{
return (105);//maximum temperature is 105
}
return (signed int)(temperature);
}
void ADC_Process(void)
{
ADC_Sample();
TMP_OUT = Cal_Temperature(otp_ad_value);
}
/**
*@name: ADC_Sample
*@description: Sample the AD value and set the sample_flag according to the result
*@params: none
*@return: none
*/
void ADC_Sample(void)
{
uint16_t ad_data = 0;
uint8_t temp = 20; //delay about 500ns when changing the ADC channel
if(cFlag_2ms == 1) //2 milli-seconds timeout
{
switch(channel)
{
case CH_V12:
ADC_GO();
while (ADC_IS_BUSY);//wait while the ADGO bit is 1
ad_data = ADC_GetADCResult();
sample_ad_sum += ad_data;
if (sample_cnt >= SAMPLE_COUNT)
{
sample_cnt = 0;
v12_ad_value = sample_ad_sum >> 4;
sample_ad_sum = 0;
channel = CH_OTP;
ADC_EnableChannel(CH_OTP);
temp = 20;
while (temp-- != 0);
}
else
{
sample_cnt++;
}
break;
case CH_OTP:
ADC_GO();
while (ADC_IS_BUSY);
ad_data = ADC_GetADCResult();
sample_ad_sum += ad_data;
if (sample_cnt >= SAMPLE_COUNT - 8)
{
sample_cnt = 0;
otp_ad_value = sample_ad_sum >> 3;
sample_ad_sum = 0;
channel = CH_V12;
ADC_EnableChannel(CH_V12);
temp = 20;
while (temp-- != 0);
}
else
{
sample_cnt++;
}
break;
default:
sample_cnt = 0;
sample_ad_sum = 0;
channel = CH_V12;
ADC_EnableChannel(CH_V12);
temp = 20;
while (temp-- != 0);
break;
}
cFlag_2ms = 0;
}
}
5、demo_adc.h:ADC头文件定义:
/*******************************************************************************
* Copyright (C) 2019 China Micro Semiconductor Limited Company. All Rights Reserved.
*
* This software is owned and published by:
* CMS LLC, No 2609-10, Taurus Plaza, TaoyuanRoad, NanshanDistrict, Shenzhen, China.
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with CMS
* components. This software is licensed by CMS to be adapted only
* for use in systems utilizing CMS components. CMS shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. CMS is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/*****************************************************************************/
/** \file demo_timer.h
**
**
**
** History:
** -
*****************************************************************************/
#ifndef __DEMO_ADC_H__
#define __DEMO_ADC_H__
/*****************************************************************************/
/* Include files */
/*****************************************************************************/
#include "cms8s6990.h"
/*****************************************************************************/
/* Global pre-processor symbols/macros ('#define') */
/*****************************************************************************/
#define CH_V12 ADC_CH_5
#define CH_OTP ADC_CH_20
#define ADCFS 4096.0 //12-bit ADC maximum AD value
#define ADCREF 5.0 //3.3V reference voltage
#define V12_DIV_RUP (10.0) //up and down resistors
#define V12_DIV_RLOW 3.0
#define ADC_DIV_REF (float)(ADCFS/ADCREF)
#define V12_DIV_GAIN ((float)(V12_DIV_RLOW/(V12_DIV_RLOW + V12_DIV_RUP)))//gain: 3.0/(3.0+13)
#define V12_OVP_AD 2458 //3.0V
#define V12_OVP_RECOVERED_AD 2294 //2.8V
#define V12_UVP_AD 1884 //2.3V
#define V12_UVP_RECOVERED_AD 2048 //2.5V
//#define V12_NORMAL_AD 2048 //2.5V
//#define V12_ERROR_AD 1884 //2.3V
//#define V12_UVP_ALARM 9.0
//#define V12_OVP_ALARM 15.0
//#define V12_UVP_ALARM_OFF 11.0
//#define V12_OVP_ALARM_OFF 13.0
//#define V12_UVP_ALARM_AD (uint16_t)(V12_UVP_ALARM * V12_DIV_GAIN * ADC_DIV_REF)
//#define V12_OVP_ALARM_AD (uint16_t)(V12_OVP_ALARM * V12_DIV_GAIN * ADC_DIV_REF)
//#define V12_UVP_ALARM_OFF_AD (uint16_t)(V12_UVP_ALARM_OFF * V12_DIV_GAIN * ADC_DIV_REF)
//#define V12_OVP_ALARM_OFF_AD (uint16_t)(V12_OVP_ALARM_OFF * V12_DIV_GAIN * ADC_DIV_REF)
// APR-CWF104F4200FA20A Temperature sensor
#define T2OTP 3083 // 100C,3.76V,5.57K
#define T2OTPHYS 2580 // 80C,3.15V,10.75K
/*****************************************************************************/
/* Global type definitions ('typedef') */
/*****************************************************************************/
/*****************************************************************************/
/* Global variable declarations ('extern', definition in C source) */
/*****************************************************************************/
extern uint16_t v12_ad_value;
extern uint16_t otp_ad_value;
extern signed int TMP_OUT;
/*****************************************************************************/
/* Global function prototypes ('extern', definition in C source) */
/*****************************************************************************/
/******************************************************************************
** \brief ADC_Config
** \param [in]
**
** \return none
** \note
******************************************************************************/
void ADC_Config(void);
void ADC_Process(void);
void ADC_Sample(void);
signed int Cal_Temperature(uint16_t ad_value);
#endif /* __DEMO_ADC_H__ */
6、demo_epwm.c:风扇调速设置,频率为4K,占空比最小20%,最大100%,根据温度线性调整占空比,1温度值占空比步进为2%,温度越高占空比越大:
/*******************************************************************************
* Copyright (C) 2019 China Micro Semiconductor Limited Company. All Rights Reserved.
*
* This software is owned and published by:
* CMS LLC, No 2609-10, Taurus Plaza, TaoyuanRoad, NanshanDistrict, Shenzhen, China.
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with CMS
* components. This software is licensed by CMS to be adapted only
* for use in systems utilizing CMS components. CMS shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. CMS is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/****************************************************************************/
/** \file demo_timer.c
**
**
**
** History:
**
*****************************************************************************/
/****************************************************************************/
/* include files
*****************************************************************************/
#include "demo_epwm.h"
/****************************************************************************/
/* Local pre-processor symbols('#define')
****************************************************************************/
/****************************************************************************/
/* Global variable definitions(declared in header file with 'extern')
****************************************************************************/
/****************************************************************************/
/* Local type definitions('typedef')
****************************************************************************/
/****************************************************************************/
/* Local variable definitions('static')
****************************************************************************/
/****************************************************************************/
/* Local function prototypes('static')
****************************************************************************/
/****************************************************************************/
/* Function implementation - global ('extern') and local('static')
****************************************************************************/
/****************************************************************************/
/* Function implementation - global ('extern') and local('static')
****************************************************************************/
/******************************************************************************
** \brief EPWM_Config (complementary, no dead time)
** \param [in]
**
** \return none
** \note
******************************************************************************/
void EPWM_Config(void)
{
//set the run mode of the EPWM
EPWM_ConfigRunMode(EPWM_COUNT_DOWN);
//EPWM_ConfigRunMode(EPWM_WFG_COMPLEMENTARY|EPWM_OC_INDEPENDENT|EPWM_OCU_SYMMETRIC|EPWM_COUNT_DOWN);
//set the clock of the EPWM, using system clock
EPWM_ConfigChannelClk(EPWM4, EPWM_CLK_DIV_1);
//set the dudy cycle of the EPWM
EPWM_ConfigChannelPeriod(EPWM4, PWM_PERIOD);
#if (1)
EPWM_ConfigChannelSymDuty(EPWM4, 0x0BB8);//50% duty cycle by default, 3000
#elif (0)
EPWM_ConfigChannelSymDuty(EPWM4, 0);
#else
EPWM_ConfigChannelSymDuty(EPWM4, 0xFFFF);
#endif
//set the auto-load mode
EPWM_EnableAutoLoadMode(EPWM_CH_4_MSK);
//set the output polarity, disable the reverse output
EPWM_DisableReverseOutput(EPWM_CH_4_MSK);
//EPWM_DisableReverseOutput(EPWM_CH_0_MSK|EPWM_CH_1_MSK|EPWM_CH_2_MSK|EPWM_CH_3_MSK|EPWM_CH_4_MSK|EPWM_CH_5_MSK);
//set the output of the EPWM
EPWM_EnableOutput(EPWM_CH_4_MSK);
//EPWM_EnableOutput(EPWM_CH_0_MSK|EPWM_CH_1_MSK|EPWM_CH_2_MSK|EPWM_CH_3_MSK|EPWM_CH_4_MSK|EPWM_CH_5_MSK);
//disable the dead zone
EPWM_DisableDeadZone(EPWM4);
EPWM_EnableZeroInt(EPWM_CH_4_MSK); //enable the Zero interrupt of the EPWM
EPWM_AllIntEnable(); //enable the global interrupt of the EPWM
IRQ_SET_PRIORITY(IRQ_PWM, IRQ_PRIORITY_HIGH);
IRQ_ALL_ENABLE(); //enable the global interrupt
//set the alternate function of the GPIO
//here we can also set other pins to the EPWM output channel
GPIO_SET_MUX_MODE(P25CFG, GPIO_MUX_PG4);
//start the EPWM
EPWM_Start(EPWM_CH_4_MSK);
}
/******************************************************************************
** \brief adjust the duty cycle of the EPWM
** \param [value]: the duty cycle of the EPWM
**
** \return none
** \note
******************************************************************************/
void Adjust_EPWM_Duty(uint16_t value)
{
EPWM_ConfigChannelSymDuty(EPWM4, value);
}
7、demo_epwm.h:相应的头文件
/*******************************************************************************
* Copyright (C) 2019 China Micro Semiconductor Limited Company. All Rights Reserved.
*
* This software is owned and published by:
* CMS LLC, No 2609-10, Taurus Plaza, TaoyuanRoad, NanshanDistrict, Shenzhen, China.
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with CMS
* components. This software is licensed by CMS to be adapted only
* for use in systems utilizing CMS components. CMS shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. CMS is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/*****************************************************************************/
/** \file demo_epwm.h
**
**
**
** History:
** -
*****************************************************************************/
#ifndef __DEMO_EPWM_H__
#define __DEMO_EPWM_H__
/*****************************************************************************/
/* Include files */
/*****************************************************************************/
#include "cms8s6990.h"
#include "main.h"
/*****************************************************************************/
/* Global pre-processor symbols/macros ('#define') */
/*****************************************************************************/
#define PWM_FREQUENCY 4000 //the frequency of the EPWM
#define PWM_PERIOD (24000000/PWM_FREQUENCY)//24000000(system clock)*(1/4000)
#define MAX_BASE 54.0
#define T54_DUTY (uint16_t)((54.0/MAX_BASE)*PWM_PERIOD)
#define T52_DUTY (uint16_t)((52.0/MAX_BASE)*PWM_PERIOD)
#define T50_DUTY (uint16_t)((50.0/MAX_BASE)*PWM_PERIOD)
#define T48_DUTY (uint16_t)((48.0/MAX_BASE)*PWM_PERIOD)
#define T44_DUTY (uint16_t)((44.0/MAX_BASE)*PWM_PERIOD)
/*****************************************************************************/
/* Global type definitions ('typedef') */
/*****************************************************************************/
/*****************************************************************************/
/* Global variable declarations ('extern', definition in C source) */
/*****************************************************************************/
/*****************************************************************************/
/* Global function prototypes ('extern', definition in C source) */
/*****************************************************************************/
/******************************************************************************
** \brief EPWM_Config (complementary, no dead time)
** \param [in]
**
** \return none
** \note
******************************************************************************/
void EPWM_Config(void);
void Adjust_EPWM_Duty(uint16_t value);
#endif /* __DEMO_EPWM_H__ */
8、isr.c:中断处理,这里主要是Timer1超时溢出处理:
/*******************************************************************************
* Copyright (C) 2019 China Micro Semiconductor Limited Company. All Rights Reserved.
*
* This software is owned and published by:
* CMS LLC, No 2609-10, Taurus Plaza, TaoyuanRoad, NanshanDistrict, Shenzhen, China.
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with CMS
* components. This software is licensed by CMS to be adapted only
* for use in systems utilizing CMS components. CMS shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. CMS is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/****************************************************************************/
/** \file isr.c
**
**
**
** History:
**
*****************************************************************************/
/****************************************************************************/
/* include files
*****************************************************************************/
#include "cms8s6990.h"
#include "demo_timer.h"
#include "main.h"
/****************************************************************************/
/* Local pre-processor symbols('#define')
****************************************************************************/
/****************************************************************************/
/* Global variable definitions(declared in header file with 'extern')
****************************************************************************/
/****************************************************************************/
/* Local type definitions('typedef')
****************************************************************************/
/****************************************************************************/
/* Local variable definitions('static')
****************************************************************************/
/****************************************************************************/
/* Local function prototypes('static')
****************************************************************************/
/****************************************************************************/
/* Function implementation - global ('extern') and local('static')
****************************************************************************/
/******************************************************************************
** \brief INT0 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void INT0_IRQHandler(void) interrupt INT0_VECTOR
{
}
/******************************************************************************
** \brief Timer 0 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void Timer0_IRQHandler(void) interrupt TMR0_VECTOR
{
//P24 =~P24;
}
/******************************************************************************
** \brief INT0 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void INT1_IRQHandler(void) interrupt INT1_VECTOR
{
;
}
/******************************************************************************
** \brief Timer 1 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void Timer1_IRQHandler(void) interrupt TMR1_VECTOR
{
cFlag_1ms = 1;
++cDelay_10ms;
if(++c2mS_Nct >= 2)
{
cFlag_2ms = 1;
c2mS_Nct = 0;
}
TH1 = (65536 - TIMER_1MS) >> 8 ;
TL1 = 65536 - TIMER_1MS;
}
/******************************************************************************
** \brief UART 0 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void UART0_IRQHandler(void) interrupt UART0_VECTOR
{
}
/******************************************************************************
** \brief Timer 2 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void Timer2_IRQHandler(void) interrupt TMR2_VECTOR
{
}
/******************************************************************************
** \brief UART 1 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void UART1_IRQHandler(void) interrupt UART1_VECTOR
{
;
}
/******************************************************************************
** \brief GPIO 0 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void P0EI_IRQHandler(void) interrupt P0EI_VECTOR
{
//if(GPIO_GetIntFlag(GPIO0, GPIO_PIN_5))//the AC is OK
//{
//ac_down_cnt=0;
//GPIO_ClearIntFlag(GPIO0, GPIO_PIN_5);
//}
}
/******************************************************************************
** \brief GPIO 1 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void P1EI_IRQHandler(void) interrupt P1EI_VECTOR
{
;
}
/******************************************************************************
** \brief GPIO 2 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void P2EI_IRQHandler(void) interrupt P2EI_VECTOR
{
}
/******************************************************************************
** \brief GPIO 3 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void P3EI_IRQHandler(void) interrupt P3EI_VECTOR
{
;
}
/******************************************************************************
** \brief LVD interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void LVD_IRQHandler(void) interrupt LVD_VECTOR
{
}
/******************************************************************************
** \brief LSE interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void LSE_IRQHandler(void) interrupt LSE_VECTOR
{
}
/********************************************************************************
** \brief ACMP interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void ACMP_IRQHandler(void) interrupt ACMP_VECTOR
{
}
/******************************************************************************
** \brief Timer 3 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void Timer3_IRQHandler(void) interrupt TMR3_VECTOR
{
}
/******************************************************************************
** \brief Timer 4 interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void Timer4_IRQHandler(void) interrupt TMR4_VECTOR
{
}
/******************************************************************************
** \brief EPWM interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void EPWM_IRQHandler(void) interrupt EPWM_VECTOR
{
if (EPWM_GetZeroIntFlag(EPWM4))
{
//P24 = ~P24;
EPWM_ClearZeroIntFlag(EPWM4);
}
}
/******************************************************************************
** \brief ADC interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void ADC_IRQHandler(void) interrupt ADC_VECTOR
{
}
/******************************************************************************
** \brief WDT interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void WDT_IRQHandler(void) interrupt WDT_VECTOR
{
if (WDT_GetOverflowIntFlag())
{
//P24 = ~P24;
WDT_ClearOverflowIntFlag();
}
}
/******************************************************************************
** \brief I2C interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void I2C_IRQHandler(void) interrupt I2C_VECTOR
{
;
}
/******************************************************************************
** \brief SPI interrupt service function
**
** \param [in] none
**
** \return none
******************************************************************************/
void SPI_IRQHandler(void) interrupt SPI_VECTOR
{
;
}