切换到宽版
爱科技/爱创意/爱折腾/爱极致;技术知识分享平台,点击进入新版数码之家网站
  • 21379阅读
  • 75回复

[工仪]~~数显白光技术预览版发布~~ [复制链接]

上一主题 下一主题
离线elecfun
 

发帖
1330
M币
164
专家
12
粉丝
87
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2011-03-20
哈哈,今天终于实现了白光控制器的基本功能。
此次是技术预览版,故只有基本功能,其它功能将在后期陆续加入。
目前实现功能:
1、烙铁温度读取;
2、PWM加热;
3、PID控温;
4、单按键控制加热与否。

由于刚刚才实现基本功能,还没有加上冷端补偿;手上51板的按键都在P1口,所以也只加了一个按键,没有加入温度调整;PID还没有调好,升温较慢;手上只有NMOS管,且自举电路有问题,另在1N4148上端与地之间并了一0.02uF电容。

源程序及电路图下载      



/* 白光控制器技术预览版
* elecfun
* 2011-3-20
*      实现基本功能
*/


#include "STC_NEW_8051.H"
#include <intrins.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "LCD1602.H"

#define FOSC    11187107
#define BAUD    1200

#define BG_ON   P1&=~(1<<3)
#define BG_OFF  P1|=(1<<3)
#define BG_CPL  P1^=(1<<3)

#define PORT_KEY P1     //按键接口
#define KEY_ON   0x20   //按键位置

#define TTNUM   10

unsigned char
  idata tArr[TTNUM];
unsigned char
ptArr;
unsigned char
keyOne,keyAll;        //按键
bit isWork=0;
unsigned char
pwm;                  //系统PWM值
unsigned int t;
unsigned int
intT=1;

struct
PID {  
    unsigned int
SetPoint;      // 设定目标 Desired Value  
    double Proportion;          // 比例常数 Proportional Const  
    double Integral;            // 积分常数 Integral Const  
    double Derivative;          // 微分常数 Derivative Const  
    unsigned int LastError;     // 上次误差
    unsigned int PrevError;     // 上上次误差  
    unsigned int SumError;      // 累积误差
};  
struct
PID spid;

//PID计算
unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )  
{
  
    int
dError,Error;  
    Error = pp->SetPoint - NextPoint;           // 偏差        
    pp->SumError += Error;                      // 积分          
    dError = pp->LastError - pp->PrevError;     // 当前微分  
    pp->PrevError = pp->LastError;          
    pp->LastError = Error;      
    return
(pp->Proportion * Error              // 比例项        
        + pp->Integral * pp->SumError           // 积分项  
        + pp->Derivative * dError);             // 微分项  
}  

//读按键值
void KeyRead( void )
{

    unsigned char
readData;
    PORT_KEY |= (KEY_ON);
    readData = PORT_KEY^0xff;                   //读端口值,并取反
    keyOne = readData & (readData ^ keyAll);    //只在第一次按下时为按键值,以后为0
    keyAll = readData;                          //长按、短按都为按键值
}

void
Delayms(unsigned int dm)
{

    unsigned int
d1,d2;
    for
(d1=0; d1<dm; d1++)
        for
(d2 = 0; d2<666; d2++)
            ;
}


unsigned char
GetADCResult(unsigned char ch)
{

    ADC_CONTR = ADC_POWER | ADC_SPEEDL | ch | ADC_START;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    while
(!(ADC_CONTR & ADC_FLAG));//等待完成
    return ADC_RES;                 //返回8位值
}

//ADC初始化
void InitADC()
{

    P1ASF = 1<<7;
    P1M0 =  1<<7;                    //ADC7设置为开漏输入,其它为准双向
    P1M1 =  1<<7;
    ADC_RES = 0;                    
    ADC_CONTR = ADC_POWER | ADC_SPEEDL;
    Delayms(2);
}


//串口初始化
void InitUart()
{

    SCON = 0x5a;
    TMOD = 0x20;                    //T18位自动重载
    TH1 = TL1 = -(FOSC/12/32/BAUD);
    TR1 = 1;
}


//串口发送字符
void SendData(unsigned char dat)
{

    while
(!TI);
    TI = 0;
    SBUF = dat;
}


//串口发送字符串
void SendString(unsigned char *s)
{

    while
(*s++)
    {

        SendData(*s);
    }
}


//读取温度,取平均值
void GetTemp(void)
{

    unsigned char
i;
    unsigned int
tAll=0;
    for
(i=0; i<TTNUM; i++)
    {

        tAll += tArr[i];
    }

    t = tAll / TTNUM;
    Delayms(2);
    tArr[ptArr] = GetADCResult(7);

    if
(++ptArr >= TTNUM)
    {

        ptArr = 0;
    }
}


//PWM初始化
void InitPWM(void)
{

    EA = 1;
    CCON = 0x00;                    //初始化PCA寄存器
    CMOD = 0x00;                    //时钟12分频,禁止溢出中断
    CL = 0;                         //初始化PCA计数器
    CH = 0;
    CCAP0H = CCAP0L = 0x80;         //占空比00%
    CCAPM0 = 0x63;                  //8位PWM,由低变高产生中断
    CR = 1;                         //PCA时钟开始工作
}

//PWM中断函数,读取温度并计算PID值
void PCA_Int(void) interrupt 7      //PCA中断
{
    CR = 0;
    EA = 0;
    intT++;
    if
(intT>20)
    {

        intT=0;
        GetTemp();
        pwm = PIDCalc(&spid, t);
        if
(pwm == 0)
        {

            pwm = 1;
        }
    }

    EA = 1;
    CF = 0;
    CCF0 = 0;
    CR = 1;
}


void
main(void)
{

    float
tt;
    unsigned int
td,tp;
    unsigned char
arr[10];

    InitADC();  
    InitUart();
    Init_LCD1602();
    BG_OFF;
    InitPWM();

    spid.Proportion = 2.0;    //比例常数
    spid.Integral   = 0.0;    //积分
    spid.Derivative = 0.0;    //微分
    spid.SetPoint   = 225;  //目标

    isWork=0;
    while
(1)
    {

        KeyRead();
        if
(keyOne & KEY_ON)
        {

            isWork = ~isWork;
        }


        //此处为温度转换公式,计算得出,可能不准确
        tt = 3.55 * t + 15.8;

        sprintf(arr, "%5.1f", tt);
        LCD1602_DispString(0, 0, arr);                      //显示当前温度

        sprintf(arr, "%3u", spid.SetPoint);
        LCD1602_DispString(8, 0,arr);                       //显示设定温度

        sprintf(arr, "%3u%%",(unsigned int)(pwm*100/255));  //显示当前PWM
        LCD1602_DispString(8, 1, arr);

        if
(isWork)
        {

            CCAP0H = CCAP0L = pwm;
            CR = 1;
            LCD1602_DispString(0,1,"ON ");
        }
else {
            pwm = 1;
            CCAP0H = CCAP0L = pwm;
            LCD1602_DispString(0,1,"OFF");
        }
    }
}

本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共25条打赏M币+138专家+1
关键词: 白光白菜白光
离线hijk1

发帖
2009
M币
6943
专家
1
粉丝
57
只看该作者 1楼 发表于: 2011-03-20
请登录后查看
本帖最近打赏记录:共1条打赏
离线watr

发帖
744
M币
607
专家
2
粉丝
15
只看该作者 2楼 发表于: 2011-03-20
请登录后查看
本帖最近打赏记录:共1条打赏
离线qq1851166

发帖
827
M币
204
专家
4
粉丝
20
只看该作者 3楼 发表于: 2011-03-20
请登录后查看
本帖最近打赏记录:共1条打赏
离线tvrctjheeq

发帖
4463
M币
3474
专家
3
粉丝
41
只看该作者 4楼 发表于: 2011-03-20
请登录后查看
本帖最近打赏记录:共1条打赏
离线懒虫包子

发帖
9556
M币
1654
专家
69
粉丝
590
只看该作者 5楼 发表于: 2011-03-20
请登录后查看
本帖最近打赏记录:共1条打赏
离线散装805

发帖
590
M币
2206
专家
3
粉丝
22
只看该作者 6楼 发表于: 2011-03-20
请登录后查看
本帖最近打赏记录:共1条打赏
离线liubin

发帖
81
M币
4205
专家
1
粉丝
9
只看该作者 7楼 发表于: 2011-03-20
请登录后查看
本帖最近打赏记录:共1条打赏
离线elecfun

发帖
1330
M币
164
专家
12
粉丝
87
只看该作者 8楼 发表于: 2011-03-20
请登录后查看
本帖最近打赏记录:共1条打赏
离线hddlfz

发帖
7480
M币
564
专家
193
粉丝
623
只看该作者 9楼 发表于: 2011-03-21
请登录后查看
本帖最近打赏记录:共1条打赏
快速回复
限80 字节
如果您提交过一次失败了,可以用”恢复数据”来恢复帖子内容
 
上一个 下一个