找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 679|回复: 4
打印 上一主题 下一主题
收起左侧

有没有大佬知道eeprom寄存器为什么会报错提示内存空间不足

[复制链接]
跳转到指定楼层
楼主
/*
* 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)

-------------------------------------------------------------------------------------------------
有没有大佬知道是哪儿的问题啊?

1.jpg.png (54.53 KB, 下载次数: 76)

1.jpg.png
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:883242 发表于 2024-1-11 20:29 | 只看该作者
没有为你的单片机指定eeprom地址空间。
回复

使用道具 举报

板凳
ID:1107532 发表于 2024-1-12 08:04 | 只看该作者
Hephaestus 发表于 2024-1-11 20:29
没有为你的单片机指定eeprom地址空间。

__EEPROM_DATA(5,50,67,6,5,0,0,0);
大佬,这条语句不是指定eeprom的地址空间吗
回复

使用道具 举报

地板
ID:1057978 发表于 2024-1-12 08:45 | 只看该作者
Omniscient Code Generation的首字母组合起来就是OCG,这是PICC宣传的一种高效率编译模式,这个模式只有在收费的PRO版本中才支持,非OCG模式下编译出来的代码优化不够,比较大,编译器的全知代码生成在免费版中不可用。仅影响编译器的优化性能。
no space for _eeprom_read temps:内存不足的问题,提示芯片空间不足,flash够大,就是需要用到的ram不够了,导致数据放不到ram中报空间不足。解决办法:增加RAM分配空间,直到编译通过
回复

使用道具 举报

5#
ID:1107532 发表于 2024-1-12 17:06 | 只看该作者
wangxiangtan 发表于 2024-1-12 08:45
Omniscient Code Generation的首字母组合起来就是OCG,这是PICC宣传的一种高效率编译模式,这个模式只有在 ...

大佬,代码可以实现解决这个问题吗
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表