『壹』 C51單片機浮點數運算
因為沒有電路,所以程序我就沒法給你寫,給你個思路.
第一,不知道你的a和b是什麼類型的,如果是定義成浮點型,那麼,可以這樣寫:
float f_Div = a/b;
如果兩個有一個是整形的,那麼,把整型強制轉換成浮點型:
float f_Div = (float)a/(float)b;
注意,那個f_Div變數必須是float型,才能有小數產生
第二,你要進行顯示,肯定要把各個位都取出來,這裡面肯定有一個取模運算,就是"%",
對於浮點型,不運行取模運算的,所以,你必須把浮點型轉換成整型,但是,不能強制轉換,
比如: unsigned int I_Div = (unsigned int)f_Div;這是不可以的,你的小數部分就沒有了.
所以,你必須要放大一定的倍數,根據你的要求,你是要保留三位,那麼,這里還有個問題,你的
小數點之前有幾位,決定了你小數點後面保留幾位.
比如,你得到的結果是 1.2345,那麼,你就保留1.23
如果你得到的結果是 12.345,那麼,就保留12.3
如果你得到的結果是 123.45,你就只能保留123了
如果得到的結果是 0.123,你就只能保留 0.12
所以可以看出,你的浮點型結果整數部分有多少位,決定了你的小數能保留多少位,所以還要進行如下運算:
unsigned int i_Div = unsigned int)f_Div;;
unsigned char Dot_Bit = 0; //---這個變數用來表示在第幾位上顯示小數點,因為
//---通過下面的操作,已經把小數變成整數了
if(I_Div >= 100) //---表示前面有3個整數部分位
{
; //---那就沒什麼可操作的,unsigned int i_Div = unsigned int)f_Div;;就符合要求
}
else if (I_DIV >= 10) //---表示整數部分有2位
{
I_DIV = f_Div *10;
Dot_Bit = 1; //---在右數第2個地方顯示小數點,也就是十位後顯示小數點
}
else
{
I_DIV = f_Div *10;
Dot_Bit = 2; //---在右數第2個地方顯示小數點,也就是最前面那位後面顯示
}
void Display(void)
{
unsigned char Hundred = I_Div/100;
unsigned char TenBit = (I_Div/%00)/10;
unsigned char TenBit = I_Div%10;
....... //然後就開始顯示了
}
『貳』 求51單片機怎麼顯示漢字,能不能給我發個現成的程序
在51單片機上顯示漢字,首先需要考慮的是所使用的液晶顯示屏是否內置了字型檔。如果有字型檔,那麼只需發送相應的兩位元組漢字代碼就能直接顯示漢字。例如,發送"娟字"的編碼即可。但如果沒有內置字型檔,就需要通過漢字取模軟體提取點陣數據。點陣數據的大小會根據取模軟體的設置有所不同,常見的有16X16點陣和32X32點陣兩種,對應的點陣數據大小也不同。
對於16X16點陣的漢字,通常需要32個位元組來存儲一個漢字的點陣信息。而32X32點陣的漢字則需要128個位元組。因此,在發送點陣數據之前,需要先確定液晶屏支持哪種點陣格式。這可以通過查閱液晶屏的數據手冊來實現。
具體步驟如下:首先,使用漢字取模軟體將漢字「娟」提取成16X16點陣數據或32X32點陣數據。然後,將生成的點陣數據通過單片機發送給液晶屏,使其顯示相應的漢字。在發送點陣數據時,需要注意點陣數據的格式和傳輸方式,以確保數據能夠被液晶屏正確解析並顯示。
值得注意的是,不同的取模軟體和液晶屏可能有不同的點陣數據格式,因此在實際操作中需要根據具體情況來調整。此外,如果需要顯示更多漢字,可以使用循環或其他方法,將點陣數據逐一發送給液晶屏。
總之,在51單片機上顯示漢字的關鍵在於是否有內置字型檔或是否能正確提取和發送點陣數據。通過這些步驟,可以實現漢字的顯示。
『叄』 匯編語言常用指令
單片機匯編語言匯編錯誤原因分析
匯編語言的指令格式,目前有兩種不同的標准:Windows下的匯編語言基本上都遵循Intel風格的語法,比如:MASM、NASM;而Unix/Linux下的匯編語言基本上都遵循AT&T風格的語法;
一、匯編語言語句的通用格式
[名稱[:]] 指令碼 [第一操作數][,第二操作數] ;注釋
匯編語言的指令碼的操作數的個數可以是0、1、2個;當操作數的個數為2的時候,語句還有兩種不同的格式:
Windows下Intel風格的匯編語言語句格式為:
[名稱[:]] 指令碼 目的操作數DST,源操作數SRC ;注釋
Unix/Linux下AT&T風格的匯編語言語句格式為:
[名稱[:]] 指令碼 源操作數SRC,目的操作數DST ;注釋
例如: CYCLE: ADD AX,02H ;(AX)匯編語言語句格式中的"名稱"並不是所有語句都必需的,但是,如果語句中帶有"名稱",那麼,大多數情況下,"名稱"都表示的是內存中某一存儲單元的地址,也就是"名稱"後面各項在內存中存放的第一個存儲單元的地址(包括該"名稱"所在段的段地址和段內偏移地址);比如上面的指令中,CYCLE就是該語句的名稱,CYCLE表示的就是其後面的機器指令碼在內存中存放的第一個地址;"名稱"與指令碼之間的分隔符可以是冒號":",也可以是空格字元" ";當以冒號分割時,該名稱代表的是一個標號;當以空格分割時,該名稱代表的可能是標號,也可能是變數;當指令碼有多個操作數的時候,相鄰兩個操作數之間要用逗號","分割;指令碼與操作數之間必須以空格分割;匯編語言語句的注釋必須以分號";"開頭;
二、組成語句的元素
1、常數:
匯編語言中的常數有整數、字元串;二進制、八進制、十進制、十六進制;匯編語言採用不同的後綴區分:
B:二進制數; O:八進制數; D:十進制數; H:十六進制數;
當一個數值後面沒有後綴的時候,默認為十進制數;
字元串常數是用一對單引號('')括起來的一串字元;
2、表達式:
由操作數和操作符組成;
算數運算操作符: +、-、*、/、MOD,等;取模運算MOD是取兩數相除的余數;
邏輯運算操作符: AND(邏輯與)、OR(邏輯或)、NOT(邏輯非)、XOR(邏輯異或);
注意:邏輯運算符同時又可以是邏輯運算指令的指令碼,只有當它們出現在指令的操作數部分時,才是操作符;例如:
ADD AL,0CH ADD 0FH ;第一個ADD是指令碼,第二個ADD是操作符;
關系運算操作符: EQ(相等)、NE(不等)、LT(小於)、GT(大於)、LE(小於等於)、GE(大於等於);
匯編語言中的表達式不能單獨構成語句,只能是語句的組成部分;
注意:語句中表達式的求值不是在語句執行時完成的,而是在對源程序進行匯編鏈接時完成的.所以,語句中各表達式的值必須在匯編或鏈接時就是確定的,也就是說,表達式中各標識符的值在匯編或鏈接時就應該是確定的;
3、標號:
標號是由標識符表示的指令的名稱,用於指示對應指令的位置(地址);
標號具有三個屬性:段地址、偏移地址和類型;
標號的段地址和偏移地址屬性是指該標號所對應的指令所在段的段地址和段內偏移地址;
標號的類型有兩種:NEAR和FAR;標號定義成NEAR類型,表示該標號在段內使用,而定義成FAR類型則表示該標號可以在段間使用;
標號的定義:在指令碼前面加上標識符和冒號":";
例如:START: PUSH DS
這條語句裡面,START就是我們定義的標號,它代表指令PUSH的地址,所以,標號可以作為程序轉移指令的操作數(即:要轉向的地址);標號還可以採用偽指令來定義;例如:用LABEL偽指令和過程定義偽指令來定義;
4、變數:
與高級語言一樣,並不是所有的操作數都是常數,匯編語言也有自己的變數,變數的值在程序運行期間是可以被改變的;
A.定義變數:匯編語言中,變數的定義是通過偽指令來完成的;定義變數的偽指令格式如下:
變數名 DB 表達式 ;定義位元組變數,又稱單位元組變數(1個連續位元組),DB-->BYTE
變數名 DW 表達式 ;定義字變數,又稱雙位元組變數(2個連續位元組),DW-->WORD
變數名 DD 表達式 ;定義雙字變數,又稱四位元組變數(4個連續位元組),DD-->DWORD
變數名 DF 表達式 ;定義六位元組變數,又稱六位元組變數(6個連續位元組),DF-->FWORD
變數名 DQ 表達式 ;定義長字變數,又稱八位元組變數(8個連續位元組),DQ-->QWORD
變數名 DT 表達式 ;定義十位元組變數(10個連續位元組),DT-->TBYTE;
其中,變數名是一個合法的標識符,變數名後面不能加冒號":",只能用空格;變數名不是必要的,可有可無;變數的類型由關鍵字DB、DW、DD、DQ、DT來定義;
變數定義語句中的"表達式"是用於對變數進行初始化的,可有一下幾種情況:
(1).一個或多個常數或表達式;當為多個常數或表達式時,期間要用逗號隔開;如DATA1--DATA4;
(2).帶單引號的字元串;
對於位元組型(DB)變數,每個變數的大小為1個位元組,每個變數的值不能超過1個字元,每個位元組內存入一個字元的ASCII碼值,整個字元串可以在同一對單引號內給出,這相當於是定義了一個字元數組,如DATA5;
對於字類型(DW)變數,每個變數的大小為2個位元組,每個變數的值不能超過2個字元,若為2個字元時,同樣遵循高位存入高位元組,低位存入低位元組的規則;若為1個字元,則該字元的ASCII碼值存入到低位元組,高位元組為00,如DATA6;
對於雙字類型(DD)變數,每個變數的大小為4個位元組,每個變數的值不能超過2個字元,若為2個字元,同樣遵循高位存入高位元組,低位存入低位元組的規則;但是2個字元的值被存入到雙字變數的最低2個位元組中,1個字元的值被存入到雙字變數的最低1個位元組中;
對於長字類型(DQ)變數,每個變數的大小為8個位元組,每個變數的值不能超過2個字元,若為2個字元,同樣遵循高位存入高位元組,低位存入低位元組的規則;但是2個字元的值被存入到長字變數的最低2個位元組中,1個字元的值被存入到長字變數的最低1個位元組中;
(3).一個問號"?",表示該變數的值不確定,即:該變數所表示的內存單元中的內容是不確定的,或者說是,當表達式為問號時,變數所對應的內存區中並沒有存入新的值,而只是預留出了相應的存儲空間;如DATA7、DATA8
(4).重復方式;此時的格式為: 重復次數 DUP(表達式);重復方式指出表達式的值可以重復地存儲到變數對應的內存區中,重復的次數由偽指令給出,相當於定義數組;如DATA9、DATA10
定義變數的例子:
DATA1 DB 20H ;1位元組變數
DATA2 DW 0204H,1000H ;2位元組變數
DATA3 DB (-1*3),(15/3) ;1位元組變數
DATA4 DD 123456H ;4位元組變數
DATA5 DB '0123' ;字元串變數,相當於一個字元數組
DATA6 DW 'AB','C','D' ;字元串變數,相當於一個字元串數組;
DATA7 DB ? ;1位元組變數,未初始化
DATA8 DD ? ;4位元組變數,未初始化
DATA9 DB 5 DUP(0) ;1位元組變數,用5個0初始化,相當於是一個具有5個DB型元素的數組
DATA10 DW 3 DUP(?) ;2位元組變數,未初始化,相當於是一個具有3個DW型元素的數組
變數定義語句中偽指令的功能是在變數名所對應的地址開始的內存區依次存入表達式中的各項值,表達式中的每項值所佔用內存位元組數與變數的類型對應;
總結:一個變數的變數名實際上就代表了該變數所對應的內存區在內存段中的有效地址(偏移地址);高地址是指地址值相對較大,低地址是指地址值相對較小,高地址與低地址是相對而言的;
5、變數的屬性:
(1).屬性介紹
一個變數具有一下屬性:
A.段地址(SEG):變數所在段的段地址;
B.偏移地址(OFFSET):變數所在段內的偏移地址;
C.類型(TYPE):變數的類型定義了每個變數所佔用的內存位元組數,對於DB、DW、DD、DQ、DT類型定義的變數所佔用的內存位元組數分別是1、2、4、8、10;通常又將DB、DW、DD類型所定義的變數分別成為BYTE類型、WORD類型、DWORD類型變數;
常用標識符的類型值列表:
標識符種類 位元組變數 字變數 雙字變數 近標號NEAR 遠標號FAR
TYPE的值 1 2 4 -1 -2
D.長度(LENGTH):變數定義時,一個變數名所定義的變數個數;在含有DUP操作符的變數定義中,變數名所定義的變數個數為定義格式中的重復次數;在其它各種變數定義中,每個變數名所定義的變數個數均為1個;
E.大小(SIZE):變數定義語句中,分配給同一個變數名的所有變數的總的位元組數,其值為該變數的類型與長度的成績;
其中,段地址、偏移地址和類型屬性是變數的主屬性,而長度和大小屬性是變數的輔助屬性;
(2).屬性操作符:
操作符 表達式 含義
SEG SEG 變數名或標號 取出變數名或標號所在段的段地址
OFFSET OFFSET 變數名或標號 取出變數名或標號所在段內的偏移地址
TYPE TYPE 變數名或標號 取出變數名或標號的類型(變數所佔用的位元組數)
LENGTH LENGTH 變數名 取出變數的長度
SIZE SIZE 變數名 取出變數的大小
這些操作符不能單獨構成語句,只能作為表達式的組成部分,並且表達式的求值也是在匯編過程中完成的;
6.強制類型轉換操作符PTR
格式:數據類型 PTR 地址表達式
格式中的"數據類型"可以是BYTE、WORD、DWORD、NEAR、FAR;前三種類型是變數的類型,後兩種類型是標號的類型;格式中的表達式可以是變數、標號、其它地址表達式;
PTR操作符的功能是用來重新定義已定義的變數或標號的類型,其作用域只在當前語句中; 例如:
DATA1 DW 02H
MOV BYTE PTR DATA1,AL
這條指令中,是把DATA1的類型轉換為BYTE類型,然後把AL中的內容存放到DATA1的最低一個位元組中;作用域只在這條MOV語句中,過了這條語句,DATA1仍然是DW類型,即:DATA1原來的類型並沒有被修改;