C51 就是 c 語言 for 51 單片機,這里邊還是有很多不同的,在 c 語言里運算量
相信都知道那叫一個簡單,直接 int, float 就哦了 ,當然這里也可以直接
int, float,但是他們還是有不同的,這里就介紹一下運算量中的不同! , 相同的我就直接跳過~(果斷不說了,不同的對于以后 c 語言開發 51 單片機還是
相當有用的,慢慢的就會體會到了~~~~~ ,尤其是特殊功能寄存器變量、位 變量、還有絕對地址的訪問!
C51 的運算量(只說重點~):
C51 中的運算量主要是常量和變量。
1、常量
常量是指在程序執行過程中不能改變的量。在 C51 中支持整型常量、浮點型常量、 字符型常量和字符串型常量。
1)整型常量
2)浮點型常量
3)字符型常量
4)字符串型常量
2、變量 變量就是在程序運行過程中可以改變的量唄。
一個變量有兩部分組成:變量名和變量值。每個變量都有一個變量名,在存儲器 中占用一定的存儲單元,變量的數據類型不同,占用的存儲單元數就不同。在存 儲單元中存放的內容就是變量值。
1)數據類型說明符
在定義變量時必須通過數據類型說明符來指明變量的數據類型,指明變量在存儲 器中占用的字節數。可以使基本數據類型說明符,也可以是組合數據類型說明符, 還可以是 typedef 或者#define 定義的類型別名(這里一定要注意 typedef 一般用
來定義別名!盡量不要用#define 啊~~我就不解釋了 ,太專業了~~不過用宏 定義就一定要用#define)
例如:
typedef unsigned char uchar; //這個是有;的
typedef unsigned int uint;
或者:
#define uchar unsigned char //這個就沒有; 而且它們兩個定義相反
#define uint unsigned int
2)變量名 變量名有兩種:普通變量和指針變量。他們的區別是指針變量名前面帶“*”號。
3)存儲種類
存儲種類是指變量在程序執行過程中的作用范圍。C51 變量的存儲種類有 4 種, 分別是:自動(auto)、外部(extern)、靜態(static)和存儲器(register)。
a、auto
當定義它的函數體或者復合語句執行時,C51 才為該變量分配內存空間,結束時 占用的內存空間釋放。自動變量一般分配在內存的堆棧空間中。定義變量時,如 果缺省存儲種類,則默認為此。
b、extern
被定以后分配固定的內存空間,在程序整個執行時間內都有效,知道程序結束時 才釋放。
c、static
使用 static 定義的變量成為外部變量,可分為內部靜態變量和外部靜態變量。在 函數體內部定義的靜態變量為內部靜態變量,它在對應的函數體內有效,一直存 在,但在函數體外不可見。這樣不僅使變量在定義它的函數體外可以被保護,還 可以實現當離開函數體時值不被改變。外部靜態變量是在函數體外定義的靜態變 量,它在程序中一直存在,但在定義的范圍之外是不可見的。如在多文件或者多
模塊處理中(這點很重要,以后會用到很多,尤其是多模塊,寫大程序必須具備 的),外部靜態變量只在文件內部或者模塊內部有效。
d、register
它定義的變量存放在 CPU 內部的寄存器中,處理速度快,但是數目有限。
4)存儲器類型 存儲器類型用來指明變量所處的單片機的存儲區域情況。類型如下: data:直接尋址的片內 RAM 低 128B,訪問速度快
bdata:片內 RAM 的可位尋址區(20H~2FH),允許字節和位混合訪問
idata:間接尋址訪問的片內 RAM,允許訪問全部片內 RAM
pdata:用 Ri 簡潔訪問的片外 RAM 低 256B
xdata:用 DPTR 間接訪問的片外 RAM,允許訪問全部 64KB 片外 RAM
code:程序存儲器 ROM64KB
注意:定義變量時可以省略“存儲類型”,省略時 C51 編譯器將按存儲模式默認存 儲器類型。具體的存儲情況啊~~一會你就知道了,繼續往下看~~哈
例如:
char data var1; //在片內 RAM 低 128B 定義用直接尋址方式訪問的自足型變量
var1
unsigned char bdata var2; //在片內 RAM 位尋址區(20H~2FH)單元定義可字 節處理和位處理的無符號字符型變量 var2
5)特殊功能寄存器變量
在 51 單片機中有很多特殊功能寄存器(不過這些有些東西還是不需要我們來關 心的~~~因為在調用#include"reg52.h"的時候里面都給你整好了 ),通過這些
特殊功能寄存器可以控制 51 單片機的定時器、計數器、串口、I/0 及其他功能部 件(這里很重要的~~~~~~),沒一個特殊功能寄存器再片內 RAM 中都對應一個 字節單元或者兩個字節單元。
在 C51 中,允許用戶對這些特殊功能寄存器進行訪問,但是訪問時需要通過 sfr 或者 sfr16 類型說明符進行定義,定義是需要指明他們所對應的片內 RAM 單元的 地址。(你過關不用擔心,直接調用#include"reg52.h"就哦了~)
例如:
sfr PSW=0xd0; sfr SCON=0x98; sfr16 DPTR=0x82;
6)位變量
在 C51 中,允許用戶通過位類型符定義位變量。 位類型符有兩個:bit 和 sbit。可以定義兩種位變量。 a、bit 型位變量
在格式中可以加上各種修飾,但是要注意存儲器類型只能是 bdata、data、idata, 只能是片內 RAM 的可位尋址區,嚴格來說只能是 bdata。
例如:
bit bdata a1;
b、sbit 型位變量
sbit 位類型符用于定義在可位尋址字節或者特殊功能寄存器中的位,定義時需要 指明其位地址,可以使位直接地址,可以是可位尋址變量帶位號,也可以是特殊 功能寄存器名帶位號。
例如(這些東西都在#include"reg52.h"中):
sbit OV=0xd2;
sbit CY=0xd7;
unsigned char bdata flag;
sbit flag_0=flag^0; //字節地址與位號之間、特殊功能寄存器與位號之間一般用
“^”作間隔
sfr P1=x090;
sbit P1_1=P1^1;
3、存儲模式(個人感覺真的用不到這些東東了,因為你丫的要是嫌小可以換個 大的,而且還相當的便宜~~~~ ,我以前試過擴展一個 RAM 和 ROM,擦
不成啊~~)
C51 編譯器支持 3 種存儲模式:SMALL 模式、COMPACT 模式和 LARGE 模式。不 同的存儲模式對變量默認的存儲器類型不一樣。
1)SMALL 模式
SMALL 模式成為小編譯模式,在 SMALL 模式下,編譯時函數參數以及變量被默 認在片內 RAM 中,存儲類型為 data。
2)COMPACT 模式
COMPACT 模式稱為緊湊編譯模式,在 COMPACT 模式下,編譯時函數參數和變量 被默認在片外 RAM 的低 256B 空間,存儲類型為 pdata。
3)LARGE 模式
LARGE 模式稱為大編譯模式,在 LARGE 模式下,編譯時函數參數和變量被默認在 片外 RAM 的 64KB 空間了,存儲器類型為 xdata。
例如:
#pragma small //變量的存儲模式為 SMALL
char k1; //存儲類型為 data
int xdata m1; //存儲類型 xdata
#pragma compact //變量的存儲模式為 COMPACT
char k2;
int xdata m2;
int func1(int x1,int y1) large //函數的存儲模式為 LARGE
{
return(x1+y1);
}
int func2(int x2,int y2) //編譯的存儲模式隱含為 SMALL,沒有指明模式,隱含
SMALL
{
return(x2-y2);
}
4、絕對地址的訪問(這里才是重點中的重點啊~~~)
在 C51 中,可以通過變量的形勢訪問 51 單片機的存儲器,也可以通過絕對地址 來訪問存儲器。三種方法:
1)使用 C51 運行庫中預定義宏(就是調用#include"absacc.h")
C51 編譯器提供了一組宏定義來對 51 單片機的 code、data、pdata 和 xdata 空間 進行絕對尋址!
規定只能以無符號數方式訪問,定義了 8 個宏定義,其函數原型如下:
#define CBYTE((unsigned char volatile*)0x50000L) //CBYTE 以字節形勢對 code 區 尋址
#define DBYTE((unsigned char volatile*)0x40000L) //data 區
#define PBYTE((unsigned char volatile*)0x30000L) //pdata 區
#define XBYTE((unsigned char volatile*)0x20000L) //xdata 區
#define CWORD(unsigned int volatile*)0x50000L) //以字形式對 code 區尋址
#define DWORD(unsigned int volatile*)0x40000L)
#define PWORD(unsigned int volatile*)0x30000L)
#define XWORD(unsigned int volstile*)0x20000L)
例如:
#include"absacc.h"
#include"reg52.h"
typedef unsigned char uchar; typedef unsigned int uint; void main()
{
uchar var1;
uint var2;
var1=XBYTE[0x0005]; //XBYTE[0x0005]訪問片外 RAM 的 0005 字節單元
var2=XWORD[0x0002]; //XWORD[0x0002]訪問片外 RAM 的 0002 字單元
.
.
. while(1);
}
2)通過指針訪問
采用指針的訪問的方法,可以在 C51 程序中對任意指定的存儲器單元進行訪問。
typedef unsigned char uchar; typedef unsigned int uint; void func()
{
uchar data var1;
uchar pdata *dp1; //定義一個指向 pdata 區的指針 dp1
uint xdata *dp2; //定義一個指向 xdata 區的指針 dp2,為 uint 型
uchar data *dp3; //定義一個指向 data 區的指針 dp3,為 char 型
dp1=0x30; //dp1 指針賦值,指向 pdata 區的 30H 單元
dp2=0x1000; //dp2 指針賦值(uint 型),指向 xdata 區的 1000H 單元
*dp1=0xff; //將數據 0xff 送到片外 RAM30H 單元
*dp2=0x1234; //將數據 0x1234(由于是 uint 型,你懂得~~~),送到片 外 RAM1000H 單元
dp3=&var1; //dp3 指針指向 data 區的 var1 變量
*dp3=0x20; //給變量 var1 賦值 0x20
}
3)使用 C51 擴展關鍵字 _at_ (這個用的最多了~~~ ) 總算完了,我真的要累死了~~~~擦擦擦擦啊
一般格式:
[存儲類型] 數據類型說明 變量名 _at_ 地址常量;
其中,存儲類型為 data、bdata、idata、pdata、xdata 等 C51 能識別的數據類型, 如果省略,則會按照存儲模式規定的默認存儲類型確定變量的存儲區域( 這
里又用到上邊的了);數據類型為 C51 支持的數據類型;地址常數用于指定變量 的絕對地址,必須位于有效的存儲器空間之內;使用_at_定義的變量必須為全局 變量。
例如:
typedef unsigned char uchar;
typedef unsigned int uint;
data uchar x1 _at_ 0x40; //在 data 區中定義字節變量 x1,地址為 0x40H,這里 是 uchar
xdata uint x2 _at_ 0x2000; //在 xdata 區中定義字變量 x2,它的地址為 0x2000H, 這里是 uint
我感覺我真的不想再寫了,累死了~~~擦
不過完工了,爽啊~~解脫
完整的pdf格式文檔51黑下載地址:
C51—運算量(重點:特殊功能寄存器變量、位變量.pdf
(118.07 KB, 下載次數: 19)
2018-10-13 08:25 上傳
點擊文件名下載附件
51單片機 下載積分: 黑幣 -5
|