📄 control.c
字号:
/*
*********************************************************************************************************
*
* 包含头文件
*
*********************************************************************************************************
*/
#include <pic16f716.h>
#include "control.h"
#define __PIC16F716_H
//__CONFIG(XT & WDTDIS & PWRTDIS & PROTECT & BORDIS);
/*
*********************************************************************************************************
*
* 全局变量定义
*
*********************************************************************************************************
*/
UBYTE SUNFLAG;
UBYTE SUNFLAG0;
UBYTE SUNFLAG1; //阳光检测标志位
UBYTE BATTERRYVOLTAGE; //电池电压检测值
UBYTE OCVOTLAGE; //过流电压检测值
UBYTE bOldState; //老状态
UBYTE bNowState; //新状态
UBYTE sec; //秒
UWORD min; //分
UBYTE hour; //时
/*
*********************************************************************************************************
*
* 函数名称:void interrupt isr(void)
*
* 输入变量:无
*
* 输出变量:无
*
* 功能描述:中断服务函数
*
*********************************************************************************************************
*/
void interrupt isr(void) //@ 0x10
{
// unsigned char x;
if(TMR1IF)
{
Timer1Counter++;
if (Timer1Counter >= ONESECOND)
{
sec++;
if (sec >= 56) { // 56
min++;
if (min >= 910) {
// regTimer.hour++;
min = 0;
}
sec = 0;
}
Timer1Counter = 0;
}
TMR1H = 0x0b; //0x3c;
TMR1L = 0xdb; //0xaf; //预设时间寄存器初值
TMR1IF = 0;
}
// if(ADIF)
// {
// ADIF = 0;
// }
}
/*
*********************************************************************************************************
*
* 函数名称:void DelayTime(UWORD wTimer, UBYTE ucTimes)
*
* 输入变量:延时时间长短数据
*
* 输出变量:无
*
* 功能描述:不精确延时
*********************************************************************************************************
*/
void DelayTime(UWORD wTimer, UWORD ucTimes)
{
UWORD i;
for (i = ucTimes;i>0;i--);
for (i = wTimer;i>0;i--);
}
/*
*********************************************************************************************************
*
* 函数名称:void InitVariable(void)
*
* 输入变量:无
*
* 输出变量:无
*
* 功能描述:初始化变量
*********************************************************************************************************
*/
void InitVariable(void)
{
sec = 0;
min = 0;
hour = 0;
SUNFLAG = 0;
SUNFLAG0 = 0;
SUNFLAG1 = 0;
// bOldState = 1;
bNowState = 0;
CHARGEOUT = 0; //RB6输出低电平3843输出触发脉宽最窄,充电电流为零。
LOADOUT = 1; //RB4输出高电平导走负载触发电压,负载切断。
Timer1Counter = 0;
TMR1H = 0x0b; ////0x3c;
TMR1L = 0xdb; //0xaf; //预设时间寄存器初值
}
/*
*********************************************************************************************************
*
* 函数名称:void BatterryCharge(void)
*
* 输入变量:无
*
* 输出变量:无
*
* 功能描述:充电控制
*********************************************************************************************************
*/
//void BatterryCharge(void)
//{
//}
/*
*********************************************************************************************************
*
* 函数名称:UWORD TimeCheck(void)
*
* 输入变量:无
*
* 输出变量:时间参数(以分钟计)
*
* 功能描述:读取RB3~RB0的预制时间值后返回
*********************************************************************************************************
*/
UWORD TimeCheck(void)
{
UBYTE PortValue; //定义端口变量
PortValue = 0x00;
PortValue = PORTB;
PortValue = PortValue&0x0f; //确认低四位有效
if(PortValue == ONEHOUR)
{
return BACKONEHOUR; //定时1小时
}
else if (PortValue == TWOHOUR)
{
return BACKTWOHOUR; //定时2小时
}
else if (PortValue == THREEHOUR)
{
return BACKTHREEHOUR; //定时3小时
}
else if (PortValue == FOURHOUR)
{
return BACKFOURHOUR; //定时4小时
}
else if (PortValue == FIVEHOUR)
{
return BACKFIVEHOUR; //定时5小时
}
else if (PortValue == SIXHOUR)
{
return BACKSIXHOUR; //定时6小时
}
else if (PortValue == SEVENHOUR)
{
return BACKSEVENHOUR; //定时7小时
}
else if (PortValue == EGIHTHOUR)
{
return BACKEGIHTHOUR; //定时8小时
}
else if (PortValue == NINEHOUR)
{
return BACKNINEHOUR; //定时9小时
}
else if (PortValue == TENHOUR)
{
return BACKTENHOUR; //定时10小时
}
else if (PortValue == ELEVENHOUR)
{
return BACKELEVENHOUR; //定时11小时
}
else if (PortValue == TWELVEHOUR)
{
return BACKTWELVEHOUR; //定时12小时
}
else if (PortValue == THIRTHHOUR)
{
return BACKTHIRTHHOUR; //定时13小时
}
else if (PortValue == FOURTHHOUR)
{
return BACKFOURTHHOUR; //定时14小时
}
else if (PortValue == FIFTHHOUR)
{
return BACKFIFTHHOUR; //定时15小时
}
// return 0x00;
}
/*
*********************************************************************************************************
*
* 函数名称:void AdConvertResult(UBYTE channel)
*
* 输入变量:需要采样的模拟量的通道
*
* 输出变量:无
*
* 功能描述:获得需要采样的模拟量的数据
*
*********************************************************************************************************
*/
void AdConvertResult(UBYTE channel)
{
UBYTE i; //定义临时循环变量
if(channel) //通道值为真
{
CHS0 = 1; //选择通道1(充电电压值判定)采样
CHS1 = 0; //第一位通道选择位置零
CHS2 = 0; //第二位通道选择位置零
}
else //通道值为零通道
{
CHS0 = 0; //选择通道0(过流判定)采样
CHS1 = 0; //第一位通道选择位置零
CHS2 = 0; //第二位通道选择位置零
}
for (i = 0x00;i<0x10;i++) //采样16次用作数字简单滤波以求消除毛刺
{
GODONE = 1; //启动转换
while(GODONE); //等待转换结束
AdResult[i] = ADRES; //存储结果
}
}
/*
*********************************************************************************************************
*
* 函数名称:UBYTE SortAdConResult(void)
*
* 输入变量:采样的模拟量的数据
*
* 输出变量:滤波后实际使用的模拟量
*
* 功能描述:模拟量的数据软件滤波获得使用为判据的模拟量的数据(中值滤波)
*
*********************************************************************************************************
*/
UBYTE SortAdConResult(void)
{
UBYTE i,iflag; //定义临时循环变量
UBYTE AdSort,AdVer; //定义临时变量
UWORD AdVer1;
for (i=0;i<0x10;i++) //排序
{
for(iflag=i+1;iflag<0x10;iflag++)
{
if (AdResult[i] >= AdResult[iflag])
{
AdSort = AdResult[i];
AdResult[i] = AdResult[iflag];
AdResult[iflag] = AdSort;
}
}
}
AdVer1 = 0;
for(i=2;i<0x0d;i++)
{
AdVer1 += AdResult[i];
}
AdVer = AdVer1/0x0b; //结束排序取平均值
return AdVer; //返回平均值
}
/*
*********************************************************************************************************
*
* 函数名称:UBYTE DetectState(void)
*
* 输入变量:无
*
* 输出变量:各个不同的充放电状态
*
* 功能描述:充电控制--参考附带的说明文件表
*********************************************************************************************************
*/
UBYTE DetectState(void)
{
UBYTE bState; //定义状态变量
bState = 0; //初始状态变量
AdConvertResult(BATTCHECKCHANNEL); //电池电压采样
BATTERRYVOLTAGE = SortAdConResult(); //取最终电池电压
if(BATTERRYVOLTAGE > BATTCHARGEHIGH) //电池电压大于充电保护值28
{
bState |= 0x02; //状态位置位
}
else //电池电压小于充电保护值
{
bState &= 0xfd; //状态位清零
}
if(BATTERRYVOLTAGE > BATTCHARGELOW) //电池电压大于放电保护值22
{
bState &= 0xfb; //状态位清零
}
else //电池电压小于放电保护值
{
bState |= 0x04; //状态位置位
bOldState = 0x00; //第二天
}
AdConvertResult(OVERCURRENTCHANNEL); //过流电压采样
OCVOTLAGE = SortAdConResult(); //取最终过流电压
if(OCVOTLAGE > OVERCURRENTHIGH) //过流电压大于过流保护值(10A)
{
bState |= 0x08; //状态位置位
}
else //过流电压小于过流保护值(10A)
{
bState &= 0xf7; //状态位清零
}
// CHARGEOUT = 0; //RB6输出低电平3843输出触发脉宽最窄,充电电流为零。
SUNFLAG0 = RB5; //读取阳光检测电平信号
DelayTime(0xFFff,0xFFff);
DelayTime(0xFFff,0xFFff);
DelayTime(0xFFff,0xFFff);
DelayTime(0xFFff,0xFFff);
SUNFLAG1 = RB5; //读取阳光检测电平信号
SUNFLAG = SUNFLAG0&SUNFLAG1; //获得阳光检测电平信号
if(!SUNFLAG)
{
bState |= 0x01; //状态位置位
bOldState = 0x01; //第二天
}
else
{
bState &= 0xfe; //状态位清零
}
if(min >= TimeCheck()) //负载通电定时判别
{
bState |= 0x10; //状态位置位
bOldState = 0x00; //第二天
}
else
{
bState &= 0xef; //状态位清零
}
return bState;
}
/*
*********************************************************************************************************
*
* 函数名称:void main(void)
*
* 输入变量:无
*
* 输出变量:无
*
* 功能描述:主函数
*
*********************************************************************************************************
*/
void main(void)
{
// CLRWDT(); //禁止看门狗
// FOSC1 = 1; //振荡器模式选择位
// FOSC0 = 0;
// CONFIG_ADDR = 0x82; //HS振荡器>=4MHz
/////////////timer0 init//////////////////////////////////////
PSA = 0; //TIMER0预分频 1/256
PS2 = 1;
PS1 = 1;
PS0 = 1;
T0CS = 0; //选择内部指令周期时钟
TMR0 = 0x00; //选择TMR0寄存器清零
// TMR0IE=0; //TMR0 溢出使能关闭
T0IE = 0; //禁止TIMER0溢出中断
T0IF = 0; //TIMER0中断标志清零
/////////////timer1 init//////////////////////////////////////
T1CKPS1 = 1; //TIMER1预分频 1/8
T1CKPS0 = 1;
TMR1CS = 0; //使用内部时钟(FOSC/4)
TMR1H = 0x0b; //0x3c;
TMR1L = 0xdb; //0xaf; //预设时间寄存器初值
TMR1ON = 1; //TMR1 溢出使能
T1OSCEN = 0; //关闭振荡器
TMR1IE = 0; //允许TIMER1溢出中断
TMR1IF = 0; //TIMER1中断标志清零
/////////////timer2 init//////////////////////////////////////
T2CKPS1 = 1; //TIMER2预分频 1/16
T2CKPS0 = 1;
TMR2ON = 0; //TMR2关闭
TMR2IE = 0; //禁止中断
TMR2IF = 0; //TIMER2中断标志清零
////////////external init//////////////////////////////////////
INTE = 0; //不允许外部中断
// TXIE = 0; //发送中断屏蔽
// RCIE = 0; //接收中断屏蔽
RBIE = 0; //RB口电平中断屏蔽
CCP1IE = 0; //禁止CCP1 中断
INTF = 0; //外部中断标志清零
RBIF = 0; //RB口电平中断标志清零
CCP1IF = 0; //CCP1中断标志清零
/////////////ad convert init////////////////////////////////////
OVERCURRENT = INPUTDIRECT; //负载过流输入模拟量端口
BATTCHECK = INPUTDIRECT; //电池充电电压输入模拟量端口
ADCON1 = 0x00; //配置模拟引脚/ 参考电压
//PCFG2:PCFG0 AN3/RA3 AN2/RA2 AN1/RA1 AN0/RA0 VREF
// 0x0 A A A A VDD
ADCS1 = 0;
ADCS0 = 0; //A/D 转换时钟选择位FOSC/2
ADON = 1; //A/D 开启
ADIE = 0; //不允许AD转换中断
ADIF = 0; //AD转换中断标志清零
/////////////I/O PORT init////////////////////////////////////
LOADCONTROL = OUTPUTDIRECT; //负载控制输出
SUNCHECK = INPUTDIRECT; //阳光检测输入
CHARGECONTROL = OUTPUTDIRECT; //充电控制输出
CLKPRE0 = INPUTDIRECT; //时钟预定义第0位输入
CLKPRE1 = INPUTDIRECT; //时钟预定义第1位输入
CLKPRE2 = INPUTDIRECT; //时钟预定义第2位输入
CLKPRE3 = INPUTDIRECT; //时钟预定义第3位输入
////////////////////////////////////////////////////////////////////////////////
InitVariable(); //初始化变量
bOldState = 1; //第二天
PEIE = 1; //开放所有未被屏蔽的外设中断
GIE = 1; //使能所有未被屏蔽的中断
////////////////////////////////////////////////////////////////////////////////
while(1)
{
bNowState = DetectState(); //检测状态
switch(bNowState)
{
case 0x00:
case 0x02:
if(bOldState)
{
TMR1IE = 1; //启动定时
CHARGEOUT = 0; //RB6输出低电平3843输出触发脉宽最窄,充电电流为零。
LOADOUT = 0; //RB4输出低电平抬起负载触发电压,负载开通。
}
break;
case 0x01:
case 0x05:
case 0x0d:
case 0x11:
case 0x15:
case 0x19:
case 0x1b:
case 0x1d:
TMR1IE = 0; //关闭定时
LOADOUT = 1; //RB4输出高电平导走负载触发电压,负载切断。
sec = 0;
min = 0;
hour = 0;
CHARGEOUT = 1; //RB6输出高电平3843输出触发脉宽最宽,充电电流最大。
//CHARGEOUT = 0;
break;
case 0x08:
case 0x0a:
case 0x0c:
case 0x18:
case 0x1a:
case 0x1c:
TMR1IE = 0;
InitVariable();
break;
case 0x03:
case 0x04:
case 0x13:
case 0x14:
TMR1IE = 0;
InitVariable();
break;
default:
TMR1IE = 0;
InitVariable();
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -