打印

PIC16F676编译错误

[复制链接]
8320|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Hezhiqiang|  楼主 | 2011-1-27 17:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
Error   [1250] X:\project\02-Normal\electron\Test file\Test-1\Firmware\Main_ac\init.c; 28. could not find space (2 bytes) for variable _delay_time
#include<pic.h>          //头文件
#include<pic16630.h>        //头文件
#include"define.h"         //定义头文件
#include"function.h"        //函数头文件
__CONFIG(INTOSCIO&WDTDIS&PWRTEN&MCLRDIS&BOREN&CPD&BGHIGH);//单片机配置位设置:8M,MCLR
//*******************各函数声明,变量声明************//
unsigned int adres=0,delay_time=0;  //外部引用函数==这个有问题,屏蔽就好啦
unsigned char intcon_t;
//**************中断服务程序************************//
//void interrupt counter(void)
{   if(T0IF) {TMR0=9;T0IF=0;if(delay_time) delay_time--;}
if(TMR1IF)
{ if(!lcd_s) timer_show();     //时间显示处理
  else {TMR1IF=0; TMR1H=0x3C;TMR1L=0xB0;timer++;}
}            //延时减1        
if(!STA) {while(!STA); WDTCON=1;}
}

这是什么意思,真的没看明白,这行
沙发
庄庄| | 2011-1-27 17:20 | 只看该作者
可能是由于RAM空间太小了,你定义变量占用空间太多了

建议:仔细看看datasheet关于空间管理部分

使用特权

评论回复
板凳
Hezhiqiang|  楼主 | 2011-1-28 08:24 | 只看该作者
我就声明了两个变量,别的都屏蔽啦

使用特权

评论回复
地板
yewuyi| | 2011-1-28 08:43 | 只看该作者
提示在init.c中存在错误,错误在第 28行,错误原因: could not find space (2 bytes) for variable _delay_time


你的中断函数写得比较惨,建议买本张明峰先生的那本《PIC单片机入门与实战》,仔细阅读10次等基础知识都有了解后再动手写代码。

使用特权

评论回复
5
Hezhiqiang|  楼主 | 2011-1-28 11:02 | 只看该作者
本帖最后由 Hezhiqiang 于 2011-1-28 11:15 编辑

这是init程序,你说的我清楚,中断函数你仔细看过啦,能帮我说下哪个地方有不合的地方麻,我把我的全部程序贴出来,这是PIC16F887!以下是我去年已经调试OK的程序!现在产品已经一年多啦,硬件和软件还是比较稳定的!现在我只是把这个程序COPY到我现在PIC16F676上来然后做些修改就发生上面的那些情况!就不知道是什么原因
//各寄存器初始化
#include<pic.h>                                                                //头文件
#include<pic16f887.h>                                                //PIC头文件
#include"define.h"                                                        //定义头文件        
#include"function.h"                                                //函数头文件
//*******************各函数声明,变量声明*****//
extern unsigned int adres,delay_time;                //引用外部函数COPY过去的就是这里有问题
extern unsigned char intcon_t;
union ad_res                                                                //使用一个共用体将AD结果组合
{        unsigned int         v1;
        unsigned char adres1[2];
}adr;
//*************寄存器配置,引角设置*********//
void init()
{        OSCCON=0B01110110;                                    //8M时钟
        CM1CON0=0b0;                                                        //关闭比较器1
        CM2CON0=0b0;                                                        //关闭比较器2
        ADCON0=0b10000001;                                                //启动AD模块,8M时钟,4uS,32分频
        ADCON1=0b10000000;                                                //右对起
        ANSEL =0b00001111;
        ANSELH=0b00001000;            
        INTCON=0b00000000;                                                //中断,TMR0中断允许
        OPTION=0b00000010;                                                //TMR0分频=8
        WPUB=0b0;                                                                //开启部分弱上接
        IOCB=0b0;                                                                //电平变化中断禁止
        TRISA=0b00001111;   
        TRISB=0b10010101;
        TRISC=0b00000000;
        TRISD=0b00000000;
        TRISE=0b00001000;  
        PORTA=0b00010000;
        PORTB=0b01100000;
        PORTC=0b0;
        PORTD=0b0;
        PORTE=0b1000;                                                        //LCD背光打开
        T1CON=0b00100001;                                                //使能TMR1=1:4
        PIE1=0x00000001;                                                //允许TMR1中断
        PIE2=0x0;
        WDTCON=0;
        delay_ms(100);
        
        if(!(PCON&0b00000010))
        {
        lcd_write_comd(0b00111000);                                //双行显示,8位模式,5*7
        delay_ms(10);                                                        
        lcd_write_comd(0b00001111);                                //显示功能开,光标开,闪烁开
        lcd_write_comd(0b00000101);                                //右移,屏幕移动
        lcd_write_comd(0b00011000);                                //右移,AC加1
        lcd_write_comd(0b00000001);                                //清屏
        delay_ms(15);
        lcd_write_curs(0x90);
        lcd_write_char_delay("If you have any ");
        delay_ms(2000);
        lcd_write_char_delay("question");
        delay_ms(2000);
        lcd_write_comd(0b00000110);                                //右移,屏幕不移动
        lcd_write_comd(0b00010100);                                //右移,AC加1
        lcd_write_comd(0b00000001);                                //清屏
        delay_ms(15);
        lcd_write_char_delay("Call me James he");
        lcd_write_curs(0xc0);
        lcd_write_char_delay("Tel:633459");
        delay_ms(2000);        
        }
        PCON=0B00000011;        
}
//*************电压信号发送*****************//
void all_voltage(unsigned char b,unsigned int vol)
{        unsigned char bits[8],vol_n,count,start,end,data;
        union bits_decompound                                        //使用一个共用体分解各位
        {        struct bits_decom
                {        unsigned b0 : 1 ;
                        unsigned b1 : 1 ;
                        unsigned b2 : 1 ;
                        unsigned b3 : 1 ;
                        unsigned b4 : 1 ;
                        unsigned b5 : 1 ;
                        unsigned b6 : 1 ;
                        unsigned b7 : 1 ;
                }one;
                unsigned char all;
        }bt;
        intcon_t=INTCON;
        INTCON=0;
        bt.all=vol/25;                                                        //将电压值25mv分频        
        switch(b)
        {        case 1 : vol_n=0b00001000; break;        //b1电压单独输出
                case 2 : vol_n=0b00010000; break;        //b2电压单独输出
                case 3 : vol_n=0b00100000; break;        //b3电压单独输出
                case 4 : vol_n=0b01000000; break;        //b4电压单独输出
                case 5 : vol_n=0b10000000; break;        //b5电压单独输出
                case 6 : vol_n=0b11111000; break;        //all电压输出
        }
        bits[0]=(bt.one.b0==1)? 0xff : 0x07;        //各位数据判断
        bits[1]=(bt.one.b1==1)? 0xff : 0x07;
        bits[2]=(bt.one.b2==1)? 0xff : 0x07;
        bits[3]=(bt.one.b3==1)? 0xff : 0x07;
        bits[4]=(bt.one.b4==1)? 0xff : 0x07;
        bits[5]=(bt.one.b5==1)? 0xff : 0x07;
        bits[6]=(bt.one.b6==1)? 0xff : 0x07;
        bits[7]=(bt.one.b7==1)? 0xff : 0x07;
        for(count=0;count<8;count++)
        {        start=vol_n|PORTC;                                        //起始信号的值
                data=(vol_n|PORTC)&bits[count];                //数据信号的值
                end=PORTC&0x07;                                                //结束信号的值
                PORTC=start;                                                //起始信号
                delay_us(5*br);
                PORTC=data;                                                        //数据信号
                delay_us(10*br);
                PORTC=end;                                                        //结束信号
                delay_us(10*br);        
        }
        INTCON=intcon_t;
}
//*************充电信号发送*****************//
void cd_send(unsigned char cd,unsigned char cd_data)//最高位,1打开,0关闭
{        unsigned char bits[8],cd_s,count,start,end,data;
        union bits_decompound                                        //使用一个共用体分解各位
        {        struct bits_decom
                {        unsigned b0 : 1 ;
                        unsigned b1 : 1 ;
                        unsigned b2 : 1 ;
                        unsigned b3 : 1 ;
                        unsigned b4 : 1 ;
                        unsigned b5 : 1 ;
                        unsigned b6 : 1 ;
                        unsigned b7 : 1 ;
                }one;
                unsigned char all;
        }bt;
        intcon_t=INTCON;
        INTCON=0;
        bt.all=cd_data;                                                        //将数据按位分解        
        switch(cd)
        {        case 1 : cd_s=0b00001000; break;        //充电单独输出
                case 2 : cd_s=0b00000010; break;        //放电单独输出
                case 3 : cd_s=0b00001010; break;        //充放电全输出
        }
        bits[0]=(bt.one.b0==1)? 0xff : 0xf5;        //各位数据判断
        bits[1]=(bt.one.b1==1)? 0xff : 0xf5;
        bits[2]=(bt.one.b2==1)? 0xff : 0xf5;
        bits[3]=(bt.one.b3==1)? 0xff : 0xf5;
        bits[4]=(bt.one.b4==1)? 0xff : 0xf5;
        bits[5]=(bt.one.b5==1)? 0xff : 0xf5;
        bits[6]=(bt.one.b6==1)? 0xff : 0xf5;
        bits[7]=(bt.one.b7==1)? 0xff : 0xf5;
        PORTB|=cd_s;                                                        //触发信号
        delay_ms(1);                                                        //触发延时
        PORTB&=0xf5;                                                        //触发结束
        delay_us(50);
        for(count=0;count<8;count++)
        {        start=cd_s|PORTB;                                        //起始信号的值
                data=(cd_s|PORTB)&bits[count];                //数据信号的值
                end=PORTB&0xf5;                                                //结束信号的值
                PORTB=start;                                                //起始信号
                delay_us(5*br);
                PORTB=data;                                                        //数据信号
                delay_us(10*br);
                PORTB=end;                                                        //结束信号
                delay_us(10*br);        
        }
        INTCON=        intcon_t;
}

//-------------充电状态识别-----------------//
void ch_id()                                                                //sb高为保护,低为正常
{        while(1)
        {        if(COS) {delay_ms(5); if(COS)  {sb=1;break;}}
                else    {delay_ms(5); if(!COS) {sb=0;break;}}
        }
}
//-------------放电状态识别-----------------//
void dc_id()                                                                //sb高为保护,低为正常
{        while(1)
        {        if(DOS) {delay_ms(5); if(DOS)  {sb=1;break;}}
                else    {delay_ms(5); if(!DOS) {sb=0;break;}}
        }
}
//-------------延时判断ok_ng----------------//
void ok_ng(unsigned int delay_time1)
{        delay_time=delay_time1;
        INTCON=0b11100000;                                                //中断打开,延时计时开始
        while(ch_s)
        {        if(COS) {delay_ms(1); if(COS) {sb=1;break;}}
                if(!delay_time)        {sb=0;break;}                //延时到,结束循环
        }
        while(dc_s)
        {        if(DOS) {delay_ms(1); if(DOS) {sb=1;break;}}
                if(!delay_time)        {sb=0;break;}                //延时到,结束循环
        }
        INTCON=0b11000000;                                                //中断寄存器恢复
}
//-------------延时判断ng_ok------------//
void ng_ok(unsigned int delay_time1)
{        delay_time=delay_time1;
        INTCON=0b11100000;                                                //中断打开,延时计时开始
        while(ch_s)
        {        if(!COS) {delay_ms(1); if(!COS) {sb=0;break;}}
                if(!delay_time) {sb=1;break;}                //延时到,结束循环
        }
        while(dc_s)
        {        if(!DOS) {delay_ms(1); if(!DOS) {sb=0;break;}}
                if(!delay_time) {sb=1;break;}                //延时到,结束循环
        }
        INTCON=0b11000000;                                                //中断寄存器恢复
}
//-------------状态识别高为OK---------------//
void sb_id_h()
{        if(sb)        {enb=1;lcd_write_char_ok();}        //OK,使能置1
        else  enb=0;
}
//-------------状态识别低为OK---------------//
void sb_id_l()               
{        if(!sb)        {enb=1;lcd_write_char_ok();}        //OK,使能置1
        else  enb=0;
}
//*************按键检测函数*****************//
void key()
{        while(1)
        {        while(STA);
                delay_ms(10);
                if(!STA) break;
        }
        while(1)
        {        while(!STA);
                delay_ms(10);
                if(STA) break;
        }        
}        
//*************报警延时*********************//
void sound(unsigned char bj_time)
{        JBC=1;
//        delay_ms(3);
        delay_ms(bj_time);
        JBC=0;
}
//*************延时函数1ms******************//
void delay_ms(unsigned int m)                                //O=150:1mS
{        unsigned int o;
        for (;m>0;m--)
        for (o=150;o>0;o--) ;
}
//-------------固定延时函数1----------------//
void delay_us(unsigned char n)                                //1  =15uS, 10  =60uS
{        for(;n>0;n--);                                                        //100=500uS,1000=1.17mS
}
//*************AD测量8**********************//
void ad_test()                                                                //AD测量要中值滤波
{        unsigned char a,b;
        intcon_t=INTCON;                                                //中断寄存器保存
        INTCON=0;                                                                //中断关闭
        adr.v1=0;adres=0;                                                //清除AD测量结果
    for(a=4;a>0;a--)
        {        b=10;
                while(b>1) b--;
                GODONE=1;                                                        //打开AD_测量
                while(GODONE);                                                //等待AD测量结束
                adr.adres1[1]=ADRESH;
                adr.adres1[0]=ADRESL;
                adres+=adr.v1;
        }
        adres/=4;                                                                //测量结果4次求平均
        INTCON=intcon_t;                                                //中断寄存器恢复
}

使用特权

评论回复
6
Hezhiqiang|  楼主 | 2011-1-28 11:18 | 只看该作者
ye工,下面是主程序,中断函数里调用了一个时间显示程序,lcd_int里面,驱动程序驱动LCD显示当前时间,精确到0.1秒
//YT-BT1C05A-MAIN
//Programer:James he.(can can).
#include<pic.h>                                                                                //头文件
#include<pic16f887.h>                                                                //PIC头文件
#include"define.h"                                                                        //定义头文件       
#include"function.h"                                                                //函数头文件
__CONFIG(INTIO&WDTDIS&PWRTEN&MCLRDIS&CP&CPD&BOREN&FCMEN&LVPDIS&DEBUGEN);//单片机配置位设置:8M,MCLR
__CONFIG(0xFDFF);
//*******************各函数声明,变量声明************//
unsigned int  adres,delay_time,timer;
unsigned char intcon_t,temp;//中断备份,共用寄存器
unsigned char command,number,battery_n,ddram,key_r;        //按键用,PWM分频用
                        //程序号,测试串数,
unsigned char pro=0, test_s=2;                                                //按键用,PWM分频用
                         //程序号          0           1
unsigned char id[]          ={  15,  0};                                        //基准单位1uA
unsigned int  Cx[]          ={4150,  0};                                        //充电下限电压1mV
unsigned int  Cs[]          ={4250,  0};                                        //充电上限电压1mV
unsigned int  Ct_x[]  ={ 700,  0};                                        //充电下限延时1ms
unsigned int  Ct_s[]  ={1200,  0};                                        //充电上限延时1ms
unsigned int  Crs[]   ={4050,  0};                                        //充电恢复上限1mV
unsigned int  Crx[]   ={3950,  0};                                        //充电恢复下限1mV
unsigned char C_I[]          ={  20,  0};                                        //充电判断电流1ma
unsigned int  Ds[]          ={2800,  0};                                        //放电上限电压1mV
unsigned int  Dx[]          ={2700,  0};                                        //放电下限电压1mV
unsigned int  Dt_x[]  ={  50,  0};                                        //放电下限延时1ms
unsigned int  Dt_s[]  ={ 500,  0};                                        //放电上限延时1ms
unsigned int  Drx[]   ={2950,  0};                                        //放电恢复下限1mV
unsigned int  Drs[]   ={3050,  0};                                        //放电恢复上限1mV
unsigned char D_I[]          ={   5,  0};                                        //充电判断电流1ma
unsigned int  Df_t[]  ={1000,  0};                                        //断开负载延时1ms
//**************中断服务程序************************//
void interrupt counter(void)
{   if(T0IF)
        {        TMR0=9;
                T0IF=0;
                if(delay_time) delay_time--;
        }       
        if(TMR1IF)
        {        if(!lcd_s)        timer_show();                                        //时间显示处理       
                else
                {        TMR1IF=0;       
                        TMR1H=0x3C;
                        TMR1L=0xB0;
                        timer++;
                }
        }                                                                                                //延时减1                                                               
        if(!STA)
        {        while(!STA); WDTCON=1;}
}
//==================主程序开始======================//
void main()
{        init();       
while(1)
//==================程序开始检测按键================//       
{        lcd_init();                                                                                //单片机初始化函数
        lcd_clear_2line();                                                                //清除第二行
        lcd_write_char("PL replace part");
        PORTA=0b00010000;
        PORTB=0b01100000;
        PORTC=0b0;
        PORTD=0b0;
        PORTE=0b1000;
        key_r=0;
        key_s=0;
        cd_send(ch+dc,of);                                                                //充放电模拟关闭
        all_voltage(b_all,b_of);                                                //关闭电压输出
        all_voltage(b_all,3600);                                                //所有电压复位
        key();                                                                                        //检测按键。
        sound(10);                                                                                //声音提示
        number=0;                                                                                //序号显示清零
        timer=0;                                                                                //时间显示清零
        lcd_write_curs(0x84);                                                        //光标定位
        lcd_write_char("Timer:     S");                                        //时间位标框
        TMR1IF=0;
        INTCON=0b11000000;
        lcd_s=0;
//==================静态功耗========================//
if(1)
{        all_voltage(b_all,b_on);                                                //打开电压输出
        IDC=0;                                                                                        //取样电路打开
        lcd_write_char_no("leakage");                                                //漏电测试显示
        delay_ms(500);                                                                        //延时200ms
        ADCON0=0b10101101;                                                                //AD通道选择11
        ad_test();                                                                                //AD测量子程序
        if(adres<id[pro])
        {enb=1;IDC=1;delay_ms(500);lcd_write_char_ok();}//测试结果处理
        else enb=0;
}
//==================过充电测试======================//
if(enb)
{        SW3=1;
        ch_s=1;
        dc_s=0;
        cd_send(ch,on+C_I[pro]);                                                //充电模拟打开
        delay_ms(50);       
        cd_send(ch,on+C_I[pro]);                                                //充电模拟打开
        delay_ms(50);
        lcd_write_char_no("charge");                                        //充电下限显示
        delay_ms(500);
        sound(10);
        ch_id();                                                                                //充电状态识别
        sb_id_l();                                                                                //是否OK
        lcd_write_char_no("LED test");                                        //充电下限显示
        temp=0;                                                                                        //清空备用寄存器
        ADCON0=0b10001101;                                                                //AD通道选择3
        while(1)                        //LED检测
        {        cd_send(ch,of+C_I[pro]);
                delay_ms(500);
                ad_test();                                                                        //AD测量子程序
                if(adres>500)         temp++;else temp=0;                        //大于3V

                cd_send(ch,on+C_I[pro]);
                delay_ms(500);
                ad_test();                                                                        //AD测量子程序
                if(adres<60)         temp++;else temp=0;                        //小于300V

                if(temp>3) break;
                if(timer>100) WDTCON=1;       
        }
}
//------------------过充电测试----------------------//
for(battery_n=1;battery_n<=test_s;battery_n++)
{
//---------------
        if(enb)                                //过充下限测试
        {        lcd_write_char_cd("x");                                                //充电下限显示B1充电测试
                all_voltage(battery_n,Cx[pro]);                                //充电下限测试
                ok_ng(Ct_s[pro]);                                                        //充电下限延时测试
                sb_id_l();                                                                        //是否OK
        }
        if(enb)                                //过充上限,下限延时测试
        {        lcd_write_char_cd("sx");                                        //充电上限测试
                all_voltage(battery_n,Cs[pro]);                                //充电上限电压发送
                ok_ng(Ct_x[pro]);                                                        //充电下限延时测试
                sb_id_l();                                                                        //是否OK
        }
        if(enb)                                //过充上限,上限延时测试
        {        lcd_write_char_cd("ss");                                        //充电上限测试
                ok_ng(Ct_s[pro]-Ct_x[pro]);                                        //充电下限延时测试
                sb_id_h();                                                                        //是否OK
        }
        if(enb)                                //过充电时只有绿灯是亮的
        {        lcd_write_char_cd("L");                                                //充电led显示
                ADCON0=0b10001101;                                                        //AD通道选择2
                ad_test();                                                                        //过充电红灯灭
                if(adres>500) enb=1;else enb=0;                                //大于2V
                if(enb)
                {        ADCON0=0b10000001;                                                //AD通道选择0
                        ad_test();                                                                //过充电黄灯灭
                        if(adres>500) enb=1;else enb=0;                        //大于2V
                }
                if(enb)
                {        ADCON0=0b10001001;                                                //AD通道选择1
                        ad_test();                                                                //过充电绿灯亮
                        if(adres<260) enb=1;else enb=0;                        //小于1.3V
                }
        }
        if(enb)                                //过充恢复上限
        {        lcd_write_char_cd("rs");                                        //充电恢复上限测试
                all_voltage(battery_n,Crs[pro]);                        //充电恢复上限电压发送
                ng_ok(Ct_s[pro]);                                                        //充电恢复上限延时测试
                sb_id_h();                                                                        //是否OK
        }
        if(enb)                                //过充恢复下限
        {        lcd_write_char_cd("rx");                                        //充电恢复下限测试
                all_voltage(battery_n,Crx[pro]);                        //充电恢复下限电压发送
                ng_ok(Ct_s[pro]);                                                        //充电恢复下限延时测试
                sb_id_l();                                                                        //是否OK.
        }
}
        if(enb)       
        {        lcd_write_char_no("Not DC in CH");                        //充电恢复下限测试
                cd_send(dc,on);               
                dc_id();                                                                        //放电状态识别       
                if(sb==1) enb=1; else enb=0;                                //是否OK
        }
        if(enb) {cd_send(ch,of); delay_ms(1000);}                 //充电模拟关闭

//==================过放电测试======================//
if(enb)
{        ch_s=0;
        dc_s=1;
        delay_ms(20);
        cd_send(dc,on+D_I[pro]);                                                //放电模拟打开
        all_voltage(b_all,3600);                                                //标准电压发送
        lcd_write_char_no("dcharge");                                        //放电下限显示
        delay_ms(500);
        sound(10);
        dc_id();                                                                                //放电状态识别
        sb_id_l();                                                                                //是否OK                               
}
//------------------过放电测试----------------------//
for(battery_n=1;battery_n<=test_s;battery_n++)
{
//---------------
        if(enb)                                //过放上限测试
        {        cd_send(dc,on+D_I[pro]);                                        //放电模拟打开
                delay_ms(50);                                                                //延时50ms
                cd_send(dc,on+D_I[pro]);                                        //放电模拟打开
                lcd_write_char_cd("s");                                                //放电上限显示
                all_voltage(battery_n,Ds[pro]);                                //放电上限测试
                ok_ng(Dt_s[pro]);                                                        //放电上限延时测试
                sb_id_l();                                                                        //是否OK
        }
        if(enb)                                //这时黄灯是亮的
        {        lcd_write_char_cd("L");                                                //放电LED测试
                ADCON0=0b10000001;                                                        //AD通道选择0
                ad_test();                                                                        //AD测量子程序
                if(adres<60) enb=1;else enb=0;                                //大于3V
        }
        if(enb)                                //过放下限,下限延时测试,不能保护
        {        lcd_write_char_cd("xx");                                        //放电下限测试
                all_voltage(battery_n,Dx[pro]);                                //充电下限电压发送
                ok_ng(Dt_x[pro]);                                                        //充电下限延时测试
                sb_id_l();                                                                        //是否OK
        }
        if(enb)                                //过放下限,上限延时测试,要能保护
        {        lcd_write_char_cd("xs");                                        //放电上限测试
                ok_ng(Dt_s[pro]-Dt_x[pro]);                                        //放电下限延时测试
                sb_id_h();                                                                        //是否OK
        }
        if(enb)                                //这时黄灯是灭的
        {        lcd_write_char_cd("Lc");                                        //放电LED测试
                ADCON0=0b10000001;                                                        //AD通道选择0
                ad_test();                                                                        //AD测量子程序
                if(adres>500) enb=1;else enb=0;                                //大于3V
        }
        if(enb)                                //过放电状态,断开负载不恢复
        {        lcd_write_char_cd("nr");
                SW3=0;                                                                                //负载断开
                cd_send(dc,of+D_I[pro]);                                        //放电模拟关闭
                delay_ms(400);                                                                //延时200ms
                SW3=1;                                                                                //放电关闭
                cd_send(dc,on+D_I[pro]);                                        //放电模拟打开
                delay_ms(50);
                dc_id();                                                                        //放电状态识别       
                sb_id_h();                                                                        //高是OK                       
        }
        if(enb)                                //过放恢复上限,不恢复
        {        lcd_write_char_cd("rs");                                        //放电恢复下限测试
                all_voltage(battery_n,Drs[pro]);                        //放电恢复下限电压发送
                delay_ms(Df_t[pro]);                                                //固定延时等负载恢复
                dc_id();                                                                        //放电状态识别       
                sb_id_h();                                                                        //高是OK                       
        }
        if(enb)                                //断开开关恢复
        {        lcd_write_char_cd("NLr");                                        //放电恢复下限测试
                SW3=0;
                cd_send(dc,of+D_I[pro]);                                        //放电模拟关闭
                delay_ms(600);
                SW3=1;
                cd_send(dc,on+D_I[pro]);                                        //放电模拟打开
                delay_ms(100);
                cd_send(dc,on+D_I[pro]);                                        //放电模拟打开
                delay_ms(500);
                dc_id();
                sb_id_l();
        }
        if(enb) cd_send(dc,of);                                                        //放电模拟关闭
}
//------------------黄灯低压指示------------------//
        if(enb)
        {        all_voltage(b_all,3600);                                        //正常电压发送
                delay_ms(1000);                                                                //延时1S
                lcd_write_char_no("low vol");                                //低压显示
                all_voltage(b_all,3450);                                        //低压显示上限电压发送
                delay_ms(1000);               
                ADCON0=0b10000001;                                                        //AD通道选择0
                ad_test();                                                                        //AD测量子程序
                if(adres>500) enb=1;else enb=0;                                //大于3V,黄灯不能亮
                if(enb)
                {        all_voltage(b_all,3350);                                //低压显示下限电压发送
                        delay_ms(600);               
                        ADCON0=0b10000001;                                                //AD通道选择0
                        ad_test();                                                                //AD测量子程序
                        if(adres<60) enb=1;else enb=0;                        //小于300mv,黄灯要亮
                }
        }       
       
//==================测试结果========================//
        INTCON=0b0;                                                                                //测试计时停止
//------------------PASS----------------------------//
if(enb)
{        lcd_write_curs(0xcc);                                                        //光标定位
        lcd_write_char("PASS");                                                        //PASS
        sound(200);
        delay_ms(200);
        sound(200);
        key();
}
//------------------FAIL----------------------------//
if(!enb)
{        lcd_write_curs(0xcc);                                                        //光标定位
        lcd_write_char("FAIL");                                                        //FAIL
        //JBC=1;
        key();
        JBC=0;
}
//==================主程序结束======================//
}
}

使用特权

评论回复
7
Hezhiqiang|  楼主 | 2011-1-28 11:20 | 只看该作者
这里lcd_init程序  LCD驱动程
#include<pic.h>                                                                //头文件
#include<pic16f887.h>                                                //PIC头文件
#include"define.h"                                                        //定义头文件       
#include"function.h"                                                //函数头文件
extern unsigned char number,battery_n,ddram;
extern unsigned int timer;
                                                                                        //引用外部函数
//第一行:80-8F
//第一行:C0-CF
//*************lcd初始化********************//
void lcd_init()
{        lcd_write_comd(0b00111100);                                //双行显示,8位模式,5*7
        delay_ms(10);                                                       
        lcd_write_comd(0b00001111);                                //显示功能开,光标开,闪烁开
        lcd_write_comd(0b00000110);                                //右移,屏幕不移动
        lcd_write_comd(0b00010100);                                //右移,AC加1
        lcd_write_comd(0b00000001);                                //清屏
        delay_ms(15);       
        lcd_write_char("YAT   YT-BT1C05A");               
}
//-------------lcd写指令--------------------//
void lcd_write_comd(unsigned char c)
{        //        if(c&0x20==0)        lcd_check_bf();       
        BUS=c;
        RS=0;
        R_W=0;
        EN=1;
        delay_us(2);
        EN=0;
        lcd_check_bf();
}
//-------------lcd写数据--------------------//
void lcd_write_data(unsigned char d)
{        //lcd_check_bf();
        BUS=d;
        RS=1;
        R_W=0;
        EN=1;
        delay_us(2);
        EN=0;
        lcd_check_bf();
}       
//-------------lcd写字符串------------------//
void lcd_write_char(unsigned char *p)
{        while(*p)
        {        lcd_write_data(*p);
                p++;
        }
}
//-------------lcd写字符串------------------//
void lcd_write_char_delay(unsigned char *p)
{        while(*p)
        {        lcd_write_data(*p);
                delay_ms(200);
                p++;
        }
}
//-------------lcd写字符串1-----------------//
void lcd_write_char_no(unsigned char *p)
{        lcd_s=1;                                                                //禁止中断写
        lcd_write_no();                                                        //写序号
        sound(10);                                                                //声音提示
        while(*p)
        {        lcd_write_data(*p);
                p++;
        }
        lcd_s=0;                                                                //打开中断写
}
//-------------lcd写充电字符串--------------//
void lcd_write_char_cd(unsigned char *p)        //充电显示
{        lcd_s=1;                                                                //禁止中断写
        lcd_write_no();                                                        //写序号
        sound(10);                                                                //声音提示
        lcd_write_data('b');                                        //写入b
        lcd_write_data('0'+battery_n);
        if(ch_s)        lcd_write_char(" chg ");        //充电写入
        if(dc_s)        lcd_write_char(" dcg ");        //放电写入
        while(*p)
        {        lcd_write_data(*p);
                p++;
        }
        lcd_s=0;                                                                //打开禁止中断写
}
//-------------lcd清除第二行----------------//
void lcd_clear_2line()
{        lcd_write_curs(0xc0);                                        //光标定位
        lcd_write_char("                ");
        lcd_write_curs(0xc0);                                        //光标定位
}
//-------------lcd写序号--------------------//
void lcd_write_no()                                                        //写序号
{        unsigned char decade1,units1;
        number++;                                                                //序号自加
        lcd_clear_2line();                                                //清除第二行,光标归位
        decade1=number/10;                                                //十位算出
        units1=number%10;                                                //个位算出
        if(decade1)        lcd_write_data('0'+decade1);//十位是否要显示
        lcd_write_data('0'+units1);                                //个位是否要显示
        lcd_write_data(':');
}
//-------------光标定位---------------------//
//第一行:80-8F
//第二行:C0-CF
void lcd_write_curs(unsigned char x)
{        lcd_check_bf();
        BUS=x;
        RS=0;
        R_W=0;
        EN=1;
        delay_us(1);
        EN=0;       
        lcd_check_bf();
}
//-------------LCD等忙信号------------------//
void lcd_check_bf()
{        TRISD=0xFF;                                                                //设置总线为输入
        RS=0;
        R_W=1;
        EN=1;
        delay_us(1);
        while(bf);
        ddram=PORTD;
        EN=0;
        TRISD=0x00;                                                                //恢复总线输出状态
}
//-------------写OK-------------------------//
void lcd_write_char_ok()       
{        lcd_s=1;                                                                //禁止中断写
        lcd_write_char(" ok");
        lcd_s=0;                                                                //打开中断写
        delay_ms(200);
}
//-------------中断,测试时间显示-----------------//
void timer_show()                                                        //写序号
{        unsigned char hundreds,decade,units,unit;
        TMR1IF=0;                                                                //清TMR1中断标志
        TMR1H=0x3C;                                                                //赋初始值
        TMR1L=0xB0;
        int_write_curs(0x8a);                                        //光标定位
        hundreds=timer/1000;                                        //百位算出
        decade=(timer%1000)/100;                                //十位算出
        units=(timer%100)/10;                                        //个位算出
        unit=timer%10;                                                        //小数位算出
        int_write_data('0'+hundreds);                        //百位是显示
        int_write_data('0'+decade);                                //十位是显示
        int_write_data('0'+units);                                //个位是显示
        int_write_data('.');                                        //小位是显示
        int_write_data('0'+unit);                                //个位是显示
        timer++;                                                                //时间自加
        int_write_curs((ddram|128)+1);                        //光标恢复
}       
        //中断里写数据
void int_write_data(unsigned char d)                        //中断写数据
{        int_check_bf();
        BUS=d;
        RS=1;
        R_W=0;
        EN=1;
        int_delay_us();
        EN=0;
        int_check_bf();
}
        //中断里写光标
void int_write_curs(unsigned char x)                        //中断光标定位
{        int_check_bf();
        BUS=x;
        RS=0;
        R_W=0;
        EN=1;
        int_delay_us();
        EN=0;       
        int_check_bf();
}
        //中断里读忙
void int_check_bf()
{        TRISD=0xFF;                                                                //设置总线为输入
        RS=0;
        R_W=1;
        EN=1;
        int_delay_us();
        while(bf);
        EN=0;
        TRISD=0x00;                                                                //恢复总线输出状态
}
        //中断里延时
void int_delay_us()                       
{        asm("nop");
        asm("nop");
        asm("nop");
}

使用特权

评论回复
8
Hezhiqiang|  楼主 | 2011-1-28 11:22 | 只看该作者
//函数声明部分
        void init()                                                        ;                //初始化函数
        void lcd_init()                                                ;                //LCD初始化
        void key()                                                        ;                //按键检测
        void delay_ms(unsigned int m)                ;                //延时函数基准为1ms
        void delay_us(unsigned char n)                ;                //延时函数基准为us
        void ad_test()                                                ;                //ad电压测试
        void lcd_write_data(unsigned char d);                //LCD写数据
        void lcd_write_comd(unsigned char c);                //LCD写命令
        void lcd_read_data()                                ;                //LCD读数据
        void lcd_read_comd()                                ;                //LCD读命令
        void lcd_check_bf()                                        ;                //LCD读忙信号
        void lcd_write_curs(unsigned char x);                //光标定位
        void lcd_write_char(unsigned char *p);                //写字符串
        void lcd_write_char_delay(unsigned char *p);

        void int_write_data(unsigned char d);                //中断写数据
        void int_write_curs(unsigned char x);                //中断光标定位
        void int_check_bf();                                                //中断里读忙
        void int_delay_us();                                                //中断里延时

        void lcd_write_char_no(unsigned char *p);        //写字符串
        void lcd_write_char_cd(unsigned char *p);        //充电显示
        void lcd_clear_2line();                                                //清除第二行
        void lcd_write_char_ok();                                        //写OK
        void lcd_write_no();                                                //写序号
        void timer_show();                                                        //测试时间显示
        void all_voltage(unsigned char b,unsigned int vol);       
                                                                                                //电压发送信号
        void cd_send(unsigned char ad,unsigned char data);       
                                                                                                //充放电参数发送
        void ch_id();                                                                //充电识别
        void dc_id();                                                                //放电识别
        void sb_id_h();                                                                //识别高为OK
        void sb_id_l();                                                                //识别低为OK
        void sound(unsigned char bj_time);                        //声音输出
        void ok_ng(unsigned int dalay_time1);        //充电延时判断ok_ng
        void ng_ok(unsigned int delay_time1);        //充电延时判断ng_ok
        void over_charge_test();                                        //过充电测试

使用特权

评论回复
9
yewuyi| | 2011-1-28 11:54 | 只看该作者
我的个神,你弄一摞字母,俺们那有那么多时间给你一个一个的审查代码?


你饶了我吧。

另外,你可以把你的项目文件整个打包,说不定会有人帮你编译看看结果,你贴出来,别人还得给你见项目文件去,提问题时要考虑到尽量节省解答者的时间。

使用特权

评论回复
10
yirongfu| | 2011-1-28 11:59 | 只看该作者
本帖最后由 yirongfu 于 2011-1-28 12:02 编辑

//**************中断服务程序************************//
//
void interrupt counter(void)
{   if(T0IF) {TMR0=9;T0IF=0;if(delay_time) delay_time--;}
if(TMR1IF)

红色部分是屏蔽的?

使用特权

评论回复
11
Hezhiqiang|  楼主 | 2011-1-28 13:15 | 只看该作者
9# yewuyi
你不是说我的中断写的不是很好麻!就看看中断那一部分哪里不合适就可以啦!上面贴出来的PIC16F887的程序是没有问题的!不用打包,已经生产一年多啦!
我的问题是最上面的那个PIC16F676编译出现的问题!那一部分是从PIC16F887的那个程序(就是上面贴出来OK的程序)COPY过去的,就芯片不同!676的程序就一点点!居然搞了我一下!:(

使用特权

评论回复
12
yewuyi| | 2011-1-28 14:06 | 只看该作者
//*******************各函数声明,变量声明************//
unsigned int adres=0,delay_time=0;  //外部引用函数==这个有问题,屏蔽就好啦
unsigned char intcon_t;
//**************中断服务程序************************//
//void interrupt counter(void)
{   if(T0IF) {TMR0=9;T0IF=0;if(delay_time) delay_time--;}
if(TMR1IF)
{ if(!lcd_s) timer_show();     //时间显示处理
  else {TMR1IF=0; TMR1H=0x3C;TMR1L=0xB0;timer++;}
}            //延时减1        
if(!STA) {while(!STA); WDTCON=1;}
}
-----------------------
1、上面有人指出了,输入错误
//void interrupt counter(void)
2、虽然C语言没有严格的输入格式要求,但类似if(T0IF) {TMR0=9;T0IF=0;if(delay_time) delay_time--;}
这样的代码写法,是很让人抓狂的,请养成良好的书写代码的习惯。
3、在PIC16中,判断中断是需要协同中断使能位一起判断的,千万别只以中断溢出标志作为中断响应的依据,否则,将存在潜在的风险。示范如下:void                 interrupt ISR(void)
{
if(CCP2IE&&CCP2IF){
                  TMR1ON=false;
                  CCP2IE=false;
                  }
if(TMR2IE&&TMR2IF){
                  PWMtrisclose;
                  TMR2IF=false;
                  TMR2IE=false;
                //  CCP2IF=false;
                //  CCP2IE=ture;//allowCaptureInterrupt();
                  }
}
4、有关看门狗的设置和操作均应该考虑到看门狗这种模块的特殊性,所以WDTCON=1;这样的操作出现在你的中断代码总是让人感觉很不舒畅,请BAIDU各类有关看门狗的**,了解看门狗应该怎么养,否则养的很可能就不是看门狗,而是一条咬自己主人的疯狗。
5、针对首帖,另有一点
#include<pic.h>          //头文件
#include<pic16630.h>        //头文件
请在MPLAB中尽量少采用这种方法,在MPLAB+PICC中比较规范的做法就是:#include<pic.h> ,然后再MPLAB中设置芯片型号,PIC.H会自然的帮你找到PICC当前编译器中的对应型号头文件。在PICC中,某一个芯片型号在不同版本PICC编译器中,其头文件的可能并不相同,例如pic16630.h,可能在另外版本中就不是这个名字

使用特权

评论回复
13
Hezhiqiang|  楼主 | 2011-1-28 15:32 | 只看该作者
谢谢啦,学习啦!
第1项不说啦!!
第2项源代如下,为了简少行数,我在调试OK后并行了,以后确实要注意!
第3项真是谢啦,提醒我啦!记得用汇编一定要判断标志位的!
第4项关于看门狗说下,这里if(!STA)  while(!STA);只要条件一发生我要让芯片复位,我想这里用软件看门狗复位是比较好的啦,不知道ye工还有没有其它好的办法让芯片复位!这里硬件看门狗是关掉的!
第5项学习啦
//**************中断服务程序************************//
void interrupt counter(void)
{   if(T0IF)
        {       TMR0=9;
                T0IF=0;
                if(delay_time) delay_time--;
        }        
        if(TMR1IF)
        {        if(!lcd_s)     timer_show();      //时间显示处理        
             else
                {       TMR1IF=0;        
                        TMR1H=0x3C;
                        TMR1L=0xB0;
                        timer++;
                }
        }                                                                            //
        if(!STA)
        {        while(!STA); WDTCON=1;}
}

使用特权

评论回复
14
martin| | 2011-1-30 09:42 | 只看该作者
delay_time是unsigned int,也就是2个字节。你在中断中对delay_time的操作,又在主函数里对delay_time操作,这是根本错误的。
设想一下,如果在主函数里对delay_time操作,在汇编代码上是先操做dealy_time的低字节,然后再操作高字节,如果恰好刚操作完低字节就发生了中断会怎么样呢?

使用特权

评论回复
15
yewuyi| | 2011-1-30 11:09 | 只看该作者
martin看的太仔细了,呵呵,如果LZ确实是‘中断中对delay_time的操作,又在主函数里对delay_time操作’

这确实是送命代码。

使用特权

评论回复
16
yewuyi| | 2011-1-30 11:10 | 只看该作者
建议LZ认真学习一下有关临界代码方面的知识。

使用特权

评论回复
17
liouxingquan| | 2011-1-31 17:26 | 只看该作者
看不懂

使用特权

评论回复
18
Hezhiqiang|  楼主 | 2011-2-11 11:44 | 只看该作者
不会的,开启中断后,只会在中断里对delay_time里进行操作!

使用特权

评论回复
19
Hezhiqiang|  楼主 | 2011-2-11 16:17 | 只看该作者
本帖最后由 Hezhiqiang 于 2011-2-11 16:29 编辑

大虾们,问题找到啦,但不是很明白为什么,为了看起来方面我把所有的都放在一块,该删的就删啦!还请赐教
程序就这么多!
//Programer:James he.(can can).
#include<pic.h>                //头文件
//#include<pic16630.h>        //头文件
//#include"define.h"                //定义头文件        
//#include"function.h"        //函数头文件
__CONFIG(INTOSCIO&WDTDIS&PWRTEN&MCLRDIS&BOREN&CPD&BGHIGH
//==================各函数声明,变量声明=============//
         问题就在这下面,FLAG1是我声明的绝对地址用来保存我的位参数的,PIC16F676 BANK0的通用寄存器是从20H开始的,像下面这样编译是通过的,如果将0x20改成0x21编译就不通过啦,显示如下,当改成0x25编译又是通过,正好5个字节,主函数里的变量正好是5个字节长,当在主函数里再声明变量,则要在改成0x20+所有变量长编译才能通过,请问这是什么原因。
Error   [1250] X:\project\02-Normal\electron\Test file\Test-1\Firmware\Main_ac\main.c; 38. could not find space (2 bytes) for variable _delay_timer
        //绝对地址
        volatile       unsigned char        FLAG1                @  0x20;
        //变量声明
        unsigned char intcon_t;
        unsigned int   adres,delay_timer;        
        //函数声明
        void init();                                        //初始化函数
//==================中断服务程序====================//
//void interrupt counter(void)
//==================主程序开始======================//
void main()
{        init();        
        while(1)
{        PORTC=0b00010000;
}
//------------------主程序结束----------------------//
}
//==================初始化函数======================//
void init()
{        CMCON =0b0111;                //关闭比较器1
        ADCON0=0b10001101;        //启动AD模块,8M时钟,4uS,32分频
        ADCON1=0b00010000;        //右对起
        ANSEL =0b00001000;
        INTCON=0b00000000;            //中断,TMR0中断允许
        OPTION=0b00000010;        //TMR0分频=8
        WPUA  =0b0;                //开启部分弱上接
        IOCA  =0b0;                //电平变化中断禁止
        TRISA =0b00111111;   
        TRISC =0b00000000;
        PORTA =0b00000000;
        PORTC =0b0;
}

使用特权

评论回复
20
yewuyi| | 2011-2-11 19:48 | 只看该作者
位参数请使用关键字bit 进行定义.

另外在PICC中,尽量不要使用绝对定位定义变量,如果一定要用的话,请尽量放到RAM区的最后地址,否则就是自讨哭吃.

具体原因你可自行翻阅PICC编译器的手册,或者自行BAIDU 相关回帖.

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:学无止境,自学成材

4

主题

80

帖子

1

粉丝