www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當前位置:首頁 > 工業(yè)控制 > 電子設(shè)計自動化
[導(dǎo)讀]摘要: 以例舉的方式,闡述單片機C語言編程中有關(guān)標志位的自定義以及對于其當前狀態(tài)的保存問題。從標志位的理念著手,探討在單片機C語言編程中自定義標志位的必要性、自定義標志位保存的必要性,以及自定義標志位保存

摘要: 以例舉的方式,闡述單片機C語言編程中有關(guān)標志位的自定義以及對于其當前狀態(tài)的保存問題。從標志位的理念著手,探討在單片機C語言編程中自定義標志位的必要性、自定義標志位保存的必要性,以及自定義標志位保存的幾種具體的操作方法。

引言

在現(xiàn)有的教課書及相關(guān)文章中,都難得提到在單片機C語言編程中對于自定義“位”的狀態(tài)進行保存的理念。

當單片機C語言編程中提及“位”的概念時,人們自然會想到狀態(tài)字PSW中PSW.5的F0與PSW.1的F1兩個用戶通用標志位。這兩個標志位均可參與布爾運算、“位”控操作,也可隨狀態(tài)字PSW一起保存。但是,往往會忽視這一點:在一些特定的情況下,如在C語言編程的中斷服務(wù)程序中,對狀態(tài)字PSW中PSW.5的F0與PSW.1的F1這兩個用戶標志位的操作可能是無效的。如:

void EX1_ISR() interrupt 2 {//外部中斷1

static unsigned int tempaddr;//定義接收地址緩存

static unsigned int tempkey;//定義接收數(shù)據(jù)緩存

unsigned int timecnt;

timecnt=TH1*256+TL1;

TH1=0;

TL1=0;

TR1=1;//定時器1啟動

F0=~F0;//取反F0

if(F0) {

tempaddr=tempaddr<<1;

}

else {

tempkey=tempkey<<1;

}

}

以上是一段單片機外部中斷1的中斷服務(wù)程序,乍看似乎沒什么問題,仿真調(diào)試時也能通過“編輯”。但實際上這是一段錯誤的程序——其中對“F0”用戶標志位的“取反”操作是達不到其預(yù)期效果的。因為對“F0”用戶標志位的“取反”操作是在中斷服務(wù)程序中進行的。在進入中斷時,C語言自動會保護“中斷現(xiàn)場”——將程序指針PC、累加器ACC、狀態(tài)字PSW等壓入堆棧保護起來……直到中斷返回時彈出堆棧并覆蓋了中斷服務(wù)時的變值,恢復(fù)到壓入堆棧之前的原樣。因此,狀態(tài)字PSW中的F0也不例外,如果壓入堆棧之前F0是處于邏輯“0”狀態(tài),中斷返回后還是復(fù)原成邏輯“0”狀態(tài)——不管中斷服務(wù)程序中怎么取反改變——也就是說,在中斷服務(wù)程序中試圖改變F0之值的操作是有失偏頗的。對于上文例舉的那段中斷服務(wù)程序來說,若F0的初始狀態(tài)為邏輯“0”,即進入中斷服務(wù)之前和中斷返回之后總是邏輯“0”,那么進入執(zhí)行“F0=~F0”指令后F0總是邏輯“1”,因而接下運行的是“if(F0)”下花括號中“tempaddr=tempaddr<<1;”指令,而“else”下花括號中“tempkey=tempkey<<1”指令永遠也運行不到。所以,若要中斷服務(wù)程序達到預(yù)期的效果——“if(F0)”下花括號中的指令與“else”下花括號中的指令輪番運行,必須設(shè)立一個不受中斷現(xiàn)場保護等影響的自定義標志位。

1自定義標志“位”的保存

在C語言編程中,自定義標志位的運用概率很大,有的一個程序中就會有好多的自定義標志位,且其中幾個可能是必須要保存的。譬如有些控制器件中對一些控制狀態(tài)進行保持,即使是停電之后再來電了這種控制狀態(tài)依然能保持不變——這就牽涉到保存問題。

例舉2:我們曾搞過一個鐳射投影屏幕升降的無線遙控裝置。這個以單片機為核心的控制裝置與屏幕升降的卷動電機等都安裝固定在一個直徑不足50 mm的狹長鐵桶里面,因此裝入或拆卸都非常麻煩。為了一次性成功——避免再次拆卸裝入的麻煩,在用C語言編程時我特意多用了一個自定義的標志位——翻轉(zhuǎn)標志位“switch_sign”。因為無線遙控手柄上的向上“▲”、暫?!啊觥?、向下“▼”的鍵標志都已是做定的,因此,如果由于接線等失誤導(dǎo)致按向下“▼”鍵時投影屏幕向上卷、按向上“▲”鍵時投影屏幕卻向下伸……有了“switch_sign”自定義的標志位就不用怕這些了。相關(guān)的C語言程序段如下:

#defineuint unsigned int

#defineuchar unsigned char

uint Decode_addr,Decode_key,addr;

sbit JD1_out=P0^4;//定義繼電器1控制輸出端

sbit JD2_out=P0^5;//定義繼電器2控制輸出端

sbit BEEP=P0^3;//定義蜂鳴聲響輸出

bit bdata switch_sign;//自定義的翻轉(zhuǎn)標志位(應(yīng)作全局變量定義)

voidTelecontrol_Data() {

……

if(Decode_addr==0x5535) {//地址碼核對

if(Decode_key==0x00C0) {//“▲”鍵碼核對

BEEP=1;//蜂鳴聲響輸出

if(switch_sign) {//翻轉(zhuǎn)標志位

JD1_out=0;//繼電器1控制輸出端

JD2_out=1; //繼電器2控制輸出端

}

else {

JD1_out=1;//繼電器1控制輸出端

JD2_out=0;//繼電器2控制輸出端

}

}

if(Decode_key==0x0030) {//“■”鍵碼核對

BEEP=1;//蜂鳴聲響輸出

JD1_out=0;//繼電器1控制輸出端

JD2_out=0;//繼電器2控制輸出端

}

if(Decode_key==0x000C) {//“▼”鍵碼核對

BEEP=1;//蜂鳴聲響輸出

if(switch_sign) {//翻轉(zhuǎn)標志位

JD1_out=1;//繼電器1控制輸出端

JD2_out=0;//繼電器2控制輸出端

}

else {

JD1_out=0;//繼電器1控制輸出端

JD2_out=1;//繼電器2控制輸出端

}

}

}

if(Decode_addr==0x5D35) {//取反操作糾正時地址碼核對

if(Decode_key==0x00C0) {//“▲”鍵碼核對

BEEP=1;//蜂鳴聲響輸出

switch_sign=~switch_sign; //取反一次翻轉(zhuǎn)標志位

save_data();//調(diào)用保存數(shù)據(jù)子程序

}

}

}

從上面這段遙控數(shù)據(jù)處理子程序可以看到:在任何時候兩個繼電器的控制輸出端JD1_out與JD2_out至多只能開一個。當遙控“▲”鍵按下有效時,翻轉(zhuǎn)標志位“switch_sign”的邏輯“0”或邏輯“1”狀態(tài)將決定兩個繼電器的控制輸出端JD1_out與JD2_out的一開一關(guān),或一關(guān)一開;同理,當遙控“▼”鍵按下有效時也會得到與“▲”鍵按下相反的類同效果……也就是說,只要改變翻轉(zhuǎn)標志位“switch_sign”的邏輯狀態(tài),就能改變兩個繼電器控制輸出端誰“開”誰“關(guān)”的控制輸出狀態(tài)。亦即,在同一個遙控按鍵按下時(如“▲”鍵按下),標志位“switch_sign”的邏輯狀態(tài)不同,兩個繼電器控制輸出端誰“開”誰“關(guān)”的控制輸出狀態(tài)也將不同。其中的蜂鳴聲響提示按鍵操作是否有效。

投影屏幕升降的動力電機是一個AC 220V的交流電機,圖1是電機控制電路的簡圖。由此可見,當繼電器JD1閉合,JD2斷開時,電機M中的L1為主繞組,L2為啟動副繞組,電機將一個方向運轉(zhuǎn);當繼電器JD1斷開,JD2閉合時,電機M中的L1為啟動副繞組,而L2為主繞組了,電機將以原來的反方向運轉(zhuǎn)。結(jié)合上文,改變翻轉(zhuǎn)標志位“switch_sign”的邏輯狀態(tài)→改變兩個繼電器控制輸出端誰“開”誰“關(guān)”的控制輸出狀態(tài)→改變電機的運轉(zhuǎn)方向→投影屏幕的升降狀態(tài)。也就是說,改變翻轉(zhuǎn)標志位“switch_sign”的邏輯狀態(tài),就可糾正遙控電機運轉(zhuǎn)方向及其投影屏幕的升降狀態(tài)。將遙控按鍵與投影屏幕升降的對應(yīng)關(guān)系協(xié)調(diào)后,必須保存自定義的標志位“switch_sign”當前的邏輯狀態(tài),否則,斷電后下一次上電復(fù)位初始化,又可能要出洋相了。

從例舉2的程序中還可以看到,翻轉(zhuǎn)標志位“switch_sign”的取反操作也是用同一個遙控器上的“▲”鍵來執(zhí)行的,只是在遙控器的地址編碼上動了點手腳——改變了一下地址編碼(0x5D35),待操作對應(yīng)協(xié)調(diào)后再改回到原來的地址編碼(0x5535)。

2保存1個字節(jié)來復(fù)原自定義標志“位”

自定義標志“位”的保存及其復(fù)原有很多種方法,我曾嘗試過幾種方法。例3是一種保存1個字節(jié)來復(fù)原1個自定義標志位的方法,具體操作如下:

static unsigned char current_dat;//定義一個通用的輔助字節(jié)變量

bit bdata switch_sign;//自定義的翻轉(zhuǎn)標志位(應(yīng)作全局變量定義)

……

switch_sign=~switch_sign;//取反1次翻轉(zhuǎn)標志位

if(switch_sign) {//判斷switch_sign是邏輯“1”還是邏輯“0”

current_dat=0xA5;//對通用的輔助字節(jié)變量賦值

}

else {

current_dat=0x00;//通用的輔助字節(jié)變量

}

save_data();//調(diào)用保存數(shù)據(jù)子程序

BEEP=1;//蜂鳴聲響輸出

以上程序是:取反翻轉(zhuǎn)標志位“switch_sign”后,若“switch_sign”為邏輯“1”狀態(tài),就給通用的輔助字節(jié)變量“current_dat”賦值“0xA5”(當然,這數(shù)據(jù)由你自己隨意定);若“switch_sign”為邏輯“0”狀態(tài),則給通用的輔助字節(jié)變量“current_dat”賦值“0x00”(這數(shù)據(jù)也是自己隨意定的,只要與前面那個不一樣就是了),然后調(diào)用保存數(shù)據(jù)程序?qū)⑼ㄓ玫妮o助字節(jié)變量“current_dat”保存起來。這樣,即使斷電了翻轉(zhuǎn)標志位“switch_sign”的當前狀態(tài)已間接地被通用的輔助字節(jié)變量“current_dat”保存起來了……當下一次上電復(fù)位初始化時,應(yīng)先將保存的輔助變量“current_dat”的數(shù)據(jù)讀出來,并還原成翻轉(zhuǎn)標志位“switch_sign”相應(yīng)的邏輯狀態(tài)。上電初始化時若從存儲處讀出的數(shù)據(jù)是“0xA5”,則將翻轉(zhuǎn)標志位“switch_sign”置“1”;若讀出的數(shù)據(jù)是“0x00”,則將翻轉(zhuǎn)標志位“switch_sign”置“0”——這就與原來保存時的狀態(tài)對應(yīng)起來了。其操作過程如例4:

static unsigned char current_dat;//定義一個通用的輔助字節(jié)變量

static unsigned char addr;//自定義地址變量緩沖單元

static unsigned char Rdat;//自定義讀數(shù)據(jù)緩沖單元

bit bdata switch_sign;//自定義的翻轉(zhuǎn)標志位(應(yīng)作全局變量定義)

……

addr=0x7F6;//給一個原來的存儲地址

REEPROM();//調(diào)用讀取E2PROM的子程序

current_dat=Rdat;//將讀出的數(shù)據(jù)還給通用的輔助字節(jié)變量

if(current_dat==0xA5) {//判斷讀出的數(shù)據(jù)是否等于“0xA5”

switch_sign=1;//將翻轉(zhuǎn)標志位“switch_sign”置“1”

}

else {

switch_sign=0;//將翻轉(zhuǎn)標志位“switch_sign”置“0”

}

31個字節(jié)保存8個自定義“位”

用保存一個自定義的字節(jié)變量來復(fù)原一個自定義標志位的過程上文已敘述了,接下來闡述1個字節(jié)變量保存8個自定義“位”的方案。1個字節(jié)變量保存8個自定義“位”的方案很多,例5是其中比較理想的一種:

#defineuint unsigned int

#defineuchar unsigned char

uintaddr;

ucharWdat,Rdat;

uchar bdatacurrent_dat;//在可位尋址區(qū)定義unsigned char類型的字節(jié)變量current_dat

sbitsign_bit1= current_dat^0;//用關(guān)鍵字sbit 定義位變量來獨立訪問可尋址位對象中的1位

sbitsign_bit2= current_dat^1;//自定義標志位2

sbitsign_bit3= current_dat^2;//自定義標志位3

……

sbitsign_bit8= current_dat^7;//自定義標志位8

……

void Bit_save() {//自定義標志位保存子程序

addr=0x7F6;//給予存儲地址

Wdat= current_dat;//將current_dat賦值給寫E2PROM的緩沖單元Wdat

save_data();//調(diào)用保存子程序存儲current_dat數(shù)據(jù)

}

void Bit_comeback() {//自定義標志位復(fù)原子程序

addr=0x7F6;//給一個原來的存儲地址

REEPROM();//調(diào)用讀取E2PROM的子程序

current_dat=Rdat;

//將讀出的數(shù)據(jù)還給通用的輔助字節(jié)變量

}

以上這段程序所闡述的,也許是有關(guān)自定義位操作及其保存的一種最簡捷的方案了。首先是在可位尋址區(qū)定義ucsigned char類型的通用字節(jié)變量current_dat,再用關(guān)鍵字“sbit”定義位變量來獨立訪問可尋址位對象的其中一位。這樣將自定義標志位提高到類同于特殊功能寄存器(SFR)中可位訪問的方式來操作了——字節(jié)變量current_dat中的8個位各自可以獨立操作,且其保存或讀出復(fù)原都只要直接將字節(jié)變量current_dat進行保存或讀取即可,無須像其他方案那樣需要進行邏輯與、邏輯或等的輔助操作。

結(jié)語

單片機的C語言編程中不一定都要有自定義的標志

位,但是在某些場合運用了自定義的標志位,會使整個程序顯得簡潔而明快。當然,對于自定義標志位的保存也是視其具體情況而定——應(yīng)該說是不得已而為之的。(單片機與嵌入式系統(tǒng)應(yīng)用 作者: 張春峰 )



來源:HWan13140次

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

根據(jù)客戶的定制化需求,納祥科技推出一款多功能旋鈕拓展塢方案,方案以USB Hub控制器為核心,集合了單片機、充電IC、旋鈕交互與4顆快捷鍵,支持9個接口以及SD/TF雙卡槽,確保了多設(shè)備兼容與穩(wěn)定傳輸

關(guān)鍵字: 方案 方案開發(fā) 拓展塢 納祥科技

針對大型博物館電氣設(shè)計的復(fù)雜性問題 ,詳細給出了 電氣設(shè)計方案。首先概述工程總體情況 , 包括博物館的基本結(jié)構(gòu)和電氣需求。在系統(tǒng)設(shè)計方案部分 ,分析供配電系統(tǒng) , 包括對電力負荷的計算和具體設(shè)計方法。對于應(yīng)急照明系統(tǒng) ,...

關(guān)鍵字: 大型博物館 電氣設(shè)計 方案

隨著各大手機品牌推出帶無線充電功能的手機,大家對無線充電技術(shù)已不再陌生。充電時,只需將手機往無線充電器上一放即可,不需要在凌亂的包里翻出充電器。

關(guān)鍵字: 手機 無線充電器 方案

摘要:分布式光伏項目因投資收益率較高,目前正處于快速發(fā)展的階段?,F(xiàn)首先對建設(shè)分布式光伏項目的意義及工程流程進行了說明,然后對施工中遇到的主要技術(shù)問題進行了分析,最后給出了解決方案,可供設(shè)計和工程技術(shù)人員參考。

關(guān)鍵字: 分布式光伏 方案 技術(shù)

摘要:新建廠站的測控支持直接接入智能遠動機的要求,而某些采用非IEC61850通信規(guī)約和非IEC103通信規(guī)約廠站的測控不支持直接接入智能遠動機的要求。過渡階段,可以通過規(guī)約轉(zhuǎn)換器接入智能遠動機,最終將測控改造成支持IE...

關(guān)鍵字: 測控 方案 DNP測控

摘要:在智能制造的時代背景下,智能倉儲越來越受到制藥行業(yè)的重視,當傳統(tǒng)的"高架庫+人工叉車"已無法滿足企業(yè)進一步的要求時,繁多的智能化方案撲面而來,現(xiàn)根據(jù)制藥行業(yè)的特殊性以及智能倉儲的發(fā)展現(xiàn)狀,對目前適用于制藥行業(yè)的智能...

關(guān)鍵字: 智能制造 智能倉儲 方案

編身邊的有不少朋友老家在鄉(xiāng)鎮(zhèn),相比北上廣深,家里那簡直都是土豪式的獨棟住宅,有些也是復(fù)式的商品房。 不過他們都有一個問題,就是wifi信號不好,只有wifi路由放置的那一層樓有信號,其他樓層wifi信號很弱,網(wǎng)速慢,網(wǎng)...

關(guān)鍵字: Wi-Fi 方案

摘 要:傳統(tǒng)倉儲管理存在存儲不集中,作業(yè)流程繁瑣,無法進行批次管理和庫位管理,導(dǎo)致出現(xiàn)倉庫作業(yè)效率低下、員工工作量不均衡、庫存量大等問題。文中通過建立現(xiàn)代化倉儲WMS管理體系,實現(xiàn)了倉儲資源共享,降低了企業(yè)運營成本, 提...

關(guān)鍵字: 倉儲 管理 WMS 規(guī)劃 方案

在工作中,凡是涉及到產(chǎn)品開發(fā)幾乎都會實現(xiàn)參數(shù)存儲功能,一般參數(shù)存儲會采用如下的存儲介質(zhì)進行。

關(guān)鍵字: MCU 參數(shù)存儲 方案
關(guān)閉
關(guān)閉