?? 測量顯示.c
字號:
#include<reg51.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
#include <intrins.h>
#include <stdlib.h>
#include "C:\Documents and Settings\www1\桌面\ouyw\ts128647921chuank\src\TS128647921chuank.h"
#include "C:\Documents and Settings\www1\桌面\ouyw\delaycomm\src\delaycomm.h"
#define uint8 unsigned char
#define int16 int
#define uint16 unsigned int
#define uint32 unsigned long int
#define DELAY1US_M _nop_()
#define _port 0x01 //模似信號輸入口
sbit RESET=P3^4; /*復位,高電平有效*/ //AD9851所用端口
sbit wclk=P3^7; /*字輸入時鐘,上升沿有效*/
sbit fqud=P3^6; /*頻率更新端,上升沿將40位控制字送入芯片內*/
#define DATA P2 /*數據端口*/
sbit jian_shuju=P1^2; //串口鍵盤所用端口
sbit jian_shizhong=P1^1;
sbit yiwei_zhiru=P1^0;
//#define io_janp P1 //行列式鍵盤所用端口
#define jidianq P0 /*從高到低檔用其P1.0,P1.2,P1.3控制繼電器換檔,高電平有效*/ //檔位調節
sbit CLOCK=P1^4; /*2543時鐘*/ //AD TCL2543所用端口
sbit D_IN=P1^5; /*2543輸入*/
sbit D_OUT=P1^6; /*2543輸出*/
sbit _CS=P1^7; /*2543片選*/
sbit xingwjx=P3^1; /*相位極性判斷*/ //測相位大小極性所用端口
sbit xiangwsy=P3^2; /*相位大小判斷*/
sbit io_LCDsid = P3^0; /*串行數據輸入端 */ //液晶顯示所用端口
sbit io_LCDsclk = P3^5; /*串行同步時鐘端 */
float _Y,_G,_B; //導納模,電導,電納
int16 pingl,xiangweij; //頻率,向位角
int16 xshu; //輔助顯示數據
uint8 dianx; //輔助顯示小數點
uint8 o; //輔助測量周期
float hudu; //輔助計算電導G,電納B
bit b_pduan=1; //判斷有無鍵按下
//ad9851 ini AD9851并口置數函數
/***********************************************************
功能:用來輔助測量周期
說明:
*************************************************************/
void TIMER(void) interrupt 0
{
TR0=~TR0; //下降沿中斷計數,第二次中斷則關計數器
++o;
}
/***********************************************************
功能:控制AD9851輸出波形的相位及頻率
說明:輸入存有5個字節控制字的首地址,依次對應控制字為W0,W1,W2,W3,W4.
*************************************************************/
void v_DDSkongz_f(uint8 data *u8c_xiansyh_p)
{
uint8 i;
wclk=0; /*先將wclk清零,以便置高時獲得上升沿*/
fqud=0; /*將fqud清零*/
DELAY1US_M; /*延時*/
//fqud=1; /*fqud上升沿控制40位控制字進入DDS核心,因為前面沒有輸入控制字,所以此上升沿的目的是將地址指針指向第一個輸入寄存器*/
//DELAY1US_M; /*延時*/
//fqud=0; /*將fqud清零*/
for(i=0;i<5;i++) /*發送40位控制字數據,由w_clk控制進入輸入寄存器*/
{
DATA=u8c_xiansyh_p[i]; /*發送一個控制字數據*/
DELAY1US_M; /*延時*/
wclk=1; /*w_clk置高,上升沿使得控制字進入輸入寄存器*/
DELAY1US_M; /*延時*/
wclk=0; /*w_clk清零*/
DELAY1US_M; /*延時*/
}
fqud=1; /*fqud置高,上升沿使得40位控制字進入DDS核心*/
DELAY1US_M; /*延時*/
DELAY1US_M;
fqud=0; /*將fqud清零*/
}
/******************************
math DATA
功能:將輸入的頻率值轉換到w[1]~w[4]控制字中
說明:輸入頻率值
*********************************/
uint32 math_phase(uint32 FIN)
{
float datafloat;
//datafloat=((float)FIN)*4294967296/132710400;
datafloat=((float)FIN)*65536/2025; //外部晶振22.1184MHz,開啟6倍頻
return (uint32)datafloat;
}
/*****************************************************
dujsj
功能:串口鍵盤掃描并返回鍵值
說明:有鍵按下時返回鍵值無鍵按下時返回255
********************************************************/
uint8 dujsj(uint8 xinpian) //讀鍵數據
{
uint8 dizhi[5],i,j,fan;
yiwei_zhiru = 0;
yiwei_zhiru = 1; //鎖存端口數據
if(jian_shuju == 0) i=0;
else
{
for(i=1;i<8;i++)
{
jian_shizhong = 0;
jian_shizhong = 1;
if(jian_shuju == 0)break;
}
}
dizhi[0] = i; //讀入第一塊芯片數據
for(j=1;j<xinpian;j++)
{
for(i=0;i<8;i++)
{
jian_shizhong = 0;
jian_shizhong = 1;
if(jian_shuju==0) break;
}
dizhi[j] = i;
}
for(j=0;j<xinpian;j++)
{
if(dizhi[j] != 8)
{
fan = dizhi[j]+j*8;break;
}
fan=0xff;
}
return fan;
}
/********************************************************************
anjiansz_f
功能:設定各按鍵功能
說明:
*************************************************************************/
void anjiansz_f(unsigned char key)
{
switch(key)
{
case 0:pingl=100;break; //100Hz
case 1:pingl=300;break; //300Hz
case 2:pingl=1000;break; //1KHz
case 3:pingl=3000;break; //3KHz
case 4:pingl=10000;break; //10KHz
case 5:pingl+=100;break; //以100Hz步進
case 6:pingl-=100;break; //以100Hz步減
case 7:break;
case 8:break;
case 9:break;
case 10:break;
case 11:break;
case 12:break;
case 13:break;
case 14:break;
case 15:break;
}
}
/*******************************************
功能:輸入要顯示的導納模,或電導,電納值轉換為可顯示的值
說明:shuju范圍:0.01~100之間
數據以mS為單位
*********************************************/
//int16 xshu; //輔助顯示用
//uint8 dianx;
void shujuxs_f(float shuju)
{
if(shuju<0.09) {xshu=(int16)(1000*shuju);dianx=3;}
else
{xshu=(int16)(100*shuju);dianx=2;}
}
/*******************************************
功能:輸入要顯示的頻率,相位,導納模,電導,電納值將其顯示出來
說明:范圍:頻率范圍:0Hz~32767Hz
相位-90度~90度
導納0.01~100之間以mS為單位
*********************************************/
void xianYReIm_f(int16 pl,int16 xiangw,float Y,float Re,float Im)
{
v_LcdWriteNumber_f(0x03,5,pl);
v_LcdWriteChar_f(0x00,"f=");
v_LcdWriteNumber_f(0x07,5,xiangw);
v_LcdWriteChar_f(0x04,"Hz");
v_LcdWriteChar_f(0x05,"φ");
if(xiangw<=-10) v_LcdWriteChar_f(0x06,"=-");
else v_LcdWriteChar_f(0x06,"= ");
shujuxs_f(Y);
v_LcdWriteCharOneLine_f(0x90,"導納模: mS");
v_LcdWriteNumber_f(0x16,dianx,xshu);
v_LcdWriteChar_f(0x13,": ");
shujuxs_f(Re);
v_LcdWriteCharOneLine_f(0x88," 電導: mS");
v_LcdWriteNumber_f(0x26,dianx,xshu);
v_LcdWriteChar_f(0x23,": ");
shujuxs_f(Im);
v_LcdWriteCharOneLine_f(0x98," 電納: mS");
v_LcdWriteNumber_f(0x36,dianx,xshu);
v_LcdWriteChar_f(0x33,": ");
}
/**************************************
名稱:read2543
功能:TLC2543驅動模塊
輸入參數:port通道號
輸出參數:返回上次ad轉換好的值
注意:第一次轉換的數據為隨機一般無意義
*************************************/
int16 read2543_f()
{
uint8 port=_port;
int16 ad=0;
uint16 i;
CLOCK=0;
_CS=1;
DELAY1US_M;
_CS=0;
port<<=4;
for(i=0;i<12;i++)
{
ad<<=1;
if(D_OUT) ad|=0x01;
D_IN=(bit)(port&0x80);
CLOCK=1;
DELAY1US_M;
CLOCK=0;
DELAY1US_M;
port<<=1;
}
_CS=1;
return(ad);
}
/**************************************************
功能:自動調節測量檔位
說明:輸入使用A/D TLC2543測量電路的port通道號
返回所造檔位值,1,2,3,4
1為最高大檔
4為最小檔
***************************************************/
uint8 dangwkz_f()
{
uint8 i,j;
int16 jieshouAD;
jidianq&=0x10; //斷開四個繼電器
jidianq|=0x01; //接通第一個繼電器(最大檔)
i=10;
while(--i)
jieshouAD=read2543_f();//延時并且刷新A/D值
if(jieshouAD>=409&&jieshouAD<=4095) j=1;
else
{
jidianq&=0x10; jidianq|=0x02; //接通第二檔
i=10;
while(--i)
jieshouAD=read2543_f();//延時并且刷新A/D值
if(jieshouAD>=409&&jieshouAD<4095) j=2;
else
{
jidianq&=0x10; jidianq|=0x04; //接通第三檔
i=10;
while(--i)
jieshouAD=read2543_f();//延時并且刷新A/D值
if(jieshouAD>=409&&jieshouAD<4095) j=3;
else
{
jidianq&=0x10; jidianq|=0x08; //接通第四檔
i=10;
while(--i)
jieshouAD=read2543_f();//延時并且刷新A/D值
if(jieshouAD>=409&&jieshouAD<4095) j=4;
}
}
}
return(j);
}
/*************************************************************
功能:計算導納模|Y|
說明:輸入使用A/D TLC2543測量電路的port通道號與檔位號j
返回計算后的導納模值|Y|
**************************************************************/
float daonaY_f(uint8 j)
{
int16 code R[4]={27,270,2700,27000};
float y;
int16 jieshouAD;
jieshouAD=read2543_f(); //A/D轉換后的結果
// y=(float)jieshouAD*2*(2.7/4096)*1.414/R[j]/1; //Ipp=2*1.414*jieshouAD*(2.7/4096)/R[j] ,Upp=1V
// y=(float)jieshouAD*(2.7/4096)*1.414*2/R[j];
y=(float)jieshouAD*0.001864441/R[j];
return(y);
}
/**************************************************
功能:測量相位角
說明:用的是T0帶選通控制位,返回相位角
*****************************************************/
void xiangweicl_f(void)
{
uint16 tim,zhouqi;
int16 i=1;
/**********測相位************/
IE=0x00; //關中斷
TCON=0x00;
TMOD=0x09; //INT0=1且TR0=1時計時工作方式1(16位計數)
TH0=0x00;
TL0=0x00;
while(INT0);
TR0=1; //準備計時
while(!INT0);
while(INT0);
TR0=0; //停止計數
if(xingwjx==0) i=-1; //判斷頻率的正負值
tim=TH0; //取相位差
tim<<=8;
tim+=TL0;
/**********測周期************/
o=0;
TH0=0x00;
TL0=0x00;
TCON=0x01;
TMOD=0x01; //TR0=1時計時工作方式1(16位計數)
IE=0x81; //開外部中斷
while(o!=2);
IE=0x00;
zhouqi=TH0;//取周期值
zhouqi<<=8;
zhouqi+=TL0;
hudu=(float)tim*3.14159265/zhouqi*i; //相位角弧度制表示
xiangweij=(int16)(tim*180.0/zhouqi)*i;//相位角度數
}
/******************************************************************
功能:求相位角,導納,電導與電納
分別存入全局變量xiangweij,_Y,_G,_B中
*******************************************************************/
void qiuGB_f(void)
{
_Y=daonaY_f(dangwkz_f());
xiangweicl_f(); //測量相位角
_G=_Y*cos(hudu);
_B=_Y*sin(hudu);
}
/*******************************************************************
主函數
********************************************************************/
main()
{
uint8 data *p;
uint32 q,fin;
uint8 j,key=255,shong=0;
uint8 w[5];
const uint8 code kaicjm1[][16]={" 歡迎進入 ","網絡導納測試儀! "," ^-^ **** ^-^ "," 按任意鍵進入 "};
const uint8 code kaicjm[][16]={"0:100 1:300 ","2:1K 3:3K 4:10K ","5:+100 6:-100 ","7:設置頻率值(Hz)"};
v_LcdWriteCharIni_f();//對12864初始化
DELAY1US_M;
v_LcdWriteCharScreen_f(kaicjm1);
do{key=dujsj(2);} while(key==255);
v_LcdWriteCharScreen_f(kaicjm); //輸出介面,請求輸入頻率
do{key=dujsj(2);} while(key!=255);
do
{
while(key!=7)
{
do{key=dujsj(2);} while(key==255);
anjiansz_f(key);
v_WriteIns_f(0x01); //清屏
v_LcdWriteCharOneLine_f(0x80,"頻率為: ");
v_LcdWriteNumber_f(0x06,5,pingl); //顯示設定頻率值
v_LcdWriteChar_f(0x07,"Hz");
v_LcdWriteCharOneLine_f(0x88,"設定完成請按07鍵");
v_DelayX10ms_f(30);
//do{shong=dujsj(2);} while(shong!=255); //松鍵確認
}
// v_LcdWriteCharOneLine_f(0x88," 頻率設定完成 ");
//控制DDS輸出設定的頻率
fin=(uint32)pingl;
q=math_phase(fin);
p=&q;
w[0]=1;
for(j=1;j<5;j++)
w[j]=*p++;
RESET=1; //使AD9851復位
v_DelayX10ms_f(1); // 延時10ms
RESET=0; // RESET清零
v_DDSkongz_f(&w); // 調用寫入5個字節控制字子程序
v_DelayX10ms_f(1); //延時10ms
v_LcdWriteCharOneLine_f(0x88," 頻率已送輸出 ");
//***************************************
// qiuGB_f(); //求相位角,導納,電導與電納分別存入全局變量xiangweij,_Y,_G,_B
// v_WriteIns_f(0x01); //清屏
// xianYReIm_f(pingl,xiangweij,_Y,_G,_B); //顯示
// v_LcdWriteCharOneLine_f(0x88," 測量完成 ");
//xianYReIm_f(220,-90,0.012,0.12,100); //顯示
do{key=dujsj(2);} while(key==255); //判斷有無按鍵,重新設置頻率進行測量
}
while(1);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -