/*
* 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)
-------------------------------------------------------------------------------------------------
有沒有大佬知道是哪兒的問題啊?
|