找回密码
 立即注册

QQ登录

只需一步,快速开始

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

pic编译求助

[复制链接]
跳转到指定楼层
楼主
ID:105780 发表于 2016-3-5 15:17 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
网上收到了一段程序,编译出错。求智者帮忙,怎样修改出错内容:
Build C:\Users\Administrator\Desktop\wenk\wenk for device 16F628A
Using driver C:\Program Files\HI-TECH Software\PICC\PRO\9.65\bin\picc.exe

Make: The target "C:\Users\Administrator\Desktop\wenk\wenk.p1" is out of date.
Executing: "C:\Program Files\HI-TECH Software\PICC\PRO\9.65\bin\picc.exe" --pass1 C:\Users\Administrator\Desktop\wenk\wenk.c -q --chip=16F628A -P --runtime=default --opt=default -D__DEBUG=1 -g --asmlist "--errformat=Error   [%n] %f; %l.%c %s" "--msgformat=Advisory[%n] %s" "--warnformat=Warning [%n] %f; %l.%c %s"
Error   [141] C:\Users\Administrator\Desktop\wenk\pc68.h; 2.24 can't open include file "defineports.h": No such file or directory

********** Build failed! **********



代码如下:
#include "defineports.h"

__CONFIG(INTIO & WDTEN & MCLRDIS & BOREN & LVPDIS & PWRTEN);

//各种模式定义,位操作
#define MODE_NORMAL     0x00
#define MODE_SETTING    0x01
#define MODE_NO_NTC     0x02

unsigned char currMode = 0;

#define NTC_TEMP_BUFF_NUM 6
signed char prevCfgTemp = 60;
signed char cfgTemp = 60;
signed char currTemp = 0;    //当前NTC所测得的温度
signed char ntcTempBuff[NTC_TEMP_BUFF_NUM];
unsigned char ntcTempBuffCnt = 0;

//EEPROM
#define EE_VERIFY_ADDR      0x20
#define EE_VERIFY_VALUE     0x35
#define EE_CFG_TEMP_ADDR    0x21

//用于按键防抖
unsigned char downKeyHistory = 0;
unsigned char upKeyHistory = 0;
bit downKeyPressed = 0;
bit upKeyPressed = 0;

bit halfSecond = 0; //每500ms反转一次
bit revertLed = 0;

unsigned int tickNum = 0;
unsigned int btnIdleTicks = 0;

//PID系数和中间变量
#define PID_PROPORTION  8  // 比例系数
#define PID_INTEGRAL    1  // 积分系数
#define PID_DERIVATIVE  1  // 微分系数
signed char pidLastError = 0;  // 上次偏差
signed int pidSumError = 0;    // 历史误差累计值
signed int pidResult = 0;

//以度为单位的NTC温度查找表,起始温度为-9度(因为只有两位数码管)
/* 换一个NTC后,如果知道B值,则修改此python代码中的B值,然后执行生成此表
import math
B = 3800
sOut = "#define TBL_NTC_TEMP_NUM 110\nconst unsigned int tblNtcTemp[TBL_NTC_TEMP_NUM] = {\n"
for i in range(-9, 100, 10):
    sl = []
    for j in range(i, i + 10):
        sl.append('%.0f' % (10000 * math.exp(B * (1 / (273.15 + j) - 1 / (273.15 + 25) ) ) ) )
    sOut += '    ' + ', '.join(sl) + ',\n'
sOut += '};'
with open('c:/tblntctemp.txt', 'w') as f:
    f.write(sOut)
*/
#define TBL_NTC_TEMP_NUM 110
const unsigned int tblNtcTemp[TBL_NTC_TEMP_NUM] = {
    31057, 29915, 28822, 27778, 26778, 25822, 24906, 24029, 23190, 22385,
    21614, 20875, 20166, 19486, 18834, 18208, 17607, 17029, 16475, 15943,
    15431, 14939, 14466, 14011, 13574, 13153, 12748, 12357, 11982, 11620,
    11272, 10936, 10613, 10301, 10000, 9710, 9430, 9160, 8900, 8648,
    8406, 8171, 7945, 7726, 7515, 7311, 7113, 6922, 6738, 6559,
    6386, 6219, 6058, 5901, 5750, 5603, 5461, 5323, 5190, 5060,
    4935, 4814, 4696, 4582, 4471, 4364, 4260, 4159, 4061, 3965,
    3873, 3783, 3696, 3612, 3529, 3450, 3372, 3296, 3223, 3152,
    3083, 3015, 2950, 2886, 2824, 2764, 2705, 2648, 2592, 2538,
    2485, 2434, 2384, 2335, 2288, 2242, 2197, 2153, 2110, 2068,
    2028, 1988, 1949, 1912, 1875, 1839, 1804, 1770, 1737, 1704,
};

//段对应关系
//RB0-G, RB1-F, RB2-B, RB3-A, RB4-E, RB5-D, RB6-DP, RB7-C
//0 - 9,
//'-', 'E', 'H', 'L'
unsigned char segMap[] = {0x41, 0x7b, 0xc2, 0x52, 0x78, 0x54, 0x44, 0x73, 0x40, 0x50,
    0xfe, 0xc4, 0x68, 0xcd};
#define SEG_IDX_DASH  10
#define SEG_IDX_E     11
#define SEG_IDX_H     12
#define SEG_IDX_L     13

unsigned char digit0Seg = 0;
unsigned char digit1Seg = 0;


//延时函数,一个循环刚好10个指令,在最后加上函数调用的花销7个指令即可。
//假定4m晶体,则:
//延时0.5ms可以用:delayit(50)
//延时1ms可以用:delayit(100)
//延时10ms可以用:delayit(1000)
void delayit(unsigned int d)
{
    while(--d){;}
}

//EEPROM写数据函数
void SaveCfgToEeprom()
{
    unsigned char n;
    if (prevCfgTemp == cfgTemp)
        return;

    for (n = 2; n > 0; n--)
    {
        while (WR == 1);

        if (n == 2)
        {
            EEADR = EE_CFG_TEMP_ADDR;
            EEDATA = (unsigned char)cfgTemp;
        }
        else
        {
            EEADR = EE_VERIFY_ADDR;
            EEDATA = EE_VERIFY_VALUE;
        }
        WREN = 1;
        EECON2 = 0x55;
        EECON2 = 0xaa;
        WR = 1;
    }
    while (WR == 1);
    WREN = 0;
    prevCfgTemp = cfgTemp;
}

//EEPROM读数据函数
void RestoreCfgFromEeprom()
{
    while (RD == 1);
    EEADR = EE_VERIFY_ADDR;
    RD = 1;
    while (RD == 1);
    if (EEDATA != EE_VERIFY_VALUE)
        return;

    EEADR = EE_CFG_TEMP_ADDR;
    RD = 1;
    while (RD == 1);
    cfgTemp = (signed char)EEDATA;

    if ((cfgTemp < -9) || (cfgTemp > 99))
        cfgTemp = 50;

    prevCfgTemp = cfgTemp;
}

//扫描按键事件,并且更新当前模式状态
void ScanButtons()
{
    if (currMode & MODE_NO_NTC)
        return;

    downKeyHistory = downKeyHistory << 1 | !PORT_BUTTON_DOWN;
    if ((downKeyHistory & 0x07) == 0x07) //确定按键按下
    {
        downKeyPressed = 1;
        btnIdleTicks = 0;
    }
    else
    {
        downKeyPressed = 0;
    }

    upKeyHistory = upKeyHistory << 1 | !PORT_BUTTON_UP;
    if ((upKeyHistory & 0x07) == 0x07) //确定按键按下
    {
        upKeyPressed = 1;
        btnIdleTicks = 0;
    }
    else
    {
        upKeyPressed = 0;
    }

    if (currMode & MODE_SETTING)
    {
        if (((downKeyHistory & 0x0f) == 0x07) && !upKeyPressed)
        {
            if (--cfgTemp < -9)
                cfgTemp = 99;
        }
        else if (((upKeyHistory & 0x0f) == 0x07) && !downKeyPressed)
        {
            if (++cfgTemp > 99)
                cfgTemp = -9;
        }

        //设置模式下4s无动作则自动退出
        if (btnIdleTicks > 800)
        {
            currMode = MODE_NORMAL;
            ntcTempBuffCnt = 0;
            pidResult = 0;
            SaveCfgToEeprom();
        }
    }
    else if ((currMode == MODE_NORMAL) && downKeyPressed && upKeyPressed)
    {
        currMode |= MODE_SETTING;
        PORT_HEATER = 0;
    }
}

//三中取二判断端口状态
unsigned char PortNtcStatus()
{
    unsigned char p = 0;
    if (PORT_NTC)
        p++;
    delayit(1);
    if (PORT_NTC)
        p++;
    delayit(1);
    if (PORT_NTC)
        p++;

    if (p >= 2)
        return 1;
    else
        return 0;
}

//判断NTC是否正常连接,原理是改变另一个端口输出值,看其是否跟着改变
unsigned char IsNtcAvailable()
{
    unsigned int cnt = 1000;

    TRIS_MEASURER = 1;
    TRIS_REF_RESISTOR = 1;
    TRIS_NTC = 1;

    if (PortNtcStatus())
    {
        TRIS_MEASURER = 0;
        PORT_MEASURER = 0;
        while (PortNtcStatus() && (cnt > 0))
            cnt--;
    }
    else
    {
        TRIS_MEASURER = 0;
        PORT_MEASURER = 1;
        while ((PortNtcStatus() == 0) && (cnt > 0))
            cnt--;
    }

    PORT_MEASURER = 1;
    if (cnt)
        return 1;
    else
        return 0;
}

//使用PID算法根据当前温度计算要加热的时间(加热周期为Tick中断的周期)
void CalPidResult()
{
    signed char curError, dError;
    curError = cfgTemp - currTemp;
    if (curError > 1)
    {
        dError = curError - pidLastError;
        pidSumError += curError;
        pidLastError = dError;
        pidResult = curError*PID_PROPORTION + pidSumError*PID_INTEGRAL + dError*PID_DERIVATIVE;
        pidResult >>= 3;
    }
    else
    {
        pidSumError = 0;
        pidLastError = 1;
        pidResult = 0; //curError * PID_PROPORTION;
    }
    /*if (curError > 10)
        pidResult = 10
    else if (curError > 1)
        pidResult = curError * 2;
    else
        pidResult = 0;*/
}

//使用普通IO口计算NTC的电阻,进而查表得出当前温度
//软件滤波算法:采样多次,然后去掉一个最大值,一个最小值,剩下的取平均
void GetCurrentTemp()
{
    //因为NTC为通过插座外接,可能会出现断开、接触不好、断路等异常,此变量用于防止死循环
    unsigned int cntSafe = 20000;
    unsigned int cntNtc, cntRef;
    float resistorNtc, ratio;
    signed int sumTemp;
    unsigned char idx;
    signed char maxTemp, minTemp;
    signed char thisTemp = 0;

    if (IsNtcAvailable() == 0)
    {
        currMode |= MODE_NO_NTC;
        currTemp = 120;
        ntcTempBuffCnt = 0;
        return;
    }
    else
    {
        currMode &= ~MODE_NO_NTC;
    }

    //输出高电平给电容充电
    TRIS_REF_RESISTOR = 1;
    TRIS_NTC = 1;
    TRIS_MEASURER = 0;
    PORT_MEASURER = 1;
    PORT_NTC = 0;
    PORT_REF_RESISTOR = 0;
    delayit(50); //让电容充分充电

    //停止TMR1,重新设置TMR1
    TMR1ON = 0;
    TMR1H = 0;
    TMR1L = 0;

    //打开NTC端口,让电容放电,获取放电时间
    GIE = 0;
    TRIS_MEASURER = 1;
    PORT_NTC = 0;
    TRIS_NTC = 0;
    TMR1ON = 1; //TMR1开始计时

    while ((PORT_MEASURER) && (cntSafe > 0))
        cntSafe--;

    TMR1ON = 0;
    cntNtc = (TMR1H << 8) + TMR1L;
    GIE = 1;

    //NTC可能断开连接了?
    if (cntSafe == 0)
    {
        currMode |= MODE_NO_NTC;
        currTemp = 120;
        ntcTempBuffCnt = 0;
        return;
    }
    else
    {
        currMode &= ~MODE_NO_NTC;
    }

    //同样步骤测试参考电阻,然后通过两个计数值的对比就可以计算出NTC电阻

    //输出高电平给电容充电
    TRIS_NTC = 1;
    TRIS_MEASURER = 0;
    PORT_MEASURER = 1;
    delayit(50); //让电容充分充电

    //重新设置TMR1
    TMR1H = 0;
    TMR1L = 0;

    //打开参考电阻端口,让电容放电,获取放电时间
    GIE = 0;
    TRIS_MEASURER = 1;
    TRIS_REF_RESISTOR = 0;
    PORT_REF_RESISTOR = 0;
    TMR1ON = 1; //TMR1开始计时
    do {}
    while (PORT_MEASURER);
    TMR1ON = 0;
    cntRef = (TMR1H << 8) + TMR1L;
    GIE = 1;

    TRIS_REF_RESISTOR = 1;
    TRIS_MEASURER = 0;
    PORT_MEASURER = 1;

    //计算得到当前NTC阻值,然后就可以查表得到温度值了
    if ((cntNtc > 0) && (cntRef > 0))
    {
        ratio = (float)cntNtc / (float)cntRef;
        resistorNtc = REF_RESISTOR_VALUE * ratio;

        if (resistorNtc < tblNtcTemp[TBL_NTC_TEMP_NUM - 1]) //温度越限
        {
            thisTemp = 120;
        }
        else if (resistorNtc > tblNtcTemp[0])
        {
            thisTemp = -120;
        }
        else
        {
            for (idx = TBL_NTC_TEMP_NUM; idx > 0; idx--)
            {
                if (resistorNtc <= tblNtcTemp[idx - 1])
                {
                    thisTemp = idx - 10; //温度表从-9度开始
                    break;
                }
            }
        }
    }
    else //计数值为零可能是短路
    {
        thisTemp = 120;
    }

    //软件滤波:去掉一个最大值,去掉一个最小值,然后剩下的取平均
    ntcTempBuff[ntcTempBuffCnt] = thisTemp;
    if (++ntcTempBuffCnt >= NTC_TEMP_BUFF_NUM)
    {
        ntcTempBuffCnt = 0;

        //去掉一个最大值和一个最小值,然后剩余取平均
        maxTemp = ntcTempBuff[0];
        minTemp = maxTemp;
        sumTemp = maxTemp;
        for (idx = 1; idx < NTC_TEMP_BUFF_NUM; idx++)
        {
            thisTemp = ntcTempBuff[idx];
            if (thisTemp > maxTemp)
                maxTemp = thisTemp;
            if (thisTemp < minTemp)
                minTemp = thisTemp;
            sumTemp += thisTemp;
        }

        currTemp = (sumTemp - maxTemp - minTemp) >> 2;

        //通过PID计算加热周期数
        CalPidResult();
    }
}

//在数码管上显示温度
//此函数仅更新段码到内存缓冲区,然后由Tick中断函数输出到数码管显示,
//Tick中断每5ms扫描一次数码管,无闪烁
void DisplayTemp(signed char temp)
{
    if (currMode & MODE_NO_NTC) //显示EE
    {
        digit0Seg = segMap[SEG_IDX_E];
        digit1Seg = digit0Seg;
    }
    else if (temp < -9) //显示LL
    {
        digit0Seg = segMap[SEG_IDX_L];
        digit1Seg = digit0Seg;
    }
    else if (temp > 99) //显示HH
    {
        digit0Seg = segMap[SEG_IDX_H];
        digit1Seg = digit0Seg;
    }
    else if ((temp >= 0) && (temp < 10)) //0-9则高位消隐
    {
        digit0Seg = segMap[temp];
        digit1Seg = 0xff;
    }
    else if (temp < 0)
    {
        temp = -temp;
        digit0Seg = segMap[temp];
        digit1Seg = segMap[SEG_IDX_DASH];
    }
    else
    {
        digit1Seg = segMap[temp / 10];
        digit0Seg = segMap[temp % 10];
    }
}

//显示子程序
void Display()
{
    //如果不是正常状态,则在数码管上闪烁设定的温度或错误信息
    if (currMode)
    {
        if (halfSecond)
            DisplayTemp(cfgTemp);
        else
        {
            digit0Seg = 0xff;
            digit1Seg = 0xff;
        }
    }
    else
    {
        DisplayTemp(currTemp);
    }
}

//中断服务
void interrupt Tick()
{
    if (TMR2IE && TMR2IF) //定时器2中断服务程序
    {
        TMR2IF = 0;

        LED_DIGIT_1 = 1;
        LED_DIGIT_0 = 1;

        if ((++tickNum % 100) == 0)
            halfSecond = !halfSecond;
        if (btnIdleTicks < 2000)
            btnIdleTicks++;

        //加热处理
        if ((currMode == MODE_NORMAL) && (pidResult > 0))
        {
            PORT_HEATER = 1;
            pidResult--;
        }
        else
        {
            PORT_HEATER = 0;
        }

        //数码管消隐
        delayit(5);

        //动态扫描LED
        revertLed = !revertLed;
        if (revertLed)
        {
            PORTB = digit0Seg;
            if (digit0Seg != 0xff)
                LED_DIGIT_0 = 0;
        }
        else
        {
            PORTB = digit1Seg;
            if (digit1Seg != 0xff)
                LED_DIGIT_1 = 0;
        }
    }
}

//======================================================
//主函数入口
//======================================================
void main()
{
    //关闭模拟比较器
    //CM2 = 1;
    //CM1 = 1;
    //CM0 = 1;
    CMCON = 0x07;

    //关闭USART
    SPEN = 0;

    TRISA = TRISA_INIT_VALUE;
    PORTA = PORTA_INIT_VALUE;
    TRISB = TRISB_INIT_VALUE;
    PORTB = PORTB_INIT_VALUE;

    delayit(10000);

    //TIMER1设定为同步定时器,预分频1,当前暂停计数
    //TIMER1用于IO口测电阻时计数使用
    T1CON = 0b00000000;
    TMR1IE = 0;

    //TIMER2产生一个5ms的定时中断
    T2CON = 0B00100101;
    PR2 = 249;
    TMR2IE = 1;
    PEIE = 1;
    GIE = 1;

    //启动wdt,预分频128,溢出时间大约2.3s
    OPTION_REG = 0b10001111;

    //TO位非零:不是wdt复位
    if (STATUS & 0x10)
        currMode |= MODE_SETTING;

    RestoreCfgFromEeprom();

    while (1)
    {
        GetCurrentTemp();
        ScanButtons();
        Display();
        asm("CLRWDT");
    }
}



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

使用道具 举报

沙发
ID:69862 发表于 2016-3-7 09:06 | 只看该作者
can't open include file "defineports.h":No such file or directory,
不能打开defineports.h,没有这样的目录,你用的PIC什么型号?重新加一个头文件就可以了。
回复

使用道具 举报

板凳
ID:105780 发表于 2016-3-7 22:33 | 只看该作者
PIC单片机制作一个恒温暖手暖脚暖身器,NTC IO测温.rar (5.66 KB, 下载次数: 4)         编译有问题,提示出错

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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