?? main.#3
字號(hào):
XBR1 = 0x14; // 允許INT0_SCK、INT0_CS
XBR2 = 0x44; // 允許交叉開關(guān)和弱上位
// ADC和DAC(取默認(rèn)值)轉(zhuǎn)換初始化
AMX0CF = 0x00; // 配置AIN00-AIN07均為單端輸入方式(默認(rèn))
AMX0SL = 0x00; // 選擇AIN00通道進(jìn)行AD轉(zhuǎn)換(默認(rèn))
ADC0CF = 0x50; // ADC0轉(zhuǎn)換時(shí)鐘為2MHz,PGA增益為1
ADC0CN = 0x84; // 允許ADC0,正常跟蹤模式,Timer3溢出啟動(dòng)ADC0轉(zhuǎn)換,ADC0數(shù)據(jù)右對(duì)齊
DAC0 = 0x0000; // 默認(rèn)DAC0輸出為0
DAC1 = 0x0000; // 默認(rèn)DAC1輸出為0
DAC0CN = 0x80; // 允許DAC0輸出,寫DAC0H時(shí)DAC0更新輸出,DAC0H3-0保存高4位,DAC0L7-0保存低8位(默認(rèn))
DAC1CN = 0x80; // 允許DAC1輸出,寫DAC1H時(shí)DAC1更新輸出,DAC1H3-0保存高4位,DAC1L7-0保存低8位(默認(rèn))
// ADC和DAC參考電壓初始化
REF0CN = 0x03; // ADC0電壓基準(zhǔn)取至VREF0,禁止溫度傳感器,內(nèi)部偏壓發(fā)生器和基準(zhǔn)電壓緩沖器打開
// 串口UART0和UART1初始化
SCON0 = 0x50; // UART0為8位可變波特率模式,允許接收
SCON1 = 0x50; // UART1為8位可變波特率模式,允許接收
// 定時(shí)器初始化
CKCON = 0x10; // TIMER1時(shí)鐘源為SYSCLK,TIMER4、TIMER2、TIMER0時(shí)鐘源為SYSCLK/12
TMOD = 0x21; // TIMER1為8位自動(dòng)重裝載模式,TIMER0為16位定時(shí)器方式
TH1 = 0xDC; // TIMER1作為UART0和UART1的波特率發(fā)生器,波特率均為19200bps
TCON = 0x40; // 允許TIMER1定時(shí)
RCAP2H = 0xB8; // TIMER2自動(dòng)重裝載值(定時(shí)10ms,RCAP2L=0x00)
TH2 = 0xB8; // TIMER2計(jì)數(shù)寄存器初值(定時(shí)10ms,TL2=0x00)
T2CON = 0x04; // TIMER2作為10ms定時(shí)器,16位自動(dòng)重裝載模式,允許定時(shí)
TMR3RLL = 0x9A; // TIMER3自動(dòng)重裝載值(定時(shí)1ms)
TMR3RLH = 0xA9;
TMR3L = 0x9A; // TIMER3計(jì)數(shù)寄存器初值(定時(shí)1ms)
TMR3H = 0xA9;
TMR3CN = 0x06; // TIMER3作為1ms定時(shí)器,控制ADC,使用SYSCLK,允許定時(shí)
// 中斷初始化
EIE2 = 0x42; // 允許UART1和ADC0中斷
IE = 0xB0; // 允許TIMER2、UART0中斷,開總中斷
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函數(shù)名稱: SysInit
** 功能描述: ADC0轉(zhuǎn)換結(jié)束中斷服務(wù)程序。
** 輸 入: 無
** 輸 出: 無
** 全局變量: 略
** 全局常量:略
** 調(diào)用模塊:略
** 設(shè) 計(jì) 者:羅建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void SysInit(void)
{
gbCanGetKey = TRUE;
gnTxdBuf0[0] = 0xFF;
gnTxdBuf0[1] = 0xFF;
gnCntAdjust = ADJUST_WAIT;
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函數(shù)名稱: ADC0_ISR
** 功能描述: ADC0轉(zhuǎn)換結(jié)束中斷服務(wù)程序。
** 輸 入: 無
** 輸 出: 無
** 全局變量: 略
** 全局常量:略
** 調(diào)用模塊: 略
** 其它說明:ADC0轉(zhuǎn)換結(jié)果與工程量(氣體壓力)之間的轉(zhuǎn)換原理如下:
** 由于電氣比例閥ITV2000的信號(hào)輸出與壓力之間的對(duì)應(yīng)關(guān)系為:1-5V對(duì)應(yīng)于0-0.5MPa,假設(shè)1-5V信號(hào)經(jīng)
** 2.5倍分壓后(即0.4-2V)進(jìn)入單片機(jī),其對(duì)應(yīng)的ADC0數(shù)字量(即mADC0Res變量的值)為:
** 0.4V===0.4*4096/VREF0,2V===2*4096/VREF0,
** 其中,4096為ADC0的轉(zhuǎn)換位數(shù)(12位),VREF0為ADC0的參考電壓(典型值為2.43V)。
** 將壓力信號(hào)擴(kuò)大10000倍,則0-0.5MPa對(duì)應(yīng)數(shù)字0-5000(單位為0.1KPa)。為了便于計(jì)算,這里采用直線
** 方程來得到壓力與電壓數(shù)字量之間的關(guān)系:
** P1 = 0 = COEF0*0.4*4096/VREF0 + COEF1
** P2 = 5000 = COEF0*2*4096/VREF0 + COEF1
** 因VREF0可以測(cè)得,因此可以解上述方程組。為便于進(jìn)行整數(shù)運(yùn)算,將VREF0擴(kuò)大1000倍,則上述方程組可
** 表述為:
** P1 = 0 = COEF0*400*4096/VREF0 + COEF1
** P2 = 5000 = COEF0*2000*4096/VREF0 + COEF1
** 解方程組得系數(shù)COEF0和COEF1分別為:
** COEF0 = VREF0*25/32768
** COEF1 = -1250
** 故壓力方程為:
** P = D*VREF0*25/32768 - 1250
** 式中,P為待測(cè)壓力,單位為0.1KPa,D為ADC0測(cè)得的對(duì)于輸入電壓的數(shù)字量。如果P<0,則應(yīng)將其置0。
**
** 設(shè) 計(jì) 者:羅建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ADC0_ISR(void) interrupt INT_ADC0
{
static INT8U nADC0Cnt=ADC0_SAMPLE_NUMS; // ADC0采樣次數(shù)計(jì)數(shù)器定義及初始化
INT32U nPress;
AD0INT = FALSE; // 清除ADC0轉(zhuǎn)換結(jié)束標(biāo)志
gnADC0Res += ADC0; // 累加ADC0轉(zhuǎn)換結(jié)果并取平均
nADC0Cnt--; // ADC0連續(xù)轉(zhuǎn)換ADC0_SAMPLE_NUMS次,完成后暫停轉(zhuǎn)換(不響應(yīng)中斷)
if (nADC0Cnt == 0) // 同時(shí)將結(jié)果轉(zhuǎn)換為工程量值(氣體壓力)
{
nADC0Cnt = ADC0_SAMPLE_NUMS;
AD0EN = FALSE;
gnADC0Res = gnADC0Res/(ADC0_SAMPLE_NUMS+1);
nPress = gnADC0Res*VREF0*25/32768; // 進(jìn)行工程量轉(zhuǎn)換,如果值小于0,則認(rèn)為是0
if (nPress <= 1250)
gnPressGet = 0;
else
gnPressGet = nPress - 1250;
}
}
/********************************************************************************************************
** 函數(shù)名稱: UART0_ISR
** 功能描述: 串行口UART0中斷服務(wù)程序。
** 輸 入: 無
** 輸 出: 無
** 全局變量: 略
** 全局常量:無
** 調(diào)用模塊:無
** 設(shè) 計(jì) 者:羅建 日 期:2007年12月09日
** 版 本:V1.00,原始版本
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART0_ISR(void) interrupt INT_UART0
{
if (RI0) // 數(shù)據(jù)接收中斷
{
RI0 = FALSE; // 清除數(shù)據(jù)接收中斷標(biāo)志
if (gbSyncTwoOK0) // 檢查同步字節(jié)是否接收完畢
{
if (SBUF0 == 0xFF) // 同步字節(jié)已接收完畢,但仍接收到了0xFF,說明出現(xiàn)了最糟糕
return; // 的情況,即有3個(gè)0xFF,因此需將該字節(jié)舍棄。
gnRxdBuf0[gnRxdID0++] = SBUF0;
// 接收設(shè)定參數(shù)及系數(shù)命令(0xFF,0xFF,0x00,0x02,Data,共44個(gè)字節(jié),數(shù)據(jù)按先低后高的順序發(fā)送)
if (gnRxdID0 >= 32) // 檢查數(shù)據(jù)是否接收完畢(包括兩個(gè)命令字節(jié))
{
gnPressSet = gnRxdBuf0[1]*256 + gnRxdBuf0[0]; // 預(yù)設(shè)測(cè)試壓力值(單位:0.1KPa)
gnPressMax = gnRxdBuf0[3]*256 + gnRxdBuf0[2]; // 允許的最高壓力值(單位:0.1KPa)
gnPressMin = gnRxdBuf0[5]*256 + gnRxdBuf0[4]; // 允許的最低壓力值(單位:0.1KPa)
gnLeakMax = gnRxdBuf0[7]*256 + gnRxdBuf0[6]; // 允許的最高流量值(單位:0.01L/min)
gnFillTime = gnRxdBuf0[9]*256 + gnRxdBuf0[8]; // 充氣時(shí)間(單位:0.1S)
gnTestTime = gnRxdBuf0[11]*256 + gnRxdBuf0[10]; // 測(cè)試時(shí)間(單位:0.1S)
// 由于流量測(cè)量的最小值為0,因此其下限始終為0,盡管觸摸屏傳了值(即gnRxdBuf0[13]*256 + gnRxdBuf0[12]),
// 但該值始終為0,因此這里并不讀取它
gnLeakAreaMax[0] = gnRxdBuf0[15]*256 + gnRxdBuf0[14]; // 流量校線階段1對(duì)應(yīng)的最大流量
gnLeakAreaCoef[0] = gnRxdBuf0[17]*256 + gnRxdBuf0[16]; // 流量校線階段1對(duì)應(yīng)的流量修正系數(shù)
gnLeakAreaMax[1] = gnRxdBuf0[19]*256 + gnRxdBuf0[18]; // 流量校線階段2對(duì)應(yīng)的最大流量
gnLeakAreaCoef[1] = gnRxdBuf0[21]*256 + gnRxdBuf0[20]; // 流量校線階段2對(duì)應(yīng)的流量修正系數(shù)
gnLeakAreaMax[2] = gnRxdBuf0[23]*256 + gnRxdBuf0[22]; // 流量校線階段3對(duì)應(yīng)的最大流量
gnLeakAreaCoef[2] = gnRxdBuf0[25]*256 + gnRxdBuf0[24]; // 流量校線階段3對(duì)應(yīng)的流量修正系數(shù)
gnLeakAreaMax[3] = gnRxdBuf0[27]*256 + gnRxdBuf0[26]; // 流量校線階段4對(duì)應(yīng)的最大流量
gnLeakAreaCoef[3] = gnRxdBuf0[29]*256 + gnRxdBuf0[28]; // 流量校線階段4應(yīng)的流量修正系數(shù)
SetRxd0OK(); // 重新初始化同步字節(jié)檢測(cè)標(biāo)志及串口接收緩沖區(qū)索引
gnTxdBuf0[0] = 0xFF; // 發(fā)送測(cè)量數(shù)據(jù)及開關(guān)狀態(tài)至觸摸屏命令(0xFF,0xFF,0x00,0x01,共4個(gè)字節(jié))
gnTxdBuf0[1] = 0xFF;
gnTxdBuf0[2] = 0x01; // 準(zhǔn)備發(fā)送命令的低8位字節(jié)
gnTxdBuf0[3] = 0x00; // 準(zhǔn)備發(fā)送命令的高8位字節(jié)
gnTxdBuf0[4] = gnPressGet % 256;// 準(zhǔn)備發(fā)送測(cè)試壓力的低8位字節(jié)
gnTxdBuf0[5] = gnPressGet / 256;// 準(zhǔn)備發(fā)送測(cè)試壓力的高8位字節(jié)
gnTxdBuf0[6] = gnLeakGet % 256; // 準(zhǔn)備發(fā)送氣體流量的低8位字節(jié)
gnTxdBuf0[7] = gnLeakGet / 256; // 準(zhǔn)備發(fā)送氣體流量的高8位字節(jié)
gnTxdID0 = 0;
gnTxdNums0 = 7; // 指示要向觸摸屏發(fā)送的數(shù)據(jù)個(gè)數(shù)為8個(gè)(含幀頭,因下面將先發(fā)送一個(gè)字節(jié),故為7)
SBUF0 = gnTxdBuf0[0]; // 開始發(fā)送數(shù)據(jù)至觸摸屏
}
}
else // 同步字節(jié)還未接收完畢,繼續(xù)檢測(cè)
{
if (SBUF0 == 0xFF) // 如果是同步字節(jié),則設(shè)置相應(yīng)的同步字節(jié)接收到標(biāo)志
{
if (gbSyncOneOK0)
gbSyncTwoOK0 = TRUE;
else
gbSyncOneOK0 = TRUE;
}
else // 接收到的字節(jié)既非同步字節(jié)又非正常的測(cè)量數(shù)據(jù),舍棄重來。
SetRxd0OK(); // 重新初始化同步字節(jié)檢測(cè)標(biāo)志及串口接收緩沖區(qū)索引
}
}
else // 數(shù)據(jù)發(fā)送中斷
{
TI0 = FALSE; // 清除數(shù)據(jù)發(fā)送中斷標(biāo)志
if (gnTxdID0 < gnTxdNums0) // 將發(fā)送緩沖區(qū)中的gnTxdNums0個(gè)數(shù)據(jù)發(fā)送至觸摸屏
{
gnTxdID0++;
SBUF0 = gnTxdBuf0[gnTxdID0];
}
}
}
/********************************************************************************************************
** 函數(shù)名稱: UART1_ISR
** 功能描述: 串行口UART1中斷(僅處理數(shù)據(jù)接收中斷)服務(wù)程序。
** 輸 入: 無
** 輸 出: 無
** 全局變量: 略
** 全局常量:無
** 調(diào)用模塊: 無
** 其它說明:1、RIDen A50流量傳感器的通訊協(xié)議
** 1)波特率:19200bps;
** 2)數(shù)據(jù)位:8位;
** 3)停止位:1位;
** 4)奇偶校驗(yàn):none;
** 5)協(xié) 議:none;
** 6)回 波:傳感器保證一個(gè)回波。
** 7)數(shù)據(jù)格式:接收到的數(shù)值是一個(gè)表示兩種含義的有符號(hào)的16位整型數(shù)。標(biāo)定后的數(shù)據(jù)是原始接收數(shù)據(jù)除
** 以一個(gè)常系數(shù)而得來的,由此轉(zhuǎn)成小數(shù)。對(duì)于A50_V型,流量系數(shù)為128,溫度系數(shù)為100。例:接收到
** 的數(shù)值為+1234(十進(jìn)制),在流量模式中表示的相應(yīng)流量值為9.641Ln/min,在溫度模式中表示的溫度
** 為12.34℃。
** 8)幀格式:0x7F,0x7F,MSB,LSB
** 由于最大量程為0x7852,高位字節(jié)不包含0x7F。因此,最糟糕的情況就是較低位的字節(jié)中包含有0x7F。
** 在這種情況下,0x7F在一行中出現(xiàn)3次。例如:
** 值為:7C 7F,則接收數(shù)串為:7F 7F 7C 7F 7F 7F 7C 7F。在假碼中找出同步的最好方法如下:
** 如果Buf[i]=7F,且Buf[i+1]=7F,且Buf[i+2]<>7F,則Buf[i]和Buf[i+1]就是同步字節(jié)。
** 9)對(duì)整型數(shù)值的解釋如下:
** 接收值(16進(jìn)制) 接收值(10進(jìn)制) 流量(Ln/min) 溫度(℃)
** 0x7852 30802 overflow ----
** 0x7851 30801 peak overflow ----
** 0x7850 30800 +240.600 +308.00
** ...... ..... ........ .......
** ...... ..... ........ .......
** 0x0001 1 +0.007813 0.01
** 0x0000 0 0.000000 0.00
** 0xFFFF -1 -0.007813 -0.01
** ...... ..... ........ .......
** ...... ..... ........ .......
** 0x87B0 -30800 -240.600 -380.00
** *************************************************************
** 負(fù)數(shù)與正數(shù)是對(duì)稱的,可用以下公式計(jì)算負(fù)數(shù)A對(duì)應(yīng)的正數(shù)B:
** B = ~(A-1)
**
** 2、工程量(流量)轉(zhuǎn)換問題
** 對(duì)于A50_V型,流量系數(shù)為128。為了不使用浮點(diǎn)數(shù)進(jìn)行計(jì)算,且又希望保留2位小數(shù)精度,因此可采用將
** 串口接收值先乘以100,再除以128(用右移7位實(shí)現(xiàn))的方法來實(shí)現(xiàn)。這樣,如果接收到的數(shù)值為十進(jìn)制
** 的+1234,則在流量模式中利用上述方法計(jì)算的流量值為9.64Ln/min,所得的測(cè)量精度為±0.01Ln/min,
** 可以滿足使用要求。
**
** 3、顯示與儲(chǔ)存沖突防治
** 由于串口接收數(shù)據(jù)是隨機(jī)的,且數(shù)據(jù)有多字節(jié)(至少為2字節(jié)),在顯示過程中,如果主程序剛訪問了第1
** 個(gè)字節(jié),這時(shí)發(fā)生了串口中斷,并且更新了要顯示的數(shù)據(jù),當(dāng)串口中斷返回時(shí),主程序繼續(xù)顯示第2個(gè)字
** 節(jié),這時(shí)顯示結(jié)果將可能是不正確的。
** 為防止上述沖突現(xiàn)象的發(fā)生,可采用Win32 API中的“臨界區(qū)”思想來實(shí)現(xiàn),即在主程序中讀取數(shù)據(jù)前,
** 先關(guān)閉串口中斷允許標(biāo)志ES,在讀取完數(shù)據(jù)后再打開串口中斷允許標(biāo)志ES的方法。
**
** 設(shè) 計(jì) 者:羅建 日 期:2007年12月09日
** 修 改 者:羅建 日 期:2007年03月23日
** 修 改 者:羅建 日 期:2007年12月09日
** 歷史版本:V1.00,原始版本
** V1.01,修改了流量計(jì)算方式
** 版 本:V1.02,適應(yīng)C8051F020單片機(jī)的串口UART1
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void UART1_ISR(void) interrupt INT_UART1
{
INT8U i;
INT32U nRes;
static INT8U nLeakCnt=LEAK_SAMPLE_NUMS; // ADC0采樣次數(shù)計(jì)數(shù)器定義及初始化
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -