|
樓主 |
發表於 2013-1-28 01:40:39
|
顯示全部樓層
/*20130124 更改程式防止過255計數問題不再LOCK著ROBOTAI 20130123更改 DA 讀取的技巧 有快速反應與減少重啟動現象 20130121 更改sprintf 功能 減肥 增加餵狗功能 3c 2.27秒 20130109修改增加相關功能變更 點火的時間比例但溫度不穩定,高溫會發生 latch 現象要把看門狗功能加入 20121224 P0 LCM display P1 DtoA convert mith R-2R+74LS373 P2^0 hi/lo active sent to LM4558 op amp volt ,34063 neg 5v generator LM393 comparator for P2^1 bit ,loop d/a must clear each cycle */
#define ADPortL P1//P1.0~P1.7 AD574 low 8bit
#include<reg52.h>
#include<stdio.h>
#include <intrins.h>
#define DataPort P0//P0.0~P0.7 1602 LCM顯示器
#define _Nop() _nop_() //定义空指令
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
sbit CMPDT= P2^1;//compare bit P2^1 for 設定溫度 0到3.3v temperature
sbit CMPD = P2^2;//compare bit P2^2 for 熱偶溫度 250度 2.9v
sbit LTH = P2^0;//74ls373 latch bit
sbit Fire = P2^3;//控制SSR動作 LO點火 HI 關斷
sbit RS = P2^4;//P1^0;//LCM指令Lo/資料Hi
sbit RW = P2^5;//P1^1;//讀出 Hi/寫入Lo
sbit EN = P2^6;//P1^2;//動作觸發 Hi>>Lo
//bit SHV_flag;// latch volt
//bit SHT_flag;//latch temp
bit SH_flag;//clean show flag
char DisplayWord[16];//顯示第一行工作的狀況
//char DisplayAWord[16];// 顯示第二行工作的狀況
unsigned char counter; //T0使用的1/100計數器.
unsigned char TimeFlag; //T0計數1秒的使用旗標.
unsigned int ADget(void);
unsigned char ADT,ADTT, AVOS;
unsigned char ADVL;//ADVL display AD data
void DelayMs(unsigned char);
void DelayUs2x(unsigned char);
void Init_Timer0(void);//定?器初始化
void LCD_Write_String(char x,char y, char *s);
void LCD_Write_Char(char x,char y,char Data);
void LCD_Clear(void);
unsigned int SV,AV;//換算後的設定溫度,換算後的熱偶溫度
unsigned char Lst_ADT,Lst_ADTT;//最後一次的ADT ADTT 最為下一次的ad轉換基底值
//********20130127 手動增加溫度+10-5 檢查此兩位若被按下,跳彈檢查若成立則增加或減少ASV設定
sbit T_inc = P3^2;//inc temp set 10 DEG
sbit T_dec = P3^4;//dec temp set 5 DEG
bit Pres;//inc dec 按鍵被按下
signed char ASV;//手動加減溫度
//************************************
//當差異50度時候輸出30% ----20130109
void fir30(void)
{
Fire=0;
DelayMs(10+AVOS);
Fire=1;
DelayMs(3);
}
//當差異20度時候輸出10%
void fir10(void)
{
Fire=0;
DelayMs(6+AVOS);
Fire=1;
DelayMs(6);
}
//當差異5度時候 輸出2%
void fir2(void)
{
Fire=0;
DelayMs(3+AVOS);
Fire=1;
DelayMs(10);
}
void Fireout (void)
{
signed int Difv;
Difv=SV-AV;
AVOS=SV/100;//temp offset compensator
if(Difv>50)
Fire=0;//全輸出
else if((Difv>20)&&(Difv<=50))
fir30();//30%
else if((Difv>5)&&(Difv<=20))
fir10();//10%
else if((Difv>0)&&(Difv<=5))
fir2();//5%
else
Fire=1;// 全關閉輸出
}
//-----------------DAO-------------------
void DAO(void)//DA converter DAO 熱偶溫度
{
unsigned char DA;
if(Lst_ADT>=30)
DA=(Lst_ADT-30);
else
DA=0;
while(!CMPD)//compare bit P2^2 取得熱偶溫度讀取的轉態最多256ms
{
ADPortL=DA;
LTH=1;
LTH=0;
DelayMs(1);
if(DA == 0xFF)
break; //reach max, break out
DA++;
}
ADT=DA;//ADVL display AD data
Lst_ADT=ADT;//記憶最後一次ad讀值
ADPortL=0;
LTH=1;
LTH=0;
DelayMs(1);
SH_flag=1;// show flag
}
//-------------DAO2--------------------
void DAO2(void)//DA converter DAO2設定溫度
{
unsigned char DA;
if(Lst_ADTT>=30)//若溫度讀值大於30
DA=(Lst_ADTT-30);
else
DA=0;
while(!CMPDT)//compare bit P2^1 取得溫度設定的轉態最多256ms
{
ADPortL=DA;
LTH=1;
LTH=0;
DelayMs(1);
if(DA == 0xFF)
break; //reach max, break out
DA++;
}
ADTT=DA;//ADVL display AD data
Lst_ADTT=ADTT;//記憶最後一次ad讀值
ADPortL=0;
LTH=1;
LTH=0;
DelayMs(1);
SH_flag=1;// show flag
}
/*------------ LCM 顯示相關程式--------*/
bit LCD_Check_Busy(void) //檢查是否為"忙碌"
{
DataPort= 0xFF;
RS_CLR; // 指令模式
RW_SET; //寫入模式
EN_CLR; //***特別**** 啟動由LO變成HI **************
_nop_();
EN_SET; //***特別**** 啟動由LO變成HI **************
return (bit)(DataPort & 0x80);//若 讀出的資料bit7 =0 可以寫資料
}
void LCD_Write_Com(char com) //命令寫入
{
while(LCD_Check_Busy()); //忙则等待 1=while loop still;
RS_CLR; //指令功能
RW_CLR; //寫入
EN_SET; //下降緣 由HI變成LO
DataPort= com; // 指令設定
_nop_();
EN_CLR;//
}
void LCD_Write_Data(char Data) //資料寫入
{
while(LCD_Check_Busy()); //忙则等待
RS_SET; // 資料處理
RW_CLR;// 寫的動作
EN_SET; // 啟動下緣觸發
DataPort= Data; //輸入需要寫入的資料
_nop_();//延後一個時間
EN_CLR;//
}
void LCD_Clear(void)
{
LCD_Write_Com(0x01); //清屏指令
DelayMs(5);//時間延遲5ms.
}
void LCD_Write_String(char x,char y, char *s)
{
if (y == 0) //y 表示第一行或是第二行
{
LCD_Write_Com(0x80 + x); //表示第一行bit4 Hi+ x position
}
else
{
LCD_Write_Com(0xC0 + x); //表示第二行 bit4 Hi+40+x position
}
while (*s)
{
LCD_Write_Data( *s); // *s 和 s 不一樣,*s 應該是字串 s是字數
s ++;
}
}
/*
void LCD_Write_Char(char x, char y, char Data)
{
if (y == 0) //第一行
{
LCD_Write_Com(0x80 + x); //第幾個字的位置
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data( Data); //字
}
*/
void LCD_Init(void)
{
LCD_Write_Com(0x38); /*显示模式设置*/
DelayMs(5);
LCD_Write_Com(0x38); //8bit data 2 line 5x7 character.
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*显示关闭*/
LCD_Write_Com(0x01); /*显示清屏*/
LCD_Write_Com(0x06); /*显示光标移动设置*/
DelayMs(5);
LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
void DelayUs2x(unsigned char t)
{
while(t--);
}
void DelayMs(unsigned char t)
{
while(t--);
{
DelayUs2x(245);//from245>>45
DelayUs2x(245);
}
}
//--------------------------------------------------------------------------------------------
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定?器,使用"|"符?可以在使用多?定?器?不受影?
TH0= (65536-2000)/256; // 0x0D8 2ms if 12Mcristal
TL0= (65536-2000)%256;// 0x0F0
EA=1;
ET0=1;
TR0=1;
}
//--------------------------------------------------------------------------------------------
void Timer0_isr(void) interrupt 1
{
TH0= (65536-2000)/256; // 0x0D8 2ms if 12Mcristal
TL0= (65536-2000)%256;// 0x0F0
counter++;//counter is Global variable.
if(counter==10)
DAO2();//溫度設定可變電阻電壓 ADTT 255ms
if(counter==40)
DAO();//熱偶溫度讀取 ADT 255ms
// ADTT=150;//**************************************
if(counter==70) //140ms更新一次
{
counter=0;
TimeFlag=1; //計數器中斷約1秒時設定旗標為1,
//******************
if(Pres==1)
{
if(T_inc==0)
{
Pres=0;
ASV=ASV+10;
if(ASV>100)
ASV=100;
}
if(T_dec==0)
{
ASV=ASV-5;
Pres=0;
if(ASV<0)
ASV=0;
}
}
WDT_CONTR = 0x3d;//餵狗
//*************20130127*****
}
}
void main(void)
{
Init_Timer0();//起始定時器
LCD_Init();// LCM 啟動
LCD_Clear();//LCM清屏
//sprintf(DisplayWord," AD data %5d",00000);//顯示AD為零
Fire=1;//OFF Power
WDT_CONTR = 0x3d;//餵狗2.27s
Lst_ADT=0;//清除基底避免干擾ad讀取
Lst_ADTT=0;
while(1)
{
if(AV>505)
{
Fire=1;
}
if(TimeFlag==1)//每140Ms 更新一次
{
TimeFlag=0;//清除定時旗標
if(SH_flag==1)// show flag
{
SH_flag=0;
DisplayWord[0]=' ';
DisplayWord[1]='S';//Tab[IRcord[0]/16];
DisplayWord[2]='E';//Tab[IRcord[0]%16];
DisplayWord[3]='T';
DisplayWord[4]='=';//time_buf1[5]/10+'0';
DisplayWord[5]= ADTT/100+'0';
DisplayWord[6]= ADTT/10%10+'0';
DisplayWord[7]= ADTT%10%10+'0';
DisplayWord[8]= ' ';
DisplayWord[9]= 'T';
DisplayWord[10]='C';
DisplayWord[11]=':';
DisplayWord[12]= ADT/100+'0';;
DisplayWord[13]= ADT/10%10+'0';
DisplayWord[14]= ADT%10%10+'0';
DisplayWord[15]=' ';
// ADT熱偶溫度 ADTT設定溫度顯示第一組的計數 第二組的計數
LCD_Write_String(0,0, DisplayWord);//顯示在第一行
SV=ADTT+200+ASV;AV=ADT*2;//20130109 設定值增加200度 設定VR 1COUNT 1度(最多365度) 溫度顯示值1COUNT 2度 增加一個VR調整溫度的 SPAN 最多360度
DisplayWord[0]=' ';
DisplayWord[1]='S';//Tab[IRcord[0]/16];
DisplayWord[2]='E';//Tab[IRcord[0]%16];
DisplayWord[3]='T';
DisplayWord[4]='=';//time_buf1[5]/10+'0';
DisplayWord[5]= SV/100+'0';
DisplayWord[6]= SV/10%10+'0';
DisplayWord[7]= SV%10%10+'0';
DisplayWord[8]= ' ';
DisplayWord[9]= 'T';
DisplayWord[10]='C';
DisplayWord[11]=':';
DisplayWord[12]= AV/100+'0';;
DisplayWord[13]= AV/10%10+'0';
DisplayWord[14]= AV%10%10+'0';
DisplayWord[15]=' ';
LCD_Write_String(0,1, DisplayWord);//顯示在第二行
}
}
Fireout();//改到外環
if((!T_inc))//手動加溫剪溫
{
while(!T_inc);
Pres=1;
}
if((!T_dec))
{
while(!T_dec);
Pres=1;
}
}
}
|
|