📄 vaccum.c
字号:
/************************************************************************
copyright (c) 2007
Titl Altitud meter
Current version: v1.0
Function: Measure temperature / pressure / altitude
Processor C8051F230 + HP03S
Clock: 22.1184MHz Crystal
Author: jIM tIEN
Company: cROSSMIND
Contact: +86-0755-3880100
E-MAIL: txj@crossmind.cn
Date: 2008-4-11
P0.4---------------->SCL
P0.5<--------------->SDA
P0.6---------------->XCLR
P0.7---------------->MCLK
********************************************************************/
#include <c8051f200.h>
#include <stdio.h>
//#include <reg52.h>
#include <math.h>
#define MaxPress 1100 //1100Hpa
#define SYSCLK 22118400 //11059200
#define HP03SMCLK 32768
//V3.1
//#define BAUDRATE 115200
//V3.2
#define BAUDRATE 38400
#define RS485
#define TIMEOUT 60 //unit: =60*0.5 second
#define INBUF_LEN 5 //数据长度
#define STARTBYTE 0x24 //
#define MYADD 0xE4 //Barmeter Add = 0xE4
//MOTOR MODULE ADD = 0xE3 , 0xE2 - LDDRIVER, 0xE1 - PZT DRIVER
#define GETTEMP 0xAA //取温度/压力值命令
#define GETPRESS 0XBB //压力值命令
#define SETDATA 0xCC //设置相对气压值
#define ORIGNAL 0xDD //设置当前气压为基准气压
#define VACCUMON 0x01 //启动抽气机
#define VACCUMOFF 0x00 //关闭抽气机
#define RELEASEON 0x02 //排空阀ON
#define RELEASEOFF 0x03 //排空阀OFF
unsigned char inbuf1[INBUF_LEN];
unsigned char count;
bit read_flag = 0;
//function declaration
//*****************
void IIC_ReadCalData(void);
void ReadTemperaturePreesureAD(void);
unsigned int IIC_ReadTempretureAD(void);
unsigned int IIC_ReadPressureAD(void);
void CalculatePressTemp(bit);
void CalculateAltitude(void);
void IIC_ReadCalData(void);
unsigned char IIC_ReadByte(void);
void IIC_WriteByte( unsigned char);
void IIC_Start(void);
void IIC_Stop(void);
void IIC_ACK(void);
void IIC_NoAck(void);
void IIC_SDA_HIGH(void);
void IIC_SDA_LOW(void);
void IIC_SCL_HIGH(void);
void IIC_SCL_LOW(void);
void IIC_XCLR_LOW(void);
void IIC_XCLR_HIGH(void);
void SysDelay2ms(unsigned int);//
void SysDelay20us(void);//
void ClockDelay2ms(unsigned int);//
void MCLKOn(void);
//symbol defined
sbit SCL = P2^0;
sbit SDA = P2^1;
sbit XCLR = P2^2;
sbit MCLK = P2^3;
#ifdef RS485
sbit RS485_DE = P1^0;
#endif
sbit RELAY = P1^1; //CONTROL VACCUM
sbit RELAY2 = P1^3; //排空阀
sbit TestPin = P1^2;
unsigned int C1;
unsigned int C2 ;
unsigned int C3 ;
unsigned int C4 ;
unsigned int C5 ;
unsigned int C6 ;
unsigned int C7 ;
unsigned char AAA;
unsigned char BB ;
unsigned char CC ;
unsigned char DD ;
unsigned int D1;
unsigned int D2 ;
long float DUT;
long float OFF;
long float SENS;
long float X;
long float Press;
long float Temp;
long Altitude;
bit bMCLKOn = 0;
unsigned int systimer1;
//**********************************
//comparison table for pressure and altitude
//***********************************
long code Tab_BasicAltitude[80]={-6983,-6201,-5413,-4620,-3820,-3015,-2203,-1385,-560, 270, //0.1m
// 1100 1090 1080 1070 1060 1050 1040 1030 1020 1010 //hpa
1108, 1953, 2805, 3664, 4224, 5403, 6284, 7172, 8068, 8972,
// 1000 990 980 970 960 950 940 930 920 910 //hpa
9885, 10805,11734,12671,13617,14572,15537,16510,17494,18486,
// 900 890 880 870 860 850 840 830 820 810 //hpa
19489,20502,21526,22560,23605,24662,25730,26809,27901,29005,
// 800 790 780 770 760 750 740 730 720 710 //hpa
30121,31251,32394,33551,34721,35906,37106,38322,39553,40800,
// 700 690 680 670 660 650 640 630 620 610 //hpa
42060,43345,44644,45961,47296,48652,50027,51423,52841,54281,
// 600 590 580 570 560 550 540 530 520 510 //hpa
55744,57231,58742,60280,61844,63436,65056,66707,68390,70105,
// 500 490 480 470 460 450 440 430 420 410 //hpa
71854,73639,75461,77323,79226,81172,83164,85204,87294,89438};
// 400 390 380 370 360 350 340 330 320 310 //hpa
void SYSCLK_Init(void)
{
int i; // delay counter
//initial system clock
OSCXCN = 0x67; // start external oscillator with 22.1184MHz crystal
for (i=0; i < 256; i++) ; // Wait for osc. to start up
while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle
OSCICN = 0x88; // select external oscillator as SYSCLK source and enable missing clock detector
}
void PORT_Init (void)
{
//uart0, p1.0/p1.1/P1.2/P1.3/p2.0/p2.2/p2.3 push-pull
PRT0MX = 0x01;
PRT1CF = 0x0F;
PRT2CF = 0x0D;
RELAY = 0;
}
void Serial_Init(void)
{
SCON = 0x50; // SCON1: mode 1, 8-bit UART, enable RX
TMOD &= 0x0F;
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reload
TH1 = -(SYSCLK/BAUDRATE/16); // set Timer1 reload value for baudrate
TL1 = -(SYSCLK/BAUDRATE/16); // set Timer1 reload value for baudrate
TR1 = 1; // start Timer1
CKCON |= 0x10; // Timer1 uses SYSCLK as time base
PCON |= 0x80; // SMOD0 = 1
ES = 1;
TI = 0;
}
//向串口发送一个字符
void send_char_com(unsigned char ch)
{
#ifdef RS485
RS485_DE = 1;
#endif
SBUF = ch;
while (TI == 0);
TI = 0;
#ifdef RS485
RS485_DE = 0;
#endif
}
//向串口发送一个字符串,strlen为该字符串长度
void send_string_com(unsigned char *str,unsigned int strlen)
{
unsigned int k=0;
do {
send_char_com(*(str + k));
k++;
} while (k < strlen);
}
//串口接收中断函数
void serial () interrupt 4 using 3
{
unsigned char ch;
ES = 0;
if (RI && read_flag==0) {
RI = 0;
ch = SBUF;
if ( count ==0) { //startbyte
if (ch == STARTBYTE)
inbuf1[count++] = ch;
} else
if (count == 1) { //add
if (ch == MYADD)
inbuf1[count++] = ch;
else
count = 0;
} else {
inbuf1[count++] = ch;
if ( inbuf1[2]== SETDATA) {
if ( count == INBUF_LEN) {
count =0;
read_flag = 1;
}
} else
if (count == INBUF_LEN -1) {
count =0;
read_flag = 1;
}
}
}
ES = 1;
}
void Timer_Init(void)
{
TMOD &= 0xF0;
TMOD |= 0x02; //TIMER0: MODE2, 8BIT AUTO-RELOAD, TIMER1: MODE 1, 16BIT
TH0 = 256 - SYSCLK/12/(2*HP03SMCLK);
TL0 = 256 - SYSCLK/12/(2*HP03SMCLK);
PT0 = 1;
ET0 = 1;
TR0 = 1;
}
bit SetVaccum(int Vaccum)
{
unsigned int i=0,testpress;
unsigned char breach = 0;
RELAY = 1; //start bumper
while (1)
{
TestPin = ~TestPin;
i++;
ClockDelay2ms(250); //delay 500ms
//check pressure
ReadTemperaturePreesureAD();
CalculatePressTemp(0); //don't test temperature
testpress = (unsigned int)(Press/10.0);
if (testpress < Vaccum)
breach ++;
else
breach = 0;
if (breach >= 3) {
RELAY = 0;
return 1;
} else if (i >= TIMEOUT) { //
RELAY = 0;
return 0;
}
}
}
void main(void)
{
unsigned int ipress, ipress0 = 0;
int ripress=0;
int itemp;
P1 = 0;
WDTCN = 0xDE; //0xDE and 0xAD:disable, 0xA5:enable
WDTCN = 0xAD;
SYSCLK_Init();
PORT_Init();
RELAY = 0;
RELAY2 = 0;
Serial_Init();
Timer_Init();
EA = 1;
SysDelay2ms(50);
IIC_ReadCalData();
#ifdef RS485
RS485_DE = 0;
#endif
ReadTemperaturePreesureAD();
CalculatePressTemp(0);
ipress0 = (unsigned int)(Press/10.0);
while (1) {
if (read_flag) { //如果取数标志已置位,就将读到的数从串口发出
ES = 0; //禁止串口中断
if (inbuf1[2]== GETPRESS && inbuf1[3]==GETPRESS) {
ReadTemperaturePreesureAD();
CalculatePressTemp(0);
ipress = (unsigned int)(Press/10.0);
inbuf1[2] = ipress >>8; //high byte
inbuf1[3] = ipress &0x00ff; //low byte
send_string_com(inbuf1,INBUF_LEN - 1);
} else if (inbuf1[2]== GETTEMP && inbuf1[3]==GETTEMP) {
ReadTemperaturePreesureAD();
CalculatePressTemp(1);
itemp = (int)Temp;
inbuf1[2] = itemp >>8; //high byte
inbuf1[3] = itemp &0x00ff; //low byte
send_string_com(inbuf1,INBUF_LEN - 1);
ipress = (unsigned int)(Press/10.0);
inbuf1[2] = ipress >>8; //high byte
inbuf1[3] = ipress &0x00ff; //low byte
send_string_com(inbuf1,INBUF_LEN - 1);
} else if (inbuf1[2] == ORIGNAL) {
ReadTemperaturePreesureAD();
CalculatePressTemp(0);
ipress0 = (unsigned int)(Press/10.0);
send_string_com(inbuf1,INBUF_LEN - 1);
} else if (inbuf1[2]== SETDATA) {
ripress = inbuf1[3];
ripress <<= 8;
ripress |= inbuf1[4];
if (ripress > 0) {
inbuf1[3] = 0;
inbuf1[4] = 0;
} else if (!SetVaccum(ipress0 + ripress)) {
inbuf1[3] = 0xff;
inbuf1[4] = 0xff;
}
send_string_com(inbuf1,INBUF_LEN);
}
else if(inbuf1[2]== VACCUMON) {
RELAY = 1;
send_string_com(inbuf1,INBUF_LEN - 1);
}
else if(inbuf1[2]== VACCUMOFF) {
RELAY = 0;
send_string_com(inbuf1,INBUF_LEN - 1);
}
else if(inbuf1[2]== RELEASEON) {
RELAY2 = 1;
send_string_com(inbuf1,INBUF_LEN - 1);
}
else if(inbuf1[2]== RELEASEOFF) {
RELAY2 = 0;
send_string_com(inbuf1,INBUF_LEN - 1);
}
read_flag=0; //取数标志清0
ES = 1;
}
}
}
//*************************
//function: calculate power for 2
//**************************
long int Get2_x(unsigned char i)
{
long int uiData;
uiData=2;
i=i-1;
while (i) {
uiData <<= 1;
i--;
}
return uiData;
}
//***********************************
//function:calculate press and temperature
//input :D1,D2,C1---C7,AA,BB,CC,DD
//output :Press, unit: 0.01hpa
// temp, unit: 0.1℃
//************************
void CalculatePressTemp(bit btesttemp)
{
long float MiddleData1;
long float MiddleData2;
long float MiddleData3;
long float MiddleData4;
// calculate the DUT value
if (D2<C5) {
DUT = D2-C5-((D2-C5)/Get2_x(7))*((D2-C5)/Get2_x(7))*BB/Get2_x(CC);
MiddleData1 = (long)D2-C5;
MiddleData2 = MiddleData1*MiddleData1/16384;
MiddleData3 = MiddleData2*BB;
MiddleData4 = Get2_x(CC);
MiddleData4 = MiddleData3/MiddleData4;
DUT = MiddleData1 - MiddleData4;
} else {
//DUT = D2-C5-((D2-C5)/Get2_x(7))*((D2-C5)/Get2_x(7))*AA/Get2_x(C);
MiddleData1 = D2-C5;
MiddleData2 = MiddleData1 * MiddleData1 / 16384;
MiddleData3 = MiddleData2 * AAA;
MiddleData4 = Get2_x(CC);
MiddleData4 = MiddleData3/MiddleData4;
DUT = MiddleData1 - MiddleData4;
}
//calculate the OFF value
//OFF = (C2+(C4-1024)*DUT/Get2_x(14))*4;
MiddleData1 = (long)C4-1024;
MiddleData2 = Get2_x(14);
MiddleData3 = DUT*MiddleData1;
MiddleData4 = MiddleData3/MiddleData2;
MiddleData4 = (long)C2+MiddleData4;
OFF = MiddleData4*4;
//calculate the SENS value
//SENS = C1+C3*DUT/Get2_x(10);
MiddleData1 = (long)C3*DUT;
MiddleData2 = Get2_x(10);
MiddleData3 = MiddleData1/MiddleData2;
SENS = C1+MiddleData3;
//calculate the X value
//X = SENS*(D1-7168)/Get2_x(14)-OFF;
MiddleData1 = Get2_x(14);
MiddleData2 = (long)D1-7168;
MiddleData3 = MiddleData2*SENS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -