|
【簡要說明】
尺寸:長79mmX寬50mmX高22mm
一、主要芯片:STC15W408AS
二、工作電壓:直流6~24伏
三、支持:UATR接口下載程序
【板子特點】
1、6V~24V寬電壓輸入;
2、具有電源指示功能;
3、繼電器輸出最大支持220V 10A;
4、3位數碼管顯示;
5、雙按鍵溫度可調;
6、測量溫度范圍0~99度
7、采用螺旋端子壓接,接線可靠方便擴展;
8、供電具有防反接保護。電路工作穩定可靠;
9、工作環境:濕度小于80%,溫度 -0度至50度
10、提供相關軟件、原理圖 例程及相關資料;
/********************************************************************
宏定義
*********************************************************************/
#include<STC15W408AS.h> //庫文件
#include<intrins.h>
#define uchar unsigned char//宏定義無符號字符型
#define uint unsigned int //宏定義無符號整型
#define ADC_POWER 0x80 //ADC 電源控制位
#define ADC_FLAG 0x10 //ADC 轉換結束標志位
#define ADC_START 0x08 //ADC 開始轉換控制位
#define ADC_SPEEDLL 0x00 //210 個時鐘周期轉換一次
#define ADC_SPEEDL 0x20 //420 個時鐘周期轉換一次
#define ADC_SPEEDH 0x40 //630 個時鐘周期轉換一次
#define ADC_SPEEDHH 0x60 //840 個時鐘周期轉換一次
typedef unsigned char INT8U;
typedef unsigned int INT16U;
#define ENABLE_ISP 0x82 //系統工作時鐘<20MHz 時,對IAP_CONTR 寄存器設置此值
#define WD1 0x5a //使用STC11xx系列單片機時,先寫入0x5a,然寫入0xa5
#define WD2 0xa5
char IAPAddr=0;
/********************************************************************
初始定義
*********************************************************************/
code uchar seg7code[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //顯示段碼 數碼管字跟
code uint wendu[106][2]={//溫度與電阻阻值對應關系表格
0,3274,//0度對應阻值32.74k
1,3111,//1度對應阻值31.11k
2,2957,//2度對應阻值29.57k
3,2812,//
4,2674,//
5,2545,
6,2422,
7,2306,
8,2196,
9,2092,
10,1993,
11,1900,
12,1811,
13,1728,
14,1648,
15,1573,
16,1501,
17,1433,
18,1369,
19,1308,
20,1250,
21,1194,
22,1142,
23,1092,
24,1045,
25,1000,//25度對應阻值10k
26,957,//26度對應阻值9.57k
27,916,
28,877,
29,840,
30,805,
31,771,
32,739,
33,709,
34,679,
35,652,
36,625,
37,600,
38,576,
39,553,
40,531,
41,510,
42,490,
43,471,
44,453,
45,435,
46,418,
47,402,
48,387,
49,372,
50,358,
51,345,
52,332,
53,320,
54,308,
55,297,
56,286,
57,276,
58,266,
59,256,
60,247,
61,238,
62,230,
63,222,
64,214,
65,207,
66,199,
67,193,
68,186,
69,180,
70,174,
71,168,
72,162,
73,157,
74, 152,
75, 147,
76, 142,
77, 137,
78, 133,
79, 128,
80, 124,
81, 120,
82, 116,
83, 113,
84, 109,
85, 106,
86, 102,//86度對應阻值1.02k
87, 99,//87度對應阻值0.99k
88, 96,
89, 93,
90, 90,
91, 88,
92, 85,
93, 82,
94, 80,
95, 78,
96, 75,
97, 73,
98, 71,
99, 69,
100,67,
101,65,
102,63,
103,61,
104,59,
105,58//105度對應阻值0.58k
};
/********************************************************************
I/O定義
*********************************************************************/
bit z=0,ba=0,k=0,zs=0;
uchar y=0,smg2=0,s1=0,s2=0,ii=0;
uint s=0,bai=0,shi=0,ge=0,js=0,dat=0,dat1=0,dat2=0;
sbit aj1=P5^4;
sbit aj2=P5^5;
sbit out=P3^4;
sbit L1=P3^5;//數碼管位控制
sbit L2=P3^6;//數碼管位控制
sbit L3=P3^7;//數碼管位控制
sbit dp=P3^3;//小數點
bit kt=0,kt_1=0;
uchar trg=0,trg_1=0,cont=0,cont_1=0;
uchar ReadData=0,ReadData_1=0;
/********************************************************************
E2P函數
*********************************************************************/
union union_temp16
{
INT16U un_temp16;
INT8U un_temp8[2];
}my_unTemp16;
INT8U Byte_Read(INT16U add); //讀一字節,調用前需打開IAP 功能
void Byte_Program(INT16U add, INT8U ch); //字節編程,調用前需打開IAP 功能
void Sector_Erase(INT16U add); //擦除扇區
void IAP_Disable(); //關閉IAP 功能
/********************************************************************
AD轉換初始化程序
*********************************************************************/
void InitADC()
{
P1ASF = 0x80; //設置P1.7口AD轉換,必須加
P1M0=0X80;
P1M1=0X80; //設置P1.7口為開漏模式,使用AD功能
ADC_RES = 0; //AD數據寄存器清空
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;//打開AD電源,轉換周期210
_nop_(); //延時一個機器周期
_nop_();
_nop_(); //延時一個機器周期
}
/********************************************************************
AD轉換控制程序
*********************************************************************/
uchar ADCRead(uchar px) //轉換輸出的數據 (PX為通道口)
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL |px| ADC_START;//開始轉換
_nop_(); //延時一個機器周期
_nop_(); //延時一個機器周期
_nop_(); //延時一個機器周期
_nop_(); //延時一個機器周期
while (!(ADC_CONTR & ADC_FLAG));//等待轉換結束
ADC_CONTR &= ~ADC_FLAG; //關閉AD轉換
return ADC_RES; //返回數據
}
/*******************************************************************
* 讀取按鍵狀態
********************************************************************/
void KeyRead()//讀取按鍵IO口函數
{
ReadData = aj1^0xff; // 讀取按鍵狀態取反后賦值給ReadData
trg = ReadData & (ReadData ^ cont); //trg短按,每按下按鍵trg=1;抬手后為trg=0,長按為trg=0
cont = ReadData; //cont長按,長按cont=1,抬手后cont=0
ReadData_1 = aj2^0xff; // 讀取按鍵狀態取反后賦值給ReadData
trg_1 = ReadData_1 & (ReadData_1 ^ cont_1); //trg短按,每按下按鍵trg=1;抬手后為trg=0,長按為trg=0
cont_1 = ReadData_1; //cont長按,長按cont=1,抬手后cont=0
}
/*******************************************************************
* 按鍵
********************************************************************/
void key_1()
{
if(trg & 0x01) //短按
{
kt_1=0;
kt=1; //這是短按標志位,kt=1說明短按了
}
if((aj1!=0)&&(kt==1))//判斷
{
z=1; // 選位標志位
y++; //選位
out=1;
if(y==4)
{
z=0;
k=1;
y=0;
// s=s1+s2+s3;
}
kt=0;
} // 短按
}
void key_2()
{
if(trg_1 & 0x01) //短按
{
kt=0;
kt_1=1; //這是短按標志位,kt=1說明短按了
}
if((aj2!=0)&&(kt_1==1))//判斷
{
if(y==1)
{
s1++;
if(s1>9)
{
s1=0;
}
}
if(y==2)
{
s2+=10;
if(s2>90)
{
s2=0;
}
}
s=s1+s2;
kt_1=0;
} // 短按
}
/*******************************************************************
* 定時器配置
********************************************************************/
void ConfigTimer0(){
TMOD=0x01;//將定時器0,1都設置為模式1
TH0=0XFC;//1ms
TL0=0X66;
TR0=1;//開啟定時器0
ET0=1;//開定時器0的中斷
EA=1;//開總中斷
}
/*******************************************************************
* 顯示
********************************************************************/
void led(uint date)
{
bai=date/100;
shi=date%100/10;
ge=date%10;
}
/*******************************************************************
* t0定時器
********************************************************************/
void timer0() interrupt 1
{
TH0=0XFC;//1ms
TL0=0X66;
js++;
if(js==200){ba=1;js=0;}
if(z==0){
smg2++;
}
else{
smg2=y;//讓逐個顯示位
}
switch(smg2){ //數碼管掃描
/**************數碼管-開始*****************/
case 1: if(y==0){P1=0x39;} else {P1=seg7code[ge];}L3=1;L2=1;L1=0;dp=0;break;//從P2進P0出
case 2: P1=seg7code[shi];L3=1;L2=0;L1=1;if(zs==0){dp=0;}else{dp=1;}break;
case 3: P1=seg7code[bai]; L3=0;L2=1;L1=1;dp=0;break;
/**************數碼管-結束*****************/
default: smg2=0; L3=1;L2=1;L1=1; break;
}
}
/********************************************************************
主函數
*********************************************************************/
void main()
{
ConfigTimer0(); //定時器初始化
InitADC(); //AD初始化
P1M0 = 0xff; //設置強推挽和開漏模式
P1M1 = 0x80;
P3M0 = 0x08; //小數點使用
P3M1 = 0x00;
if(Byte_Read(0X0001)==0xff){s1=0;s2=0;}//首次讀取,如果讀到0xFF說明沒有存過數據,直接付給00值
else
{
s1=Byte_Read(0X0001);
s2=Byte_Read(0X0002);
}
s2=s2*10;
s=s2+s1;
while(1)
{
if(ba==1){
dat=((ADCRead(7)*51)/255);
dat1=(dat*1000)/(51-dat);
for(ii=0;ii<106;ii++) {
if((dat1 <= wendu[ii][1]) && (dat1 > wendu[ii+1][1])){ //對比列表查找溫度
dat2=(wendu[ii][0]);//dat2為溫度值
ii=0;
break;
}
}
ba=0;
} //51是單片機的工作電壓,單片機的工作電壓是多少這個就是多少
if((y==0)&&(z==0)){zs=1;led((dat2*10));} //zs標志位控制小數點
if(y==1){zs=0;led(s1);}
if(y==2){zs=0;led(s2);}
if(y==3){zs=0;z=0;led(s);}
if(dat2>s){out=0;}else{out=1;}
KeyRead(); //按鍵掃描
key_1();
key_2();
if(k==1)
{
Sector_Erase(0);
Byte_Program(0x0001,s1); //寫入扇區
Byte_Program(0x0002,(s2/10)); //寫入扇區
k=0;
}
}
}
//讀一字節,調用前需打開IAP 功能,入口:DPTR = 字節地址,返回:A = 讀出字節
INT8U Byte_Read(INT16U add)
{
IAP_DATA = 0x00;
IAP_CONTR = ENABLE_ISP; //打開IAP 功能, 設置Flash 操作等待時間
IAP_CMD = 0x01; //IAP/ISP/EEPROM 字節讀命令
my_unTemp16.un_temp16 = add;
IAP_ADDRH = my_unTemp16.un_temp8[0]; //設置目標單元地址的高8 位地址
IAP_ADDRL = my_unTemp16.un_temp8[1]; //設置目標單元地址的低8 位地址
//EA = 0;
IAP_TRIG = WD1; //先送 WD1,再送WD2 到ISP/IAP 觸發寄存器,每次都需如此
IAP_TRIG = WD2; //送完WD2 后,ISP/IAP 命令立即被觸發起動
_nop_();
//EA = 1;
IAP_Disable(); //關閉IAP 功能, 清相關的特殊功能寄存器,使CPU 處于安全狀態,
//一次連續的IAP 操作完成之后建議關閉IAP 功能,不需要每次都關
return (IAP_DATA);
}
/*********************************************************************************************/
//字節編程,調用前需打開IAP 功能,入口:DPTR = 字節地址, A= 須編程字節的數據
void Byte_Program(INT16U add, INT8U ch)
{
IAP_CONTR = ENABLE_ISP; //打開 IAP 功能, 設置Flash 操作等待時間
IAP_CMD = 0x02; //IAP/ISP/EEPROM 字節編程命令
my_unTemp16.un_temp16 = add;
IAP_ADDRH = my_unTemp16.un_temp8[0]; //設置目標單元地址的高8 位地址
IAP_ADDRL = my_unTemp16.un_temp8[1]; //設置目標單元地址的低8 位地址
IAP_DATA = ch; //要編程的數據先送進IAP_DATA 寄存器
//EA = 0;
IAP_TRIG = WD1; //先送 WD1,再送WD2 到ISP/IAP 觸發寄存器,每次都需如此
IAP_TRIG = WD2; //送完WD2 后,ISP/IAP 命令立即被觸發起動
_nop_();
//EA = 1;
IAP_Disable(); //關閉IAP 功能, 清相關的特殊功能寄存器,使CPU 處于安全狀態,
//一次連續的IAP 操作完成之后建議關閉IAP 功能,不需要每次都關
}
/*********************************************************************************************
//擦除扇區, 入口:DPTR = 扇區地址 */
void Sector_Erase(INT16U add)
{
IAP_CONTR = ENABLE_ISP; //打開IAP 功能, 設置Flash 操作等待時間
IAP_CMD = 0x03; //IAP/ISP/EEPROM 扇區擦除命令
my_unTemp16.un_temp16 = add;
IAP_ADDRH = my_unTemp16.un_temp8[0]; //設置目標單元地址的高8 位地址
IAP_ADDRL = my_unTemp16.un_temp8[1]; //設置目標單元地址的低8 位地址
//EA = 0;
IAP_TRIG = WD1; //先送 WD1,再送WD2 到ISP/IAP 觸發寄存器,每次都需如此
IAP_TRIG = WD2; //送完WD2 后,ISP/IAP 命令立即被觸發起動
_nop_();
//EA = 1;
IAP_Disable(); //關閉IAP 功能, 清相關的特殊功能寄存器,使CPU 處于安全狀態,
//一次連續的IAP 操作完成之后建議關閉IAP 功能,不需要每次都關
}
/*********************************************************************************************/
void IAP_Disable()
{
//關閉IAP 功能, 清相關的特殊功能寄存器,使CPU 處于安全狀態,
//一次連續的IAP 操作完成之后建議關閉IAP 功能,不需要每次都關
IAP_CONTR = 0; //關閉IAP 功能
IAP_CMD = 0; //清命令寄存器,使命令寄存器無命令,此句可不用
IAP_TRIG = 0; //清命令觸發寄存器,使命令觸發寄存器無觸發,此句可不用
IAP_ADDRH = 0;
IAP_ADDRL = 0;
}
/*********************************************************************************************/
|
|