8.3.1 電子秤技術(shù)指標和功能要求
1. 預(yù)存10組儲單重值,方便調(diào)出。
2. 計數(shù):能已知單重求個數(shù),已知個數(shù)求得單重再計數(shù)。
3. 去皮:已知皮重扣除指定的皮,一次性扣除秤上的皮。
4. 零點:偶爾會發(fā)生零點漂移現(xiàn)象,可按零點回零。
5. 累計:個數(shù),重量。
6. 預(yù)先設(shè)定個數(shù)上下限值,重量上下值。超過上下限自動報警
7. 單位轉(zhuǎn)換:千克,英磅,盎司,金衡盎司,克拉,英錢,克。
8. 開關(guān)背光,蜂鳴器。
9. 外部進行校正(在秤發(fā)生漂移時,可以進行校正)。
10. 精度可達0.1,0.2,0.5,1,2,5,10,20,50g等可調(diào)(通過調(diào)軟件,換傳感器達到)。
11. 外碼可達60000(通過軟件設(shè)置,可達幾十種不同規(guī)格的量程和精度的電子秤)。
12. 電源檢測
13. 當(dāng)電池電壓下降至5.25 0.1V,電源指示燈紅燈亮,則表示要充電。若此時不充電,將有可能因電壓太低而出現(xiàn)稱量不準或不穩(wěn)定。如繼續(xù)使用超過2小時,電子天平將自動關(guān)機,進入保護模式。
14. 傳感器:電阻應(yīng)變式秤重傳感器。
15. 額定電壓:
16. 交流 AC 220V(+10%-15%)50Hz 1Hz;
17. 直流 DC6V/4AH充電電池(充電式)。
18. 貯藏:-40~60 19. 工作:5~40 20. 濕度:
21. 貯藏:<=70%RH無結(jié)露;
22. 工作:<=90%RH無結(jié)露。
23. 內(nèi)部采用20位專用AD。
8.3.2 功能詳細說明
1. 單重(個數(shù))預(yù)設(shè)
(1) 如何預(yù)設(shè)單重(個數(shù))
1) 利用數(shù)字鍵0~9輸入單重值(個數(shù))。
2) 按“單重預(yù)設(shè)”鍵。個數(shù)欄顯示“PrSET”。
3) 按“單重預(yù)設(shè)”鍵。重量欄顯示“SET”。
4) 按0~9任何一鍵,即可將單重(個數(shù))存入此鍵。
(2) 如何叫出所預(yù)設(shè)之單重(個數(shù))
1) 按“單重預(yù)設(shè)”鍵。個數(shù)欄顯示“PrSET”。
2) 按0~9任何一鍵,即可將此鍵內(nèi)之單重(個數(shù))叫出。
說明:個數(shù)最多為65545個以下,重量的小數(shù)最多為兩位。
2. 計數(shù)
在計算數(shù)量前,必須先作取樣步驟以求得待稱物品之單重。取樣方法有下列2種。
(1) 待秤物品之單重未知
1) 將一取樣物品置于天平盤上。
2) 輸入天平上取樣物品之?dāng)?shù)量。
3) 按“個數(shù)設(shè)定”鍵。
4) 當(dāng)電子秤穩(wěn)定后,即取樣完成進入計數(shù)模式。
(2) 待秤物品之單重已知
1) 輸入已知的待秤物品之單重 ,進入計數(shù)模式。
2) 取樣之?dāng)?shù)量愈大,所計算出之單重愈精確。
3. 扣除包裝物品之重量
(1) 包裝物品置于天平盤上。
(2) 按“去皮”鍵。重量欄顯示“tArE”。
(3) 當(dāng)電子秤穩(wěn)定后,即進入計數(shù)模式。
將天平上物品與包裝一并移開后,重量欄將顯示包裝物品重量之負值,此時再按一次“去皮”鍵,即可取消去皮,使重量歸零且去皮符號“p”消失。
4. 零點
電子秤在工作過程中,偶爾會發(fā)生零點漂移現(xiàn)象,(即重量欄之重量有微小變動)此時按“零點”鍵可使重量回復(fù)。
5. 累計
(1) 將物品置于天平盤上。
(2) 按“累計”鍵。
(3) 當(dāng)電子秤穩(wěn)定后。重量欄顯示總重量,個數(shù)欄顯示出總個數(shù),單重欄顯示總筆數(shù)。
(4) 約3秒后,電子秤回復(fù)計數(shù)模式。
累計筆數(shù)最多為99筆,但位數(shù)為6位。
按“累計清除”鍵,即可將記憶中之累計值清除且累計符號“p”消失。
6. 數(shù)量預(yù)設(shè)(括號中為下限值)
計數(shù)時可預(yù)先設(shè)定數(shù)量之上(下)限值,以后每次計算數(shù)量,若超過(少于)此數(shù)值即有警告聲且單重欄有—o.ty—(—SLX--)字樣閃動。
7. 如何預(yù)設(shè)數(shù)量之上(下)限值
(1) 天平盤上有無物品皆可,請按“數(shù)量預(yù)設(shè)”鍵。個數(shù)欄出現(xiàn)“SLYS”
(2) 按數(shù)字鍵“1”(“3”),重量欄出現(xiàn)“SZ---1”(“SZ---3)。
(3) 輸入欲設(shè)定之上(下)限值。(可利用“清除”鍵修改所輸入之?dāng)?shù)值)
(4) 按“個數(shù)設(shè)定”鍵。(可利用“清除”鍵修改所輸入之?dāng)?shù)值。
(5) 按“數(shù)量預(yù)設(shè)”鍵。電子秤回復(fù)計數(shù)模式。
8. 重量預(yù)設(shè)
可預(yù)先設(shè)定重量之上(下)限值,以后每次秤重時,若超過(少于)此數(shù)值即有警告聲且單重欄有uuPST字樣閃動。
9. 如何預(yù)設(shè)數(shù)量之上(下)限值
(1) 秤盤上有無物品皆可,請按“數(shù)量預(yù)設(shè)”鍵。個數(shù)欄出現(xiàn)“SLYS”
(2) 按數(shù)字鍵“2”(“4”),重量欄出現(xiàn)“SZ---2”(“SZ---4)。
(3) 輸入欲設(shè)定之上(下)限值。(可利用“清除”鍵修改所輸入之?dāng)?shù)值)
(4) 按“單重設(shè)定”鍵。(可利用“清除”鍵修改所輸入之?dāng)?shù)值。
(5) 按“數(shù)量預(yù)設(shè)”鍵。電子秤回復(fù)計數(shù)模式。
10. 清除所預(yù)設(shè)之上(下)限值
欲清除所設(shè)數(shù)量或重量之上(下)限值,請依上述預(yù)設(shè)步驟操作,在輸入預(yù)設(shè)時,則輸入“0”即可。
說明:所設(shè)定的數(shù)字為重量欄所要出現(xiàn)的數(shù)字,不包括小數(shù)點,如:量程為3千克,精度為0.1,(3000.0),設(shè)定上限值為2000克,即輸入20000即可。
11. 單位切換
先按長按“清除”鍵,直到出現(xiàn)CENTR,接著再按“0”,接著按“.”鍵,會在“Kg,ct,lb,oz,ozt,dwt,g”之間切換,確認好所選單位后,按“去皮”鍵確認。
12. 背光
13. 自動背光模式
先按長按“清除”鍵,直到出現(xiàn)CENTR,接著再按“5”
當(dāng)天平盤上放置物品時,背光點亮,按按鍵時,(背光亦點亮,待歸零后約5秒背光熄滅。)
14. 一般背光模式
先按長按“清除”鍵,直到出現(xiàn)CENTR,接著再按“4”,背光一直點亮。
15. 取消背光
先按長按“清除”鍵,直到出現(xiàn)CENTR,接著再按“6”,開機后電子秤將記憶住所選用之背光模式,待下次開機后,(維持相同之背光模式。)
16. 蜂鳴器
先按長按“清除”鍵,直到出現(xiàn)CENTR,按“2”,表示按鍵也有聲音發(fā)出。如是按“3”,表示按鍵沒有聲音發(fā)出。
開機后電子秤將記憶住所選用之蜂鳴模式, 待下次開機后,(維持相同之蜂鳴模式。)
17. 外部校正
(1) 按長按“清除”鍵,直到出現(xiàn)CENTR,按“8”,個數(shù)欄出現(xiàn)“CAL”,個數(shù)欄出現(xiàn)“999”。
(2) 按“去皮”確認進入標定零點狀態(tài),(按“清零”鍵退出零點標定。)紅燈亮。在單重欄會出現(xiàn)當(dāng)前的內(nèi)碼值。內(nèi)碼確定好以后,綠燈亮,個數(shù)欄出現(xiàn)“989”,按“去皮”鍵確認,進入上限標定狀態(tài)。按“清零”鍵放棄存入內(nèi)碼值,進入上限標定狀態(tài)。
(3) 顯示“000000”,按“累計”切換閃炫的位,按“.”閃炫位加一。注意:標定時,砝碼不能大于最大量程,最小不能小于分度數(shù)。設(shè)定好后,按“去皮”進入取碼狀態(tài),紅燈亮。內(nèi)碼確定好后,綠燈亮,個數(shù)欄出現(xiàn)“888”。按“去皮”確認,自動重新初始化。(也可按“清零”鍵取消退出或放棄存入內(nèi)碼值。
18. 調(diào)入出廠之校正值
按長按“清除”鍵,直到出現(xiàn)CENTR,按“8”,即可,標定好以后,自動重新初始化。
19. 標定與調(diào)試
在顯示啟動畫面時,打開標定開關(guān),可進入標定與調(diào)試狀態(tài)。
(1) 分度數(shù)選擇:顯示[N ****]
按“.”鍵,顯示的****字為,3000, 6000,7500,10000,12000,15000,20000,30000,60000,100000循環(huán)改變,選擇其中一項,按“去皮”鍵確認,自動進入下一步驟。如該項不要改變,則按“清除”鍵進入 下一步驟。
(2) 分度值選擇:顯示[E *]
按“.”鍵,顯示的*字為,1,2,5,10,20,50循環(huán)改變,選擇其中一項,按“去皮”鍵確認,自動進入下一步驟。如該項不要改變,則按“清除”鍵進入下一步驟。
(3) 小數(shù)點選擇:顯示[D 0.0]
按“.”鍵,顯示的數(shù)字為,0,0.0,0.00,0.000,0.0000循環(huán)改變,選擇其中一項,按“去皮”鍵確認,自動進入下一步驟。如該項不要改變,則按“清除”鍵進入 下一步驟。
(4) 滿量程顯示:顯示[***.**]
將上面確認的分度數(shù)(例如:3000)乘以分度值(例如:5),再配以小數(shù)點(例如:0.00),使用戶確認是否要高置的滿量程值(例如:150.00),如不是,把標定開關(guān)關(guān)上再打開即可重新標定上述三步。如是,則按“清除”鍵進入下一步驟。
(5) 零跟蹤范圍的確定:顯示[01 *.*]
按“.”鍵,顯示的*.*字為,0 .5,1 .0,2 .0循環(huán)改變,表示范圍為:0 .5,1E,2E,選擇其中一項,按“去皮”鍵確認,自動進入下一步驟。如該項不要改變,則按“清除”鍵進入下一步驟。
(6) 開機判零范圍:顯示[02 ***]
按“.”鍵,顯示的*.*字為,0 .10,0 .20,1.00循環(huán)改變,表示當(dāng)零位不要保存時(后面的步驟8中期4設(shè)為0),開機時稱量值如在上述設(shè)定的10%FS,20%FS,100%FS范圍內(nèi),稱量值置零,否則以原來儲存的零位作為開機時的零位。選擇其中一項,按“去皮”鍵確認,自動進入下一步驟。如該項不要改變,則按“清除”鍵進入下一步驟。
(7) 手動置零范圍選擇:顯示[05 .**]
按“.”鍵,數(shù)字在0.02,0.04,0.08,1.00循環(huán),表示范圍為2%,4%,8%,100%F.S。選擇其中一項,按“去皮”鍵確認,自動進入下一步驟。如該項不要改變,則按“清除”鍵進入 下一步驟。
(8) 濾波常數(shù)的選擇:顯示為[LB *]
按“.”鍵,數(shù)字在1,2,3,4,5 ,6, 7, 8, 9, 10循環(huán),分別表示濾波常數(shù)為40,60,80,100,120數(shù)字越大,刷新速度越慢,但穩(wěn)定性愈好。選擇其中一項,按“去皮”鍵確認,自動進入下一步驟。如該項不要改變,則按“清除”鍵進入下一步驟。
(9) 零位的確定:顯示[CAL ]兩秒鐘,再顯示[NOLOAD]
檢查秤上是否空,顯示“999”,稍等十秒鐘左右,讓秤加零穩(wěn)定,顯示“989”,按“去皮”鍵確認,自動進入下一步驟。如該項不要改變,則按“清除”鍵進入 下一步驟。
(10) 滿值的標定(標定的砝碼越接近或等于滿值越好)。顯示加數(shù)砝碼為[000000](此處應(yīng)說明以什么為單位輸入),最左一位閃爍。
按“累計”鍵可向右循環(huán)改變閃爍位。按“.”鍵閃爍位加1。逐位打入實際加載的砝碼數(shù)。按“去皮”鍵確認,顯示“898”,稍等10秒~20秒鐘左右,讓秤加零穩(wěn)定,顯示“888”,(如重量值太小,則顯示[END ]約3秒鐘,再重復(fù)上述過程),最后顯示為[END]。如該項不做,則按“清除”也可。
(11) 關(guān)上標定開關(guān),標定結(jié)束。(我們用的不是標定開關(guān)而是跳線,標定時跳線在ADJ,不標定時跳線在LOCK)
8.3.3 詳細設(shè)計
1. 硬件設(shè)計
(1) 主要原器件
89C52、CS5513、OPA2277、CSI93C46、HT1622等
(2) 硬件原理圖
1) 鍵盤原理圖:

按鍵分布與鍵面文字:

2) LCD部分原理圖及MCU部分電路:
2. 程序代碼
(1) 軟件初始化與LCD
LCD驅(qū)動芯片HT1622介紹:




其它讀寫時序可以到網(wǎng)上下載相應(yīng)資料。
#include "head.h"
const UINT8 Number[20]=
{0xbe,0x06,0x7c,0x5e,0xc6,0xda,0xfa,0x0e,0xfe,0xde,0xbf,0x07,0x7d,
0x5f,0xc7,0xdb,0xfb,0x0f,0xff,0xdf};
data UINT8 LcdRam[18];
data char Slsdcs; //計錄“數(shù)量設(shè)定次數(shù)?
data uchar Dzz; //計錄“單重值”
data char Wpsl; //計錄“物品數(shù)量?
data char Ljcs; //計錄“累計次數(shù)”
data char Dssl; //計錄“定數(shù)數(shù)量”
data uchar Dszl; //計錄“定數(shù)重量”
data uchar Qpz; //計錄“去皮值”
//data float zl[10]; 用來存放“單重預(yù)設(shè)”值
/*
LcdDATSet1(13,0x01);
LcdDATSet1(13,0x02);
LcdDATSet1(13,0x04);
LcdDATSet1(13,0x08);
LcdDATSet1(14,0x04);
LcdDATSet1(14,0x08); 顯示 每個數(shù)字底下的“▽”
LcdDATSet1(14,0x02); 顯示 “k”
LcdDATSet1(14,0x01); 顯示 “g”
LcdDATSet1(15,0x08); 顯示 “oz"
LcdDATSet1(14,0x04); 顯示 “t"
LcdDATSet1(14,0x02); 顯示 "lb"
LcdDATSet1(14,0x01); 顯示 "dwt"
LcdDATSet1(15,0x08); 顯示 "ct"
LcdDATSet1(14,0x04); 顯示 "wot"
LcdDATSet1(14,0x02); 顯示 "tl"
LcdDATSet1(14,0x01); 顯示 "pcs"
LcdDATSet1(14,0x08); 顯示 "%"
LcdDATSet1(14,0x04); 顯示 " "
LcdDATSet1(14,0x02); 顯示 "-"
LcdDATSet1(14,0x01); 顯示 "◎"
LcdDATSet1(7,0x0b);
LcdDATSet1(8,0x0e);
LcdDATSet1(9,0x0e);
LcdDATSet1(10,0x08); 顯示 ”off"
*/
//const UINT8 a[5]={0xec,0x60,0xc6,0xf8,0xf0}; //顯示 "pnset",按“單重預(yù)設(shè)”所出現(xiàn)的
//const UINT8 b[5]={0xc6,0xee,0x62,0x62,0xec}; //顯示 "5annp",按“個數(shù)設(shè)定”所出現(xiàn)的
//const UINT8 c[4]={0xf0,0xee,0x60,0xf8}; //顯示 "tane",按“去皮”所出現(xiàn)的
//const UINT8 d[5]={0xec,0x60,0xf8,0xf0,0xee}; //顯示 "pneta",按“去皮”所出現(xiàn)的
void LcdInit(void)
{
LcdCmdSet1(0x01);
LcdCmdSet1(0x03);
Delay1(100);
ClearScreen();
Delay1(50);
}
void ClearScreen(void)
{
LcdDATSet1(1,0x00);
LcdDATSet1(2,0x00);
LcdDATSet1(3,0x00);
LcdDATSet1(4,0x00);
LcdDATSet1(5,0x00);
LcdDATSet1(6,0x00);
LcdDATSet1(7,0x00);
LcdDATSet1(8,0x00);
LcdDATSet1(9,0x00);
LcdDATSet1(10,0x00);
LcdDATSet1(11,0x00);
LcdDATSet1(12,0x00);
LcdRam[1]=0x00;
LcdRam[2]=0x00;
LcdRam[3]=0x00;
LcdRam[4]=0x00;
LcdRam[5]=0x00;
LcdRam[6]=0x00;
LcdRam[7]=0x00;
LcdRam[8]=0x00;
LcdRam[9]=0x00;
LcdRam[10]=0x00;
LcdRam[11]=0x00;
}
void DisplayNumber(UINT8 who,float num)
{
char temp1;
char j;
char l;
int sss=30000;
float temppara;
char n[11];
temppara=num;
sss=(int)temppara;
if(temppara>0)
{
for (j=6;j>0;j--)
{
temp1=(sss%Pow(10,j))/Pow(10,j-1);
l=abs(j-6);
n[l]=temp1;
}
for (j=1;j<6;j++)
{
temp1=((sss*Pow(10,j))%10)/1;
l=abs(6+j);
n[l]=temp1;
}
j=-1;
while (n[++j]!=0)
{
}
for (temp1=j;temp1
{
}
}
else if(temppara==0)
{
switch (who)
{
case 1:
{
LcdDATSet1(11,0x0b);
LcdDATSet1(12,0x0e);
}
case 2:
{
LcdDATSet1(11,0xb0);
LcdDATSet1(12,0xe0);
}
case 3:
{
LcdDATSet1(28,0x0b);
LcdDATSet1(29,0x0e);
}
}
}
}
void LcdDATSet1(UINT8 addr,UINT8 dat)
{
UINT8 i,temp;
LCD_CS = 0;
LCD_SD = 1;
LCD_CD = 0;
LCD_CD = 1;
LCD_SD = 0;
LCD_CD = 0;
LCD_CD = 1;
LCD_SD = 1;
LCD_CD = 0;
LCD_CD = 1;
temp=(addr-1)*2;
temp=temp<<2;
for(i=0;i<6;i++)
{
if (temp & 0x80)
LCD_SD = 1;
else
LCD_SD = 0;
LCD_CD = 0;
LCD_CD = 1;
temp = temp << 1;
}
for (i = 0; i < 8; i++) {
if (dat & 0x80) LCD_SD = 1;
else LCD_SD = 0;
LCD_CD = 0;
LCD_CD = 1;
dat = dat << 1;
}
LCD_SD=1;
LCD_CD=0;
LCD_CD=1;
LCD_CS= 1;
}
void LcdCmdSet1(UINT8 cmd)
{
UINT8 i;
LCD_CD = 1;
LCD_CS = 0;
LCD_SD = 1;
LCD_CD = 0;
LCD_CD = 1;
LCD_SD = 0;
LCD_CD = 0;
LCD_CD = 1;
LCD_SD = 0;
LCD_CD = 0;
LCD_CD = 1;
for (i = 0; i < 8; i++) {
if (cmd & 0x80) LCD_SD = 1;
else LCD_SD = 0;
LCD_CD = 0;
LCD_CD = 1;
cmd = cmd << 1;
}
LCD_SD=0;
LCD_CD=0;
LCD_CD=1;
LCD_CS= 1;
}
void disp(UINT8 who,UINT8 n,UINT8 num)
{
UINT8 who1,i,dd;
i=num;
who1=who;
dd=n;
if (who1==1)
{
LcdRam[dd*2-2]=(Number[i]>>4)|(LcdRam[dd*2-2]&0xf0);
LcdRam[dd*2-1]=0x0f&Number[i]|(LcdRam[dd*2-1]&0xf0);
LcdDATSet1(dd*2-1,LcdRam[dd*2-2]);//(Number[i]>>4)|(LcdRam[dd*2-2]&0xf0));
LcdDATSet1(dd*2,LcdRam[dd*2-1]);//(0x0f&Number[i])|(LcdRam[dd*2-1]&0xf0));
}
if(who1==2)
{
LcdRam[dd*2-2]=0xf0&Number[i]|(LcdRam[dd*2-2]&0x0f);
LcdRam[dd*2-1]=((Number[i]<<4))|(LcdRam[dd*2-1]&0x0f);
LcdDATSet1(dd*2-1,LcdRam[dd*2-2]);//(0xf0&Number[i])|(LcdRam[dd*2-2]&0x0f));
LcdDATSet1(dd*2,LcdRam[dd*2-1]);//(0xf0&(Number[i]*16))|(LcdRam[dd*2-1]&0x0f));
}
if (who1==3)
{
LcdDATSet1(dd*2+16,(Number[i]>>4));
LcdDATSet1(dd*2+17,(0x0f&Number[i]));
}
}
void Disp9to0(void)
{
int i=0,j=0,k=0;
for (k=0;k<10;k++)
{
Delay1(800000);
for (i=1;i<7;i++)
{
disp(2,i,k+10);
Delay1(80);
disp(1,i,k+10);
}
}
}
UINT32 Pow(int n,int m) //n的m次方計算函數(shù)
{
UINT32 result=1;
int x,y;
int i;
x=n;
y=m;
if (y==0)
return (1);
else
{
for(i=0;i
result=x*result;
return (result);
}
}
(2) A/D CS5513
1) 讀數(shù)據(jù)時序:
UINT32 CS5513READDATA(void)
{
idata UINT8 i;
idata UINT32 CS5513DATA;
AD_CS=0;
AD_CLK=0;
CS5513DATA=0;
Delay1(10);
while(AD_SD !=0) //等待數(shù)據(jù)轉(zhuǎn)換完成
{
}
for (i=0;i<24;i++)
{
CS5513DATA <<=1;
AD_CLK=1;
Delay1(10);
if(AD_SD==1)
CS5513DATA |= 0x01;
AD_CLK=0;
Delay1(10);
}
CS5513DATA &=0XFFFFF; //取20位有效數(shù)據(jù)
AD_CS=1;
return(CS5513DATA);
}
(3) SPI總線及93C46
1) SPI總線工作原理
?、?概述
CSI93C46/56/57/66/86 是一種存儲器,可以定義為16 位ORG 引腳接Vcc, 或者定義為8 位ORG 引腳接GND 的1K/2K/2K/4K/16K 位的串行E2PROM 。每一個的存儲器都可以通過DI 引腳或DO 引腳,進行寫入或讀出。每一片CSI93C46/56/57/66/86 都是采用CSIalyst 公司先進的CMOS E2PROM 浮動門工藝。加工器件可以經(jīng)受1,000,000 次的寫入/擦除操作,片內(nèi)數(shù)據(jù)保存壽命達到100 年。器件可提供的封裝有DIP-8 SOIC-8 TSSOP-8。
?、?管腳配置及其方框圖
管腳說明
說明:當(dāng)ORG 接Vcc 時存儲器為16 位結(jié)構(gòu)
當(dāng)ORG 接GND ,是存儲器為8 位結(jié)構(gòu)。
當(dāng)ORG引腳懸空時,內(nèi)部的上拉電阻把存儲器選擇為16 位結(jié)構(gòu)。
管腳名稱功能
CS 片選信號
SK 時鐘輸入
DI 串行數(shù)據(jù)輸入
DO 串行數(shù)據(jù)輸出
Vcc 電源+1.8 伏到6 伏
GND 接地
ORG 存儲器結(jié)構(gòu)選擇
NC 不用連接
PE* 寫入保護
圖示:數(shù)據(jù)傳輸同步時序
void EEPROMByteWrite0(UINT8 addr,UINT8 value)//寫一個字節(jié)內(nèi)容
{
EwenROM();
WriteRom(addr,value);
EwdsROM();
SCKPIN=0;
Delay1(20);
}
void EwdsROM(void) //寫停止
{
SCKPIN=0;
_nop_();
CSPIN=1;
_nop_();
SDIPIN=1;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=0;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=0;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
WR_3wire(0x00);
SDIPIN=0;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=0;
_nop_();
CSPIN=0;
_nop_();
_nop_();
}
void WriteRom(UINT8 addr,UINT8 value) //寫數(shù)據(jù)value到地址addr
{
UINT16 i;
SCKPIN=0;
_nop_();
CSPIN = 1;
_nop_();
_nop_();
SDIPIN=1;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=0;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=1;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=0;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
WR_3wire(addr);
WR_3wire(value);
_nop_();
CSPIN=0;
_nop_();
SDOPIN=1;
_nop_();
CSPIN=0;
_nop_();
CSPIN=1;
_nop_();
for(i=0;i<1000;i++)
{
if(SDOPIN || i>=1000)
break;
}
SDIPIN=0;
CSPIN=0;
}
void EwenROM(void) //寫允許
{
SCKPIN=0;
_nop_();
CSPIN=1;
_nop_();
SDIPIN=1;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=0;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=0;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
WR_3wire(0xc0);
SDIPIN=0;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=0;
_nop_();
CSPIN=0;
_nop_();
_nop_();
}
void WR_3wire(UINT8 value)
{
UINT8 i;
for(i=0;i<8;i++)
{
if(value&0x80)
SDIPIN=1;
else
SDIPIN=0;
value<<=1;
_nop_();
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
_nop_();
}
}
UINT8 EEPROMByteRead0(UINT8 addr) //讀ADDR中的內(nèi)容
{
UINT8 value;
SCKPIN=0;
_nop_();
CSPIN=1;
_nop_();
SDIPIN=1;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=1;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=0;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
SDIPIN=0;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
SCKPIN=0;
_nop_();
WR_3wire(addr);
Delay1(1);
value=ReceiveByte();
SCKPIN=0;
CSPIN=0;
Delay1(20);
return value;
}
UINT8 ReceiveByte(void)
{
UINT8 i;
UINT8 value=0;
SDOPIN=1;
for(i=0;i<8;i++)
{
SCKPIN=0;
_nop_();
SCKPIN=1;
_nop_();
_nop_();
value<<=1;
if(SDOPIN) value|=0x01;
SCKPIN=0;
}
_nop_();
_nop_();
return value;
}
(4) 鍵盤掃描
UINT8 Scankey(void)
{
UINT8 ee=0,temp1,j;
Keyval=0;
temp1=0xff;
j=0;
ET0=0;
sum=0;
longtime=0;
while(temp1==0xff)
{
j=0;
temp1=0xff;
KEY_IN1=0;
KEY_IN2=0;
KEY_IN3=0;
KEY_IN4=0;
KEY_IN5=0;
Delay1(1);
if (KEY_OUT1==0)
temp1=1;
if (KEY_OUT2==0)
temp1=2;
if (KEY_OUT3==0)
temp1=3;
if (KEY_OUT4==0)
temp1=4;
KEY_IN1=1;
KEY_IN2=1;
KEY_IN3=1;
KEY_IN4=1;
KEY_IN5=0;
Delay1(1);
if (KEY_OUT1==0 || KEY_OUT2==0 || KEY_OUT3==0 || KEY_OUT4==0)
j=1;
KEY_IN1=1;
KEY_IN2=1;
KEY_IN3=1;
KEY_IN4=0;
KEY_IN5=1;
Delay1(1);
if (KEY_OUT1==0 || KEY_OUT2==0 || KEY_OUT3==0 || KEY_OUT4==0)
j=2;
KEY_IN1=1;
KEY_IN2=1;
KEY_IN3=0;
KEY_IN4=1;
KEY_IN5=1;
Delay1(1);
if (KEY_OUT1==0 || KEY_OUT2==0 || KEY_OUT3==0 || KEY_OUT4==0)
j=3;
KEY_IN1=1;
KEY_IN2=0;
KEY_IN3=1;
KEY_IN4=1;
KEY_IN5=1;
Delay1(1);
if (KEY_OUT1==0 || KEY_OUT2==0 || KEY_OUT3==0 || KEY_OUT4==0)
j=4;
KEY_IN1=0;
KEY_IN2=1;
KEY_IN3=1;
KEY_IN4=1;
KEY_IN5=1;
Delay1(1);
if (KEY_OUT1==0 || KEY_OUT2==0 || KEY_OUT3==0 || KEY_OUT4==0)
j=5;
if (temp1!=0xff && j!=0 && ee==0)
{
Keyval=temp1*5+j;
j=0;
temp1=0xff;
ee++;
}
else if (temp1!=0xff && j!=0 && ee==1)
{
if (Keyval!=temp1*5+j)
{
j=0;
Keyval=0;
temp1=0xff;
ee=0;
}
else
{
ee++;
temp1=0xff;
}
}
else if(ee==2 && temp1!=0xff)
temp1=0xff;
else if(ee==2 && temp1==0xff && j==0)
break;
else if(ee==0 && temp1==0xff && j==0)
break;
if(sum==120)
{
longtime=1;
sum=0;
break;
}
}
if(slys==0)
ET0=1;
switch (Keyval)
{
case 22:
if (Once==0)
Once++;
break;
case 21: //數(shù)字0
Keyval=30;
if (Once>0)
Once++;
break;
case 16: //數(shù)字1
Keyval=31;
if (Once>0)
Once++;
break;
case 17: //數(shù)字2
Keyval=32;
if (Once>0)
Once++;
break;
case 18: //數(shù)字3
Keyval=33;
if (Once>0)
Once++;
break;
case 11: //數(shù)字4
Keyval=34;
if (Once>0)
Once++;
break;
case 12: //數(shù)字5
Keyval=35;
if (Once>0)
Once++;
break;
case 13: //數(shù)字6
Keyval=36;
if (Once>0)
Once++;
break;
case 6: //數(shù)字7
Keyval=37;
if (Once>0)
Once++;
break;
case 7: //數(shù)字8
Keyval=38;
if (Once>0)
Once++;
break;
case 8: //數(shù)字9
Keyval=39;
if (Once>0)
Once++;
break;
default:
break;
}
if(Speakflag==1)
{
if(Keyval!=0 && Keyval!=19)
{
Speak=0;
Delay1(100);
Speak=1;
}
}
return(Keyval);
}




