功能:按鍵8個,測頻計數,交流電壓 ,直流電壓,及相應保護判斷亮燈指示,用ST7920-12864液晶顯示
硬件:測頻計數用到 單運放遲滯比較器、555波形陡處理、 CD4013做的D觸發器;交流電壓用到
LM358單運放半波整流,輸出加一級RC濾波.調節運放可以調節電壓、AD轉換芯片TLC1543(0-5V)。
直流電壓就沒嘛說的,電阻分壓就行了。
按鍵用74HCT245雙向數據芯片,蠻好。
繼電器控制,液晶并口數據線,保護燈,按鍵都是用P0口,用74HC573鎖存切換,AD轉換口用P1口。計數用T0 INT0 INT1 ,其他的控制腳接P2口,所以沒有做單片機口擴展,那樣到更麻煩些
補充:燈光顯示和繼電器的74HC573控制腳接到反向器74HC04,加大驅動能力。
備注:由于硬件電路做的簡單,所以,程序繁瑣,待優化中。。。。。。。。。。。。。
以下是部分程序預覽,完整的源代碼下載:http://m.raoushi.com/ziliao/file/cepin1.rar
/********關于多周期測頻法,精度與晶振和閘門時間有關。晶振越大,閘門時間越長,都可以提高精度。**********/
#include <stc89c52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define LCD12864_IO P0
#define CLERADISPLAY LCD12864_command(0x01);
int a1=0,a2=0,a3=0,a4=0,a5=0,a6=0;//存儲電壓值的每一位,設計a4,a5是小數位.
const uchar num[]="0123456789. ";
//AD轉換控制腳
sbit CLK = P1^0; //TLC1543 18P
sbit ADDRESS = P1^1; //17P
sbit SDATA = P1^2; //16P
sbit CS = P1^3; //15P
/********************************************************************/
sbit LCD12864_RS=P2^5; // 12864-st7920 4P RS
sbit LCD12864_RW=P2^6; //RW(5P)
sbit LCD12864_EN=P2^7; //E(6P)
/********************************************************************/
void LCD12864_busy(void);
void LCD12864_command(unsigned char command);
void LCD12864_data(unsigned char dat);
void LCD12864_address(unsigned char row,unsigned char line);
void LCD12864_string(unsigned char row,unsigned char line,unsigned char *s);
void LCD12864_picture(unsigned char *gImage);
void LCD12864_init(void);
void LCD12864_char (unsigned char row,unsigned char line,unsigned char a);
unsigned char LCD12864_ReadData();
void LCD12864_Drawpoint(uchar X,uchar Y);
void LCD12864_LineX(unsigned char X0, unsigned char X1, unsigned char Y);
void LCD12864_LineY( unsigned char X, unsigned char Y0, unsigned char Y1);
void LCD12864_DrawPicture( unsigned char code *pic);
void clrgdram();
/********************************************************************/
//
double DAT[7]={115.0, 115.1, 115.2, 285.0,1500.0, 400.0,3100.0};
// U V W E N F CINT
// 控制腳
sbit CONTRL=P1^7; //測頻控制腳
sbit SCANF =P2^0; //鍵盤掃描控制腳
sbit LED1 =P2^1; //狀態顯示控制腳1
sbit LED2 =P2^2; //狀態顯示控制腳2
sbit SHUCHU=P2^3; //繼電器輸出控制腳
//
bit FLAG; //測頻標志位
bit xunhuanflag;//顯示方式標志位
bit outflag; //允許輸出標志
bit eding;//額定狀態標志
// 按鍵存儲
bdata uchar key; //鍵值存儲
sbit key0=key^0;//停機
sbit key1=key^1;//啟動按鈕
sbit key2=key^2; //顯示方式(高循環)
sbit key3=key^3; //自檢
sbit key4=key^4;//燈檢
sbit key5=key^5;//復位
sbit key6=key^6;//應急 (高應急)
sbit key7=key^7;//油壓(高有油壓)
uint t1h,t1l,t2h,t2l;//測頻變量
double cnt1,cnt2;
double AD; //定義為float 類型,可以防止下面做四則運算時每一步的值超出 范圍
unsigned long int X;
/****************************************************************/
uint rd1543(uchar address);//AD轉換程序
void voltage(); //電壓檢測
void init(); //初始化
void zhuansu(); //計算轉速
void reset();//測頻計數定時復位
uchar scanf(); //鍵盤掃描
void keychuli(); //按鍵處理程序
void baohu();
void display(unsigned long int sx); //顯示函數
void displayFX(unsigned long int sx);
/*************************************************************/
void delayus(uint);
void delayms(uint);
void delays(uint m); //延時秒
unsigned char code Bmp019[]=
{
/*------------------------------------------------------------------------------
; 若數據亂碼,請檢查字模格式設置,注意選擇正確的取模方向和字節位順序。
; 源文件 / 文字 : C:\Documents and Settings\Administrator\桌面\888.bmp字模
; 寬×高(像素): 128×64
; 字模格式/大小 : 單色點陣液晶字模,橫向取模,字節正序/1024字節
; 數據轉換日期 : 2010-7-26 20:46:48
------------------------------------------------------------------------------*/
/****************************
0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 上半屏行坐標,表示的是多少列
0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 下半屏行坐標,每組8列,每列16位,共128位,
0x80
0x81
0x82
0x83
........
0x9f //列坐標,共32個,表示的是行數 ,分兩個半屏,每個32行,共64行
//Y坐標 只是用來確定具體坐標,在哪一行
功能:圖形模式下,顯示(X,Y)點
輸入:X(0~127) Y(0~63) 相對屏幕坐標
輸出:無
點亮某一點的操作步驟: 1.求出水平坐標X對應的地址和是哪一位 0x80-----0x8f (范圍0-15) X/16求地址 X%16求該地址哪一位
2.求垂直坐標Y對應的地址和上下半屏 0x80------0x9f(范圍0-63) Y本身就是8位地址,Y=63-Y ,Y--(0-31)
3.寫入行列地址(Y是行X是列),0x80+Y ,0X80+X/16
4.讀要顯示的數據 DAT
5.區分上下半屏(X%16<=7&&X%16>=0是上半屏)寫入數據每一位 DAT|0x80 ;DAT<<1
注意:這個函數顯示某一點時,可能會把上次顯示的處于同一地址的其他位的點擦掉,所以先保存所有數據,最后顯示,就連貫起來了
*******************************/
/*******************************************************************/
/**************************************************************/
//------------------清整個GDRAM空間----------------------------
/**************************************************************/
void clrgdram()
{
unsigned char x,y ;
for(y=0;y<64;y++)
for(x=0;x<16;x++)
{
LCD12864_command(0x34);
LCD12864_command(y+0x80);
LCD12864_command(x+0x80);
LCD12864_command(0x30);
LCD12864_data(0x00);
LCD12864_data(0x00);
}
}
/******************************************/
/*******8==========================================================================
功能:圖形模式下,顯示(X,Y)點
輸入:X(0~127) Y(0~63)
輸出:無
0x80 0x81 0x82 0x83 0x84 0x85 0x86 0x87 上半屏行坐標,表示的是多少列,X地址
0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8e 0x8f 下半屏行坐標,X地址 (水平地址 )
0x80 (垂直地址)
0x81
0x82
0x83
........
0x9f //列坐標,共32個,表示的是行數 ,分兩個半屏,每個32行,共64行
====================================================================**********/
void LCD12864_Drawpoint(uchar X,uchar Y)
{
uchar i= 0, j = 0,ok=0;
uchar temp1 = 0x00,temp2 = 0x00;
LCD12864_command(0x34); //8位,擴充指令,繪圖關
LCD12864_command(0x36); //8位,擴充指令,繪圖開
i = X/16; //計算出X字節地址(0X80-0X8F)
j = X%16; //計算出該字節的具體位(0-15)
//Y = 63 - Y;
if(Y>=0 && Y<=31)//判斷上下半屏
{
ok=1;
}
else if(Y>=32 && Y<=63)//下半屏
{
Y = Y - 32;//Y只有0-31共32個 地址
i = i + 8;//X地址進入下半屏 (0X88-0X8F)
ok=1;
}
if(ok)
{
//讀數據操作
LCD12864_command(0x80+Y); //第一步:設置Y坐標,讀數據先寫地址,寫GDRAM時先寫垂直地址(0X80-0X9F)
LCD12864_command(0x80+i); //第二步:設置X坐標
LCD12864_ReadData(); //第三步:空讀取一次
temp1 =LCD12864_ReadData(); //第四步:讀取高字節,先讀高字節
temp2 =LCD12864_ReadData(); //第五步:讀取低字節
//圖形模式下的寫數據操作
LCD12864_command(0x80+Y); //第一步:設置Y坐標
LCD12864_command(0x80+i); //第二步:設置X坐標
if(j>=0 && j<=7) //判斷是高字節
{
LCD12864_data(temp1|(0x80>>j)); //第三步:寫高字節數據
LCD12864_data(temp2); //第四步:寫低字節數據
}
else if(j>7 && j<=15) //判斷是低字節
{
j = j - 8;
LCD12864_data(temp1);
LCD12864_data(temp2|(0x80>>j)); //改變字節里的位
}
}
}
/******************************************/
//畫線
/********************************************/
//畫水平線
void LCD12864_LineX(unsigned char X0, unsigned char X1, unsigned char Y)
{
unsigned char Temp ;
if( X0 > X1 )
{
Temp = X1 ; //交換X0 X1值
X1 = X0 ; //大數存入X1
X0 = Temp; //小數存入X0
}
for( ; X0 <= X1 ; X0++ )
LCD12864_Drawpoint(X0,Y);
}
//畫垂直線
void LCD12864_LineY( unsigned char X, unsigned char Y0, unsigned char Y1)
{
unsigned char Temp ;
if( Y0 > Y1 )//交換大小值
{
Temp = Y1 ;
Y1 = Y0 ;
Y0 = Temp ;
}
for(; Y0 <= Y1 ; Y0++)
LCD12864_Drawpoint( X, Y0) ;
}
/******************************************/
/**************畫圖************************/
void LCD12864_DrawPicture( unsigned char code *pic)
{
unsigned char i, j, k ;
LCD12864_command(0x34);//開擴充指令
LCD12864_command(0x36);//開繪圖功能
for( i = 0 ; i < 2 ; i++ )//分上下兩屏寫
{
for( j = 0 ; j < 32 ; j++)//垂直地址遞加 ,行掃方式
{
LCD12864_command( 0x80 + j ) ;//寫Y坐標(Y的范圍: 0X80-0X9F )
if( i == 0 ) //寫X坐標
{
LCD12864_command(0x80);//上半屏
}
else
{
LCD12864_command(0x88);//下半屏開始地址
}
for( k = 0 ; k < 16 ; k++ ) //寫一整行數據
{
LCD12864_data( *pic++ );//前面只寫入首地址,后面依次寫入數據,地址會自動遞增
}
}
}
LCD12864_command( 0x30);//恢復到一般模式
}
//
// 初始化設置
/*******************************************************************/
void LCD12864_init(void)
{
CLERADISPLAY // clear DDRAM
LCD12864_command(0x30); // 8 bits unsigned interface,basic instrument
LCD12864_command(0x02); // cursor return
LCD12864_command(0x0c); // display,cursor on
LCD12864_command(0x03);
LCD12864_command(0x06);
CLERADISPLAY // clear DDRAM
}
//
//顯示函數
void display(unsigned long int sx)
{
a1=sx/100000;
a2=sx%100000/10000;
a3=sx%10000/1000;//千位
a4=sx%1000/100;//百位
a5=sx%100/10;//十位
a6=sx%10;//個位
LCD12864_command(0x90); //指定顯示位置
LCD12864_data(num[a1]); //從最高位開始顯示
LCD12864_data(num[a2]);
LCD12864_data(num[a3]);
LCD12864_data(num[a4]);
LCD12864_data(num[a5]);
LCD12864_data(num[10]);//小數點
LCD12864_data(num[a6]);
}
void displayFX(unsigned long int sx)
{
a1=sx/100000;
a2=sx%100000/10000;
a3=sx%10000/1000;
a4=sx%1000/100;
a5=sx%100/10;
a6=sx%10;
LCD12864_command(0x98); //指定顯示位置
LCD12864_data(num[a1]); //從最高位開始顯示
LCD12864_data(num[a2]);
LCD12864_data(num[a3]);
LCD12864_data(num[a4]);
LCD12864_data(num[a5]);
LCD12864_data(num[a6]);
}
/*********************************
主函數入口
/********************************************/
//主函數入口
//
main()
{
uchar ii=0;
CONTRL=0;
Mcu_init();
CLERADISPLAY
delays(1);
LCD12864_char(1,2,'A');
LCD12864_string(1,4,"shaozhanyu");
delays(2);
clrgdram();
CLERADISPLAY
delays(1);
clrgdram();
delays(1);
LCD12864_LineX(8,113,25);
clrgdram();
CLERADISPLAY
delays(2);
clrgdram();
LCD12864_LineY(55,29,57);
delays(2);
clrgdram();
delays(1);
LCD12864_DrawPicture(Bmp019);
delays(3);
Mcu_init();
CLERADISPLAY
LCD12864_string(3,1,"N F U V W E");
LCD12864_char(2,1,'D');
LCD12864_string(4,1,"計數");
LCD12864_string(1,3,"少占魚做");
display(123456);
/***************8888
P0=0x10;//怠速,準備打開K5繼電器,關閉其他輸出繼電器
SHUCHU=0;//打開輸出閘門
SHUCHU=1;//關閉閘門
outflag=0;//輸出標志位
******************/
AD=0.0;
keychuli(); //掃描并處理按鍵
delayms(5200);
///初始化
init();
while(1)
{
while(!FLAG); //等待頻率測出
keychuli(); //掃描并處理按鍵
LCD12864_string(1,3,"開始轉換");
delayms(300);
voltage(); //采樣電壓
LCD12864_string(1,3,"轉換完成");
delayms(400);
baohu();//判斷采樣數據保護
for(;ii<6;ii++)
{
display(DAT[ii]);
LCD12864_string(1,3,"顯示下組");
delayms(1200);
// keychuli();
if(xunhuanflag==0) //定點
{display(DAT[ii]);
break;
}
}
if(ii==6)
ii=0;
display(DAT[ii]);
displayFX(DAT[6]);
LCD12864_string(1,3,"下輪復位");
delayms(1000);
init();
}
}
/*************************************/
//初始化函數
void init()
{
/******T1定時器模式,外部INT1控制開啟,T0計數器不允許中斷,外部控制
INTO開啟,外部中斷0允許(EX0=1),
定時器T2中斷允許 (ET2=1) ************/
CONTRL=0;
FLAG=0;
EX0=0;
ET2=0;
//三個定時器方式設置
TMOD=0x9d; //T0T1方式控制
T2MOD=0x00;
T2CON=0x00;//定時器2,16位定時方式,自動重裝。
TH0= 0x00; // T0高8位
TL0= 0x00; // T0低8位
TH1= 0x00; // T1高8位
TL1= 0x00; // T1低8位
EXEN2=0;
TH2=256/256;
TL2=256%256;
RCAP2H=256/256;
RCAP2L=256%256;
//中斷設置 5
EX0=1;//允許外部0輸入中斷(INT0引腳)
ET2=1; //開定時中斷2
IT0=1; //外部中斷0邊沿觸發,下降沿到來觸發
//優先級設置
PX0=1;
//預置T0,T1
TR1=1;//先允許T1定時,因T1的GATE=1,還要等外部INT1高電平才計數
TR0=1;//先允許T0計數 ,同T1一樣,等待INTO高電平
TR2=1;//啟動T2定時,不用外部控制,直接啟動
EA=1; //開全局中斷
CONTRL=1;
//初始化完成......
}
/**********************************
void reset()
{
CONTRL=0;
FLAG=0;
TL0=0x00;
TH0=0x00;
TL1=0x00;
TH1=0x00;
TF2=0;
TH2=256/256;
TL2=256%256;
TR1=1;//先允許T1定時,因T1的GATE=1,還要等外部INT1高電平才計數
TR0=1;//先允許T0計數 ,同T1一樣,等待INTO高電平
TR2=1;//啟動T2定時,不用外部控制,直接啟動
EA=1; //開全局中斷
CONTRL=1;
}
*******************************/
//鍵盤掃描
uchar scanf()
{
uchar value;
P0=0xff;
delayms(1);
SCANF=0;//打開鍵掃閘門
value=P0;
delayms(2);
value=P0;
SCANF=1;
return value;
}
/********************************/
//鍵處理
void keychuli()
{
uchar k;
//關于指示燈,交流和頻率是一組,直流和其他項是一組
/***************************************/
/******************/
key=scanf();
/******************/
//啟動鍵判斷
if(key1==0&&key7==0&&DAT[4]==0)//啟動位 ,油壓和轉速為0
{
for(k=0;k<3;k++)//三次啟動循環
{
P0=0x04;//準備 輸出K6繼電器
SHUCHU=0;//打開閘門
delays(3);//隔三秒響應一次停機鍵
//響應停機鍵
key=scanf();
if(key0==0&&key7==1&&DAT[4]>500)//停機開關狀態,油壓高,轉速達到500,其他繼電器都停止工作 ,所以 ,P0=0x08
{
P0=0x03;//準備 輸出K0繼電器
SHUCHU=0;//打開輸出閘門
SHUCHU=1;//關閉閘門
outflag=0;//輸出標志位
}
if(key1==0&&key7==1&&DAT[4]>430) //每啟動一次都判斷是否成功,成功直接跳出
break ; //判斷啟動成功,立即跳出啟動for 循環
delays(3);//沒有啟動成功,繼續啟動3秒
key=scanf();
if(key1==0&&key0==0&&key7==1&&DAT[4]>500)//停機,油壓高,轉速達到500,其他繼電器都停止工作 ,所以 ,P0=0x08
{
P0=0x03;//準備 輸出K0繼電器
SHUCHU=0;//打開輸出閘門
SHUCHU=1;//關閉閘門
outflag=0;//輸出標志位
}
if(key1==0&&key7==1&&DAT[4]>430) //每啟動一次都判斷是否成功,成功直接跳出
break ;
delays(3);
key=scanf();
if(key0==0&&key7==1&&DAT[4]>500)//停機,油壓高,轉速達到500,其他繼電器都停止工作 ,所以 ,P0=0x08
{
P0=0x03;//準備 輸出K0繼電器
SHUCHU=0;//打開輸出閘門
SHUCHU=1;//關閉閘門
outflag=0;//輸出標志位
}
if(key1==0&&key7==1&&DAT[4]>430) //每啟動一次都判斷是否成功,成功直接跳出
break ;
P0=0x00;//停止啟動
SHUCHU=0;
SHUCHU=1;
delays(9);
}//for啟動循環結束
SHUCHU=1;//關閉閘門
/**********************/
//啟動失敗判斷
if(key7==0) //油壓低
if(DAT[4]<440)
{
P0=0x01;//點亮啟動失敗燈
LED1=0;//開啟573輸入
LED1=1;//關閉使能,74HC573鎖定狀態
outflag=0;//輸出標志位清0,表示輸出未允許
}
}
//停機鍵判斷
/********************/
if(key0==0&&key7==1&&DAT[4]>500)//停機,油壓高,轉速達到500,其他繼電器都停止工作 ,所以 ,P0=0x08
{
P0=0x03;//準備 輸出K0繼電器
SHUCHU=0;//打開輸出閘門
SHUCHU=1;//關閉閘門
outflag=0;//輸出標志位
}
/*****************/
//應急鍵判斷
if(key6==1)//應急/正常,高電位應急
{
eding=1;//應急標志
}
else if(key6==0) //進入怠速
{
eding=0;//怠速標志
}
if(eding==0)//對怠速的處理
{
P0=0x08;//怠速,準備打開K5繼電器,關閉其他輸出繼電器
SHUCHU=0;//打開輸出閘門
SHUCHU=1;//關閉閘門
outflag=0;
}
if(eding==1&&outflag==0)//對額定的處理
{
P0=0x00;//額定,準備關閉K5繼電器,進入額定,其他繼電器都停止工作 ,所以 ,P0=0x00
SHUCHU=0;//打開輸出閘門
SHUCHU=1;//關閉閘門
delayms(2);
if(DAT[0]>110&&DAT[1]>110&&DAT[2]>110&&DAT[5]>390)//三相交流大于110 ,頻率大于390
{
P0=0x30;//準備合閘(交流,直流 內控制 )
SHUCHU=0;
SHUCHU=1;
outflag=1;//合閘后,輸出標志位置1
}
}
/******************************/
//循環鍵
if(key2==1) //處理循環定點顯示標志位
xunhuanflag=1;
else if(key2==0)
xunhuanflag=0;
/**********保護函數*******************/
void baohu()
{
if(outflag==1)
{
//立即保護值
if((DAT[0]<80||DAT[1]<80||DAT[2]<80) || (DAT[0]>180||DAT[1]>180||DAT[2]>180) || DAT[5]>445||DAT[5]<320)//立即斷閘保護
{
{
P0=0x00;//準備斷閘(交流,直流 內控制 )
SHUCHU=0;
SHUCHU=1;
outflag=1;//合閘后,輸出標志位清0
}
if((DAT[0]>180||DAT[1]>180||DAT[2]>180)&&DAT[5]>445)
{P0=0x05;
/*******************************/
//轉速計算 ,頻率計算
void zhuansu()
{
t1h=TH0;
t1l=TL0;
t2h=TH1;
t2l=TL1;
cnt1=t1l+(t1h<<8);
cnt2=t2l+(t2h<<8);
DAT[6]=cnt1/cnt2*1000000.200;//計數值
DAT[4]=cnt1/cnt2*1000000.200/124.00*600.00; //計算轉速,信號頻率就是單片機計數頻率的整數倍 ,這里這樣寫是怕cnt1 cnt2 超出范圍
//注意這里: cnt1 cnt2 的類型不能是 uint 否則第一步計算除法會得0 , 如果你要先乘1000000.0,也不行。因為超出了uint 范圍
DAT[5]=DAT[4]*16.00/60.000;//電壓頻率計算
}
/******************************/
//外部中斷0,調用轉速計算
void interint0() interrupt 0 //using **
//外部中斷0處理
{
EA=0;
zhuansu();//調用轉速函數
FLAG=1;
/***注意:因為TO T1是外部引腳控制的,所以,這時外部低電平,自動停止。不用軟件停止**/
}
void intertimer2() interrupt 5 //using **
//T2定時中斷處理
{
TR2=0;
CONTRL=0;//關閉閘門信號
}
/*******************************/
//AD轉換程序
/************************************************/
//常測數據函數
void voltage() //電壓測量
{
uchar i;
AD=0.00;
X=0;
for(i=0;i<20;i++)
{
AD+=rd1543(0x08); //讀取AD值
}
//
AD=AD/20;
X=AD*46.0001*50.00/1023.00;//轉換成電壓值 ,分辨率是10位
DAT[0]=X;
AD=0.00;
delayus(2);
//
for(i=0;i<20;i++)
{
AD+=rd1543(0x08); //讀取AD值
}
//
AD=AD/20;
X=AD*46.0001*50.00/1023.00;//轉換成電壓值 ,分辨率是10位
DAT[1]=X;
//
AD=0.00;
delayus(2);
//
for(i=0;i<20;i++)
{
AD+=rd1543(0x08); //讀取AD值
}
//
AD=AD/20;
X=AD*46.0001*50.00/1023.00;//轉換成電壓值 ,分辨率是10位
DAT[2]=X;
//
AD=0.00;
delayus(2);
//
/*********
for(i=0;i<20;i++)
{
AD+=rd1543(0x07); //讀取AD值
}
//
AD=AD/20;
X=AD*50.000/1023.000*28.500/4.000;
DAT[3]=X;
//
**********/
}
/***********************************************/
//TLC1543輸入模擬電壓范圍: 0-4.9152 V
//TLC1543AD 10個時鐘方式 方式1 。 LC1543 有四位精度 。 輸入 0.0024v 時,AD值為0000000001
//0.0048時,還為1。 0.0072為 2 也就是0.0048 為一個 寬度 0.0048*AD 就是電壓值 .
uint rd1543(uchar addr)
{
uint date_out=0;
uchar k;
// uchar j;
CLK=0;
CS=0;
ADDRESS=(bit)(addr&0x08); //用這種愚蠢的方法比用FOR循環快的多 。
CLK=1;
CLK=0;
addr=addr*2; //用乘法比用左移快
ADDRESS=(bit)(addr&0x08);
CLK=1;
CLK=0;
addr=addr*2; //用乘法比用左移快
ADDRESS=(bit)(addr&0x08);
CLK=1;
CLK=0;
addr=addr*2; //用乘法比用左移快
ADDRESS=(bit)(addr&0x08);
CLK=1;
CLK=0;
addr=addr*2; //用乘法比用左移快
// for (j=0;j<6;j++) //填充6 個CLOCK
// {
CLK=1;CLK=0; //這里不用循環,省時間
CLK=1;CLK=0;
CLK=1;CLK=0;
CLK=1;CLK=0;
CLK=1;CLK=0;
CLK=1;CLK=0;
CLK=0;
// }
CS=1;
delayus(8); //等待AD 轉換
CS=0;
for(k=0;k<10;k++)
{
SDATA=1; //非P0口作為數據總線使用時,讀入數據前要賦值1,特別
CLK = 1; //是既用于寫有用于讀的情況下.
date_out<<=1;
if(SDATA) date_out += 1; //這樣寫法比下面的方法速度快(5us)
// date_out=date_out|SDATA;//用時6US
CLK = 0;
}
return(date_out);
}




