📄 sunpcontrol_main.c
字号:
#include "reg935.h"
#include <stdio.h> /* prototype declarations for I/O functions */
#define uchar unsigned char
#define uint unsigned int
#define LIGHT_VALUE_HIGH 0X1A //关灯的亮度阀值
#define LIGHT_VALUE_LOW 0X10 //开灯的亮度阀值
#define BATTER_VALUE_HIGH 0X81 //恢复放电阀值11
#define BATTER_VALUE_LOW 0X7B //过放电保护电压值,1
#define CHARG_OUT_HIGH 0X9E //过充断开电压14
#define CHARG_OUT_LOW 0X95 //充电开启阀值13.
#define OUT_PUT1 ICB //P2^0
#define OUT_PUT2 OCD //P2^1
#define OUT_PUT3 KB0 //P0^0
#define DIS_LED OCC //P1^7
#define CHARG_OUT ICA //P2^7
#define SENSE_IN OCA //P2^6
#define SD1 OCB //P1^6
#define SD2 XTAL1 //P3^1
#define SD3 XTAL2 //P3^0
#define SD4 INT1 //P1^4
#define SD5 INT0 //P1^3
#define SD6 T0 //P1^2
#define SD7 MOSI //P2^2
#define SD8 MISO //P2^3
void CommInit()
{
SCON = 0x52; /* initialize UART */
BRGR0 = 0x70; /* 9600 baud, 8 bit, no parity, 1 stop bit */
BRGR1 = 0x01;
BRGCON = 0x03;
}
void IOInit()
{
P0M1=0x0E; //P0.1和P0.2设置为仅为输入状态
P0M2=0x00;
P1M1=0x5C;
P1M2=0x00;
P2M1=0x0C; //P0端口设置为准双向
P2M2=0x00;
P3M1=0x03; //P0端口设置为准双向
P3M2=0x00;
}
void ADInit()
{
ADINS=0x70; //0111 0000, 选择channel
ADMODA=0x10; //0001 0000, 选择转换工作模式:AD1单次转换模式
ADMODB=0x00; //500Khz < ADC CLK < 3.3Mhz,,
}
void TimerInit()
{
TH0 = 0X70;
TL0 = 0X09;
TMOD = 0X01;
TR0 = 1;
ET0 = 1;
}
void WDInit()
{
EA = 0;
// WDCON |= 0x04;
WDL = 0xff;
WFEED1 = 0xa5;
WFEED2 = 0x5a;
}
void Delay(uint time_out)
{
uint i;
while(time_out--)
for(i=0;i<300;i++);
}
void DeviceInit()
{
CommInit();
IOInit();
ADInit();
TimerInit();
Delay(500);
WDInit();
EA = 1;
}
static uchar clock_time_10ms,clock_time_1s,clock_time_1m,clock_time_1h;
static uint time_10ms,dis_time;
static uchar led_mode;
void TimeInter() interrupt 1
{
TH0 =0x70;
TL0 =0x09;
time_10ms++;
if(!led_mode)
DIS_LED = 1;
else if(led_mode == 1)
DIS_LED = 0;
else if(led_mode == 2 && time_10ms - dis_time >=30)
{
dis_time = time_10ms;
DIS_LED = !DIS_LED;
}
else if(led_mode == 3 && time_10ms - dis_time >=100)
{
dis_time = time_10ms;
DIS_LED = !DIS_LED;
}
clock_time_10ms++;
if(clock_time_10ms>99)
{
clock_time_10ms = 0;
clock_time_1s++;
if(clock_time_1s>59)
{
clock_time_1s = 0;
clock_time_1m++;
if(clock_time_1m>59)
{
clock_time_1m = 0;
clock_time_1h++;
}
}
}
}
uchar BatterVolGet()
{
static uchar battervoltage[10],bv_len,i;
uchar temp_value;
uint add_buf;
if(bv_len >=10)
bv_len = 0;
ADCON1=0x05; //选择转换触发模式;并立即启动
battervoltage[bv_len++] = AD1DAT0; //将AD转换获得的数据存入result
ADCON1&=0xF7; //清除中断完成标志
add_buf = 0;
for(i=0;i<10;i++)
add_buf =add_buf+battervoltage[i];
temp_value = add_buf/10;
printf("电池电压值是= %fV ",(float)(temp_value*0.0913));
return temp_value;
}
uchar IrfVolGet()
{
static uchar Irfvoltage[10],bv_len,i;
uchar temp_value;
uint add_buf;
if(bv_len >=10)
bv_len = 0;
ADCON1=0x05; //选择转换触发模式;并立即启动
Irfvoltage[bv_len++] = AD1DAT1; //将AD转换获得的数据存入result
ADCON1&=0xF7; //清除中断完成标志
add_buf = 0;
for(i=0;i<10;i++)
add_buf =add_buf+Irfvoltage[i];
temp_value = add_buf/10;
// printf("IRF电压值是= %fV ",(float)(temp_value*0.0913));
return temp_value;
}
uchar SolarVolGet()
{
static uchar solarvoltage[10],bv_len,i;
uchar temp_value;
uint add_buf;
if(bv_len >=10)
bv_len = 0;
ADCON1=0x05; //选择转换触发模式;并立即启动
solarvoltage[bv_len++]=AD1DAT2; //将AD转换获得的数据存入result
ADCON1&=0xF7; //清除中断完成标志
add_buf = 0;
for(i=0;i<10;i++)
add_buf =add_buf+solarvoltage[i];
temp_value = add_buf/10;
printf("太阳能电池值是= %fV \n",(float)(temp_value*0.0913));
return temp_value;
}
bit DayAndNightCheck(uchar temp_value)
{
static bit is_state;
if((temp_value < LIGHT_VALUE_LOW) && is_state)
is_state = 0;
else if((temp_value > LIGHT_VALUE_HIGH) && !is_state)
is_state = 1;
return is_state;
}
void CLRWD()
{
EA = 0;
WFEED1 = 0xa5;
WFEED2 = 0x5a;
EA = 1;
}
void ChargControl(uchar battervoltage,uchar solarvoltage)
{
if((battervoltage < CHARG_OUT_LOW) && (solarvoltage >= battervoltage) && CHARG_OUT)
{
CHARG_OUT = 0;
led_mode = 3;
}
else if(((battervoltage >= CHARG_OUT_HIGH) || (solarvoltage < battervoltage)) && !CHARG_OUT)
{
CHARG_OUT = 1;
led_mode = 0;
}
}
uchar TimerLen()
{
uchar time_len;
time_len = 0;
if(!SD1)
time_len += 1;
if(!SD2)
time_len += 2;
if(!SD3)
time_len += 3;
if(!SD4)
time_len += 4;
if(!time_len)
time_len = 1;
// printf ("定时时间 = %d ",(int)time_len);
return time_len;
}
//
bit SenserIn()
{
static bit last_state;
if(SENSE_IN != last_state)
last_state = SENSE_IN;
else
{
// printf ("传感器 = %d ",(int)last_state);
return last_state;
}
return 1;
}
void OutControl(uchar out_put_value)
{
if(out_put_value == 0)
{
OUT_PUT3 = 1;
OUT_PUT2 = 1;
OUT_PUT1 = 1;
}
if(out_put_value & 0x01)
OUT_PUT1 = 0;
if((out_put_value & 0x02))
OUT_PUT2 = 0;
else
OUT_PUT2 = 1;
if((out_put_value & 0x04))
OUT_PUT3 = 0;
else
OUT_PUT3 = 1;
}
bit is_daytime_or_night; //1:表示白天,0:表示夜晚
bit is_batter_low; //1:电池正常,0:电池欠压
bit is_sense_in;
static uchar solarvoltage; //太阳能电池电压
static uchar battervoltage; //蓄电池电压
static uchar out_put_value; //输出状态
static uchar is_light_state; //1:表示点灯状态,0:表示熄灯状态(包括白天熄灯和过放电熄灯)
static uchar delay_len;
uchar SaveAndRead(uchar eeprom_value,bit is_save)
{
if(is_save)
{
printf("写入标志值= %d \n",(int)eeprom_value);
DEECON=0x00; //初始化DEECON
DEEDAT=eeprom_value; //赋值DEEDAT
DEEADR=0x10; //赋值DEEADR
while((DEECON&0x80)==0); //等待写完成
DEECON=DEECON&0x7F; //清0写完成标志位
}
DEECON=0x00; //初始化DEECON
DEEADR=0x10; //赋值DEEADR
while((DEECON&0x80)==0); //等待
eeprom_value=DEEDAT; //将读出的值赋给Temp
return eeprom_value;
}
main()
{
uint last_second,last_minute,sense_delay_time,i,j;
DeviceInit();
printf ("Program is Starting\n");
is_batter_low = 1;
SaveAndRead(1,1);
// printf ("eeprom_value = %d\n",(int)SaveAndRead(0xff,0));
for(i=0;i<20;i++)
{
for(j=0;j<1000;j++);
is_sense_in = SenserIn();
battervoltage = BatterVolGet();
IrfVolGet();
solarvoltage = SolarVolGet();
delay_len = TimerLen();
}
printf("定时时间 = %d ,LED显示模式= %d ,电池欠压情况= %d , 输出状态= %d \n",(int)delay_len,(int)led_mode,(int)is_batter_low,(int)out_put_value);
while(1)
{
CLRWD();
if(last_second != clock_time_1s)
{
delay_len = TimerLen();
is_sense_in = SenserIn();
// printf("LED显示模式= %d ,电池欠压情况= %d ,延时时间状况= %d , 输出状态= %d ",(int)led_mode,(int)is_batter_low,(int)clock_time_1h,(int)out_put_value);
last_second = clock_time_1s;
battervoltage = BatterVolGet();
// IrfVolGet();
solarvoltage = SolarVolGet();
}
is_daytime_or_night = DayAndNightCheck(solarvoltage);
if(is_daytime_or_night) //判断是否白天
{
if(battervoltage >= BATTER_VALUE_HIGH && !is_batter_low)//判断电池电压是否正常
{
printf ("电池电压正常,");
is_batter_low = 1;
}
if(out_put_value || SaveAndRead(0xff,0))
{
printf ("已经天亮,关闭所有输出\n");
SaveAndRead(0,1);
out_put_value = 0; //关闭输出
led_mode = 0; //指示灯显示关闭状态
}
last_minute = clock_time_1m = clock_time_1h = 0;
}else
{
if(battervoltage < BATTER_VALUE_LOW && is_batter_low) //判断电池电压是否过低
{
printf ("电池电压过低,进入电池欠压状态\n");
SaveAndRead(1,1);
is_batter_low = 0;
}
if(is_batter_low) //电池是否欠压
{
if(!out_put_value && !SaveAndRead(0xff,0))
{
printf ("已经天黑,打开光控输出\n");
out_put_value |= 0x01;
led_mode = 1;
}
if(clock_time_1h < delay_len && !(out_put_value & 0x02) && !SaveAndRead(0xff,0))
{
printf ("打开时间控制输出\n");
out_put_value |= 0x02;
}
else if(clock_time_1h >= delay_len && (out_put_value & 0x02))
{
printf ("关闭时间控制输出\n");
SaveAndRead(1,1);
out_put_value &= 0xFD;
}
if(!is_sense_in)
{
sense_delay_time = clock_time_1m;
if(!(out_put_value & 0x04))
{
printf ("打开传感器控制输出\n");
out_put_value |= 0x04;
}
}
else
{
if(clock_time_1m - sense_delay_time >1 && (out_put_value & 0x04))
{
printf ("关闭传感器控制输出\n");
out_put_value &= 0xFB;
}
}
}else
{
if(out_put_value)
{
printf ("电池欠压,关闭所有输出\n");
out_put_value = 0; //关闭输出
led_mode = 2; //指示灯显示电池过放电状态
}
}
}
ChargControl(battervoltage,solarvoltage); //充电控制
OutControl(out_put_value);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -