|
/*
* File: adcshili.c
* Author: Administrator
*
* Created on 2024年1月5日, 上午9:24
*/
//#include <stdio.h>
//#include <stdlib.h>
/*
*
*/
/*
int main(int argc, char** argv) {
return (EXIT_SUCCESS);
}
*/
# include <xc.h>
#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSC oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)INTOSC 振荡器, RA4、RA5为IO口
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)看门狗开
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)上电复位开
#pragma config MCLRE = OFF // RA3/MCLR pin function select (RA3/MCLR pin function is digital I/O, MCLR internally tied to VDD)RA3/MCLR引脚功能为MCLR
#pragma config BOREN = OFF // Brown-out Detect Enable bit (BOD enabled)欠压检测功能关
#pragma config CP = OFF // Code Protection bit (Program Memory code protection is disabled)程序存储器代码保护被禁用
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)数据代码保护关
//__ CONFIG(0X31A4);
__EEPROM_DATA(5,50,67,6,5,0,0,0); //0X00第一位表示定时倍数;0X01第二位表示最低电压-低;0X02第三位表示最高电压-高;0X03第四位表示清虫天数记录;0X04第五位表示清虫天数预设;0X05第五位表示为0铅酸电池(最低不能低于2点几V)、为1锂电池(最高不能超过12.6V);0X06空;0X07空
#define uchar unsigned char
#define uint unsigned int
uint count;
uint AN2_val; //存放AN2通道模拟转换的值
uint AN4_val; //存放AN4通道模拟转换的值
uchar i = 0;
uchar j = 0;
uint yanshi;
uchar AN2_num1;
uchar AN2_num2;
uchar AN2_num3;
uchar AN4_num1;
uchar AN4_num2;
uchar AN4_num3;
uchar AN4_num4;
uchar yukon_num1;
uchar yukon_num2;
uint anjian_num1;
uchar anjian_num2;
uchar n;
uint num;
uchar daochon_num;
uint h;
uchar day; //0为白天,1为晚上
uchar fuzhai=1; //负载开启
uchar chondian; //0为充电完成,1为充电未完成,继续充电
uchar taiyangban; //1为太阳板电压高于电池,0为太阳板电压低于电池
uchar ONOFF=1; //放电到充电一循环,1开启,0关闭
uchar qingchontianshu;
uchar k;
uchar a=6;
uchar t;
uchar z=0;
uchar m;
void init1()
{
TRISA = 0b00110100; //设置RA输入输出端口 RA2,RA4,RA5(AN2、AN3)为输入,其他输出
TRISC = 0b00010011; //设置RC输入输出端口 RC0、RC1、RC4(AN4、AN5)为输入,其他输出
PORTA = 0b00000000; //设置A端口输出为低电平
PORTC = 0b00000000; //设置C端口输出为低电平
ANSEL = 0X14; //ANS4=1,ANS2=1;AN4和AN2为模拟输入 二进制00010100
CM2 = 1; //CM2:CM0:111 比较器模式位(关闭)
CM1 = 1;
CM0 = 1;
ADCON1 = 0X10; //ADCS<2:0>:A/D 转换时钟源选择位 0011 =FOSC/8 4MHz频率 二进制00010000
}
void ADAN2() //对RA2(AN2)进行A/D模拟转换输入
{
for (i=0; i<20; i++)
{
ADCON0 = 0X09; //二进制0000 1001 (bit7:0 左对齐,bit6:0 参考电压VDD, bit5:0 未用, bit4-bit2:010 通道02(AN2), bit1:0 A/D转换结束/未进行, bit0:(ADON)1 A/D转换模块正在工作) A/D 控制寄存器
asm("NOP"); //稍微延时
asm("NOP");
asm("NOP");
asm("NOP");
GO_DONE = 1; //1 = A/D 转换正在进行。该位置 1 将启动 A/D 转换。 在转换结束后该位将被硬件自动清零。 ADCON0 _ A/D 控制寄存器
while (GO_DONE) //循环检测GO_DONE是否为0,为0转换结束
{
continue;
}
AN2_val + = ADRESH; //将左对齐后的20次结果赋值
}
AN2_val = AN2_val/20; //取20次检测电压的平均值
ADON = 0; //A/D转换模块结束
if (AN2_val < eeprom_read(0X01)) //读写寄存器__EEPROM_DATA(5,50,67,6,5,0,0,0)中第二位,电源电压为10.8v时,电路分压后测出AN2电压为:0.98v (5v是参考电压,一个数值代表多少电压:5/1024=0.00448,如果输入电压为0.98v,0.98/0.00448=218.75)
{
AN2_num1++;
if(AN2_num1 > 20) //(超过20次电压低于10.8v)
{
AN2_num1 = 0; //计数清0
fuzhai = 0; //负载未开启工作
}
}
else
{
AN2_num1 = 0; //清0
}
if (AN2_val > eeprom_read(0X02)) //读写寄存器__EEPROM_DATA(5,50,67,6,5,0,0,0)中第三位,电源电压为14.4v时,电路分压后测出AN2电压为:1.31v (如果输入电压为1.31v,1.31/0.00448=292.41)
{
AN2_num2++;
if(AN2_num2++ > 20) //(超过20次电压高于14.4v)
{
AN2_num2 = 0; //计数清0
chondian = 0; //充电完成
}
}
else
{
AN2_num3++; //计数自增
if (AN2_num3 > 20) //(超过20次电压低于14.4v)
{
AN2_num3 = 0; //计数清0
chondian = 1; //充电未完成,继续充电
}
}
}
void ADAN4() //对RC0(AN4)进行A/D模拟转换输入
{
for (j=0; j<20; j++)
{
ADCON0 = 0X11; //二进制0000 1001 (bit7:0 左对齐,bit6:0 参考电压VDD, bit5:0 未用, bit4-bit2:100 通道04(AN4), bit1:0 A/D转换结束/未进行, bit0:(ADON)1 A/D转换模块正在工作) A/D 控制寄存器
asm("NOP"); //稍微延时
asm("NOP");
asm("NOP");
asm("NOP");
GO_DONE = 1; //1 = A/D 转换正在进行。该位置 1 将启动 A/D 转换。 在转换结束后该位将被硬件自动清零。 ADCON0 _ A/D 控制寄存器
while (GO_DONE) //循环检测GO_DONE是否为0,为0转换结束
{
continue;
}
AN4_val + = ADRESH; //将左对齐后的20次结果赋值
}
AN4_val = AN4_val/20; //取20次检测电压的平均值
ADON = 0; //A/D转换模块结束
if(AN2_val - AN4_val < 13) //连续检测20次太阳板比铅酸电池或锂电池低于3V (晚上)
{
AN4_num1++;
if (AN4_num1 > 20) //(超过20次太阳板电压比电源电压低于3v)
{
AN4_num1 = 0; //计数清0
day = 1; //晚上
}
}
else
{
AN4_num1 = 0;
}
if (AN2_val - AN4_val > 23) //连续检测20次太阳板高于5.5V的铅酸电池或锂电池 (白天)
{
AN4_num2++;
if (AN4_num2 > 20) //(超过20次太阳板电压比电源电压高于5.5v)
{
AN4_num2 = 0;
day = 0; //白天
}
}
else
{
AN4_num2 = 0;
}
if (AN4_val < 0b00000011) //连续检测20次太阳板电压高于电池电压,开始充电,连续检测20次太阳板电压低于电池电压,不充电
{
AN4_num3++;
if (AN4_num3 > 20) //连续检测20次太阳板电压高于电池电压
{
AN4_num3 = 0; //计数清零
taiyangban = 1; //1为太阳板电压高于电池
fuzhai = 1; //负载工作开启
ONOFF=1; //放电到充电一循环,开启
}
}
else
{
AN4_num4++;
if (AN4_num4 > 20) //连续检测20次太阳板电压低于电池电压
{
AN4_num4 = 0; //计数清零
taiyangban = 0; //0为太阳板电压低于电池
}
}
}
void kaijishansuo() //开机闪烁5次
{
if (yanshi > 3906) //1s溢出
{
yanshi = 0;
if (z == 0)
z = 1;
else
z = 0;
a--;
}
}
void condianshansuo() //充电连续闪烁
{
if (yanshi > 3906) //1s溢出
{
yanshi = 0;
if (z == 0)
z = 1;
else
z = 0;
}
}
void panduan () //转换后的数据判断,定义是否需要开灯、充电、雨控等待
{
if (fuzhai == 1) //负载开启
{
if (day == 1) //晚上
{
if (ONOFF==1) //放电到充电一循环,开启
{
TMR1ON=1; //中断TMR1开启,开始计时
if (RC1 == 0) //雨控控制,0为雨控检测无雨,短接帽断路
{
yukon_num1++;
if (yukon_num1 > 20) //检测超过20次没有雨
{
yukon_num1 = 0; //计数清0
RC2 = 1; //没有雨水,继电器启动
}
}
else //雨控控制,0为雨控检测有雨,短接帽连通,将5v电压拉到RC1引脚
{
yukon_num2++;
if (yukon_num2 > 20) //检测超过20次有雨
{
yukon_num2 = 0; //计数清0
RC2 = 0; //下雨,继电器关闭
}
}
}
else
{
RC2 = 0; //未实现放电到充电的循环,继电器关闭,负载未启动
}
}
else
{
RC2 = 0; //白天继电器关闭,负载未启动
}
}
else
{
RC2 = 0; //继电器关闭,负载未启动
}
if (chondian == 1) //1为充电未完成,继续充电
{
if (taiyangban == 1) //1为太阳板电压高于电池
{
RC1 = 1; //RC3高电平,电源模块充电,太阳板给电池充电
if (num > 0)
num = 0; //定时清0
if (h > 0)
h = 0;
condianshansuo(); ////充电蓝灯闪烁
}
else
{
RC3 = 0; //充电完成,RC3低电平,电源模块不充电
if (a < 1) //蓝灯不闪烁
z = 0; //RA0=0
}
}
else
{
RC3 = 0; //充电完成,RC3低电平,电源模块不充电
if (a < 1) //蓝灯不闪烁
z = 0; //RA0=0
}
}
void anxia()
{
anjian_num1++;
if (anjian_num1 > 7200)
{
anjian_num1 = 0;
anjian_num2++; //增加一小时(定时数据)
a = 2; //蓝灯闪烁一次
k = 1; //有未写入数据
}
}
void sonkai()
{
if(k == 1)
{
eeprom_write(0x04,anjian_num2); //把anjian_num2写到地址0x04
qingchontianshu = anjian_num2; //清除定时时间
k = 0; //没有未写入数据
anjian_num1 = 0;
anjian_num2 = 0; //清除定时数据
}
if(t == 1) //开始读定时时间
{
if (a < 1) //蓝灯不闪烁的时候
{
if (anjian_num2 > 0) //定时时间大于0
{
anjian_num1++;
if (anjian_num1 > 7200) //延时7200
{
if (anjian_num1%2000 == 0)
{
anjian_num2--; //减去一次已显示的
a = 2; //蓝灯闪烁一次
}
}
}
else
{
t = 0; //读定时时间控制位清除
anjian_num1; //延时清零
}
}
}
else
{
if ( anjian_num1>20 && anjian_num1<40) //短按10s-20s之间,可以开始读定时间t=1
{
a = 6; //开始读蓝灯闪烁5次
t = 1; //开始读定时时间
anjian_num2 = eeprom_read(0x04); //从内存读取定时数据
}
anjian_num1 = 0; //延时清零
}
}
void shezhi() //设置定时时间
{
if (RC4 == 0) //按键按下
anxia();
else //按键松开
sonkai();
}
void init2 ()
{
T0CS = 0; //Timer0使用内部时钟 OPTION_REG _ 选择寄存器
PSA=1; //将预分频器给看门狗WDT OPTION_REG _ 选择寄存器
TMR0=0x00; //定时器
T0IF=1; //Timer0 启动控制位使能(0关闭)(标志位) INTCON _ 中断控制寄存器
T0IE=1; //Timer0中断开启(使能位) INTCON _ 中断控制寄存器
TMR1CS = 0; //Timer1使用内部时钟 Timer1 控制寄存器
T1CKPS0=1; //1:8倍预分频比 Timer1 控制寄存器 T1CKPS1:T1CKPS0:11=1:8倍预分频比
T1CKPS1=1; //1:8倍预分频比 Timer1 控制寄存器
//TMR1H=(65536-(500000/8))/256; //初始化TMR1的高八位初始值 0.5s中断溢出一次
//TMR1L=(65536-(500000/8))%256; //初始化TMR1的低八位初始值
TMR1H=0x0B; //高八位置初始值
TMR1L=0xDC; //低八位置初始值
TMR1ON=0; //Timer1 启动控制位使能(0关闭) Timer1 控制寄存器
TMR1IF=0; //中断标志位清零 外设中断标志寄存器 1
TMR1IE=1; //Timer1中断开启 外设中断使能寄存器 1
PEIE=1; //外部中断开启 INTCON ? 中断控制寄存器
GIE=1; //全局中断开启 INTCON ? 中断控制寄存器
}
void daochon(); //倒虫,函数声明
void interrupt time0()
{
if (TMR1IF == 1)
{
TMR1IF=0; //中断标志溢出清0
//TMR1H=(65536-(500000/8))/256; //初始化TMR1的高八位初始值
//TMR1L=(65536-(500000/8))%256; //初始化TMR1的低八位初始值
TMR1H=0x0B; //高八位置初始值
TMR1L=0xDC; //低八位置初始值
num++;
if (num == 7200) //定时计时1一个小时溢出
{
h++; //每小时自增
num = 0; //溢出清0
if (h == 1)
{
count = eeprom_read(0x03); //清虫天数计数+1天
eeprom_write(0x03, count + 1);
}
if (h == 5) //等于设定的小时
{
h = 0; //小时清零
RC2 = 0; //继电器/负载关闭
ONOFF=0; //放电到充电一循环,时间到置0,关闭
TMR1ON=0; //Timer1 启动控制位使能(0关闭)
}
}
}
if (T0IF == 1) //1 = TMR0 寄存器溢出 (必须在软件中清除) 0 = TMR0 寄存器没有溢出
{
T0IF = 0; //tmr0溢出清零
yanshi++;
TMR0=0x00;
n++;
if (n > 200) //1s/256us=3906.25,1秒溢出
{
n = 0; //溢出清0
ADAN2(); //读AD转化口RA2/AN2
ADAN4(); //读AD转化口RC0/AN4
panduan (); //转换后的数据判断,定义是否需要开灯、充电、雨控等待
if (eeprom_read(0x03)>=qingchontianshu && TMR1ON==1) //读清虫设定天数2天的时候 ?????
daochon(); //倒虫
}
if (a > 0)
kaijishansuo(); //开机蓝灯闪烁5次
if (z == 1)
RA0 = 1; //蓝灯闪烁
else
RA0 = 0;
shezhi(); //设置定时时间
}
}
void dianchi() //每次开机判断所使用的电池,和读入定时时间
{
if (RA4 == 0 ) ////RA4口为低时是用蓄电池
{
if (eeprom_read(0x05)==1) //如果RA4口为蓄电池,控制位为1时,就写入蓄电池的数据
{
eeprom_write(0x01,50); //最低电压
eeprom_write(0x02,67); //最高电压
eeprom_write(0x05,0); //标记为蓄电池 ????
}
}
else //RA4口为高时是用锂电池
{
if (eeprom_read(0x05)==0) //如果RA4口为锂电池,控制位为0时,就写入锂电池的数据
{
eeprom_write(0x01,43); //最低电压(41)
eeprom_write(0x02,58); //最高电压
eeprom_write(0x05,1); //标记为锂电池 ???
}
}
qingchontianshu = eeprom_read(0x04); //(预计青虫天数为5天一次)
if(eeprom_read(0x03) <= qingchontianshu) //(判断清除天数几天一次)
eeprom_write(0x03,6); //(将清虫天数记录设为6天一次)
}
void daochon() //倒虫
{
if (RC5 == 0)
RC5 = 1;
if (RC5 == 1 && RA5 == 0)
m = 1; //(步骤控制)
if (RC5 == 1 && RA5 == 1 && m == 1)
{
daochon_num++; //倒虫天数增加
m = 0;
}
if (daochon_num >= 2) //超过两天清一次虫
{
daochon_num = 0; //清0
RC5 = 0;
eeprom_write(0x03,0);
}
}
void main ()
{
init1(); //通道初始化
init2 (); //定时器初始化
dianchi(); //电池选择
daochon(); //倒虫
while (1) //死循环
{
}
}
----------------------------------------------------------------------------------------
以上是我写的代码,可是编译时出现以下报错
:: warning: (1273) Omniscient Code Generation not available in Free mode
adcshili.c:421: warning: (752) conversion to shorter data type
D:\XC8\sources\common\lwdiv.c:31: error: (1358) no space for _eeprom_read temps (1)
(908) exit status = 1
nbproject/Makefile-default.mk:131: recipe for target 'dist/default/production/ADCshili.X.production.hex' failed
make[2]: Leaving directory 'D:/MPLAB X IDE v4.05��Ŀ/ADCshili.X'
nbproject/Makefile-default.mk:90: recipe for target '.build-conf' failed
make[1]: Leaving directory 'D:/MPLAB X IDE v4.05��Ŀ/ADCshili.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make[2]: *** [dist/default/production/ADCshili.X.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
编译已失败 (退出值2, 总时间: 1s)
-------------------------------------------------------------------------------------------------
有没有大佬知道是哪儿的问题啊?
|
|