第一篇:單片機C語言知識點大全
【C語言】 【數據類型】
【轉義字符】 【語句】 【#define】 #define 新名 原名 【typedef】
typedef 原類型名 新類型名;【sbit】 sbit P1_0=P1^0;在reg52.h或reg51.h的頭文件下,要使用P0.0~7….一定要事先位定義。【if】
(1)if(表達式)語句; 表達式的值為真,則執行其后的語句,否則不執行該語句,繼續執行
這條語句的下一條。(2)if(表達式)語句1; else 語句2;
表達式的值為真,則執行語句 1,否則執行語句2。(3)if(表達式1)語句1; else if(表達式2)語句2; else if(表達式3)語句3; …
else if(表達式m)語句m; else 語句n;
依次判斷表達式的值,只要出現某個表達式的值為真時,則執行其對應的語
句。然后跳到整個if 語句之外繼續執行程序。【switch】(1)switch(表達式){ case常量表達式1: 語句1;case常量表達式2: 語句2;------------------------case常量表達式n: 語句n;default : 語句n+1;} 計算表達式的值。并逐個與其后的常量表達式值相比較,當表達式的值與
某個常量表達式的值相等時,即執行其后的語句,然后不再進行判斷,繼續執行后面所有 case 后的語句。(2)
switch(表達式){ case 常量表達式1:語句1;Break;case 常量表達式2:語句2;Break;case 常量表達式3:語句3;Break;------------------------case 常量表達式n:語句n;Break;default : 語句n+1;} 計算表達式的值。并逐個與其后的常量表達式值相比較,當表達式的值與
某個常量表達式的值相等時,即執行其后的語句。【goto】 goto 語句標號;
goto 語句標號; 其中語句標號是按標識符規定書寫的符號,放在某一語句行的前面,標號后加冒號(:)。語句標號起標識語句的作用,與goto 語句配合使用。【while】(1)
while(表達式)語句;
只要這個表達式所表描述的事情成立或該表達式經過計算后的值是非0 值,就一直循環執行其后
面的語句;當表達式所描述的事情不成立或經過計算后表達式的值為0 時,就不再執行其后 面的語句,并跳出while 循環。(2)do 語句; while(表達式);
先執行循環中的語句,然后再判斷表達式是
否為真,如果為真則繼續循環;如果為假,則終止循環。【for】
for(循環變量賦初值;循環條件;循環變量增量)語句 1)先求解表達式1。
2)求解表達式2,若其值為真(非0),則執行語句,然后執行下面第3)步;若其值為
假(0),則結束循環,轉到第5)步。3)求解表達式3。4)轉回上面第2)步繼續執行。
5)循環結束,執行for語句下面的一個語句。【數組】(一維數組)
類型說明符數 組名
[常量]; unsigned char a[10];(二維數組)
類型說明符 數組名 [常量] [常量]; unsigned char b[3][3];int display[2][3]={{1},{3}};
*unsigned char code table[] 定義在code區,為常量
第二篇:單片機C語言學習心得
8、指針的使用
8.1 在定義的時候,*ap中的‘*’是指針類型說明符;
在進行指針預算時,x = *ap 中的‘*’是指針運算符。8.2 如果在已定義好的指針變量,并引用,即
int *ap, int a;ap = &a;則在進行指針運算的時候:
(1)*ap與a是等價的,即 *ap就是a;
(2)&*ap:由于*ap與a等價,則&*ap與&a等價(地址);
(3)*&a:由于&a = ap,則*&a與*ap等價,即*&a與a等價(變量);(4)*ap++相當于a++。
8.3 指向數組的指針變量的定義,應用,賦值:
int a[10];int *app;則有兩種方法:app = &a[0];或 app = &a;(1)app+I 或a+i就是數組元素a[i]的地址;(2)*(app+i)或 *(a+i)就是元素a[i]中的內容;
(3)指針變量也可以帶下表,即app[i]與*(app+i)等價。8.4 數組和指針可以互換,但在代碼執行的效率上卻大不相同。用數組找元素必須每次計算元素的地址,效率不高;而用指針則直接指向某個元素,不必每次計算地址,可以大大的提高運算效率。8.5 關于指針的運算:
(1)p++(或p+=1):使指針p指向下一個數組元素,地址加1;
(2)*p++:先得到p指向的變量值,再執行p加1,指向下一個數組元素;(3)*++p:先使p加1,指向下一個數組元素,再去p指向的變量值;(4)(*p)++:表示p指向的變量值加1;
(5)若p指向當前數組中的第i個元素,則:
(p--)與a[i--] 等價:先執行*p,然后p自減;(++p)與a[++i] 等價:先執行p自加,再執行*p;(--p)與a[--p] 等價:先執行p自減,再執行*p。
8.6 指向多維數組:
定義一個二維數組:a[3][4];定義一個指針變量:(*p)[4];(注意:列數相同(第二維相同))使指針變量指向數組:p = a;此時: p與a等價:指向數組a[3][4]的第0行首地址;
p+1與a+1等價:指向數組a[3][4]的第1行首地址; p+2與a+2等價:指向數組a[3][4]的第2行首地址;
而:
*(p+1)+3與& a[1][3]等價,指向a[1][3]的地址;
*(*(p+1)+3)與a[1][3]等價,表示a[1][3]的值; 一般的:對于數組a[i][j]來講,有
*(p+i)+j相當于&a[i][j],表示第i行第j列元素的地址; *(*(p+i)+j)相當于a[i][j],表示第i行第j列元素的值。
8.7 指向結構體:
如果指針p指向結構體數組msg1[0]的首地址,則:
(1)(*p).flg與p->flg和msg1[0].flg三者完全等價,即(*p).成員名 與p->成員名 以及 結構體數組元素成員名三種形式是等價的;
(2)p+1:使指針指向結構數組msg1[0]的下一個元素msg1[1]的首地址;(3)由于指向運算符->的優先級高于自加運算符++,則:
(++p)->flg:先使p自加1指向msg1[1]的地址,再指向msg1[1]的flg成員值;(p++)->flg:先得到msg1[0].flg的值,再使p自加1指向msg1[1]的首地址;
p->flg++:先得到msg1[0].flg的值,使用完后再使msg1[0].flg的值加1; ++p->flg:先將msg1[0].flg的值加1,再使用。
第三篇:單片機C語言學習心得
8、指針的使用
8.1 在定義的時候,*ap中的‘*’是指針類型說明符;
在進行指針預算時,x = *ap 中的‘*’是指針運算符。
8.2 如果在已定義好的指針變量,并引用,即
int *ap, int a;
ap = &a;
則在進行指針運算的時候:
(1)*ap與a是等價的,即 *ap就是a;
(2)&*ap:由于*ap與a等價,則&*ap與&a等價(地址);
(3)*&a:由于&a = ap,則*&a與*ap等價,即*&a與a等價(變量);
(4)*ap++相當于a++。
8.3 指向數組的指針變量的定義,應用,賦值:
int a[10];int *app;
則有兩種方法:app = &a[0];或 app = &a;
(1)app+I 或a+i就是數組元素a[i]的地址;
(2)*(app+i)或 *(a+i)就是元素a[i]中的內容;
(3)指針變量也可以帶下表,即app[i]與*(app+i)等價。
8.4 數組和指針可以互換,但在代碼執行的效率上卻大不相同。用數組找元素必須每次計算
元素的地址,效率不高;而用指針則直接指向某個元素,不必每次計算地址,可以大大的提高運算效率。
8.5 關于指針的運算:
(1)p++(或p+=1):使指針p指向下一個數組元素,地址加1;
(2)*p++:先得到p指向的變量值,再執行p加1,指向下一個數組元素;
(3)*++p:先使p加1,指向下一個數組元素,再去p指向的變量值;
(4)(*p)++:表示p指向的變量值加1;
(5)若p指向當前數組中的第i個元素,則:
(p--)與a[i--] 等價:先執行*p,然后p自減;
(++p)與a[++i] 等價:先執行p自加,再執行*p;
(--p)與a[--p] 等價:先執行p自減,再執行*p。
8.6 指向多維數組:
定義一個二維數組:a[3][4];定義一個指針變量:(*p)[4];(注意:列數相同(第二維相同))
使指針變量指向數組:p = a;
此時: p與a等價:指向數組a[3][4]的第0行首地址;
p+1與a+1等價:指向數組a[3][4]的第1行首地址;
p+2與a+2等價:指向數組a[3][4]的第2行首地址;
而:*(p+1)+3與& a[1][3]等價,指向a[1][3]的地址;*(*(p+1)+3)與a[1][3]等價,表示a[1][3]的值; 一般的:對于數組a[i][j]來講,有*(p+i)+j相當于&a[i][j],表示第i行第j列元素的地址; *(*(p+i)+j)相當于a[i][j],表示第i行第j列元素的值。
8.7 指向結構體:
如果指針p指向結構體數組msg1[0]的首地址,則:
(1)(*p).flg與p->flg和msg1[0].flg三者完全等價,即(*p).成員名 與p->成員名 以及 結
構體數組元素成員名三種形式是等價的;
(2)p+1:使指針指向結構數組msg1[0]的下一個元素msg1[1]的首地址;
(3)由于指向運算符->的優先級高于自加運算符++,則:
(++p)->flg:先使p自加1指向msg1[1]的地址,再指向msg1[1]的flg成員值;(p++)->flg:先得到msg1[0].flg的值,再使p自加1指向msg1[1]的首地址; p->flg++:先得到msg1[0].flg的值,使用完后再使msg1[0].flg的值加1; ++p->flg:先將msg1[0].flg的值加1,再使用。
第四篇:單片機C語言學習
單片機C語言之一___________________________________________________________________ _____________________ 預處理 一》宏定義:
1、不帶參數:
#define 標識符 常量表達式
/*#define是宏定義命令,宏名(標識符)好習慣用大寫*/ #define NIL 0x80
2、帶參數:/*相當于小函數*/ #define 宏名(參數表)字符串
/*不僅要時行字任串替換還要進行參數的替換,在宏定義時,宏名與帶參數的括弧之間不應該加空格,否則將空格以后的字符串都作為替代字符串的一部分,這可是很容易出錯的*/ 如:#define SQ(a,b)a*b 使用:x=12;y=10;area=SQ(x,y);/*則area=12*10=120*/ 二》文件包含:
#include <文件名>或#include “文件名” /*在C中用雙引用形式更保險,在C51中常用物是尖括弧形式*/ 三》條件編譯:
/*一般源程序中的所有程序行都參加編譯,但有時希望對其中一部分內容只在滿足一定條件下才進行編譯,也就是對一部分內容指定編譯的條件。*/ #if、#elif、#else、#endif、#ifdef、#ifndef /*選擇不同的編譯范圍,產生不同的代碼,提供通用性。*/ /*如對8051在6MHZ與12MHZ下有*/ #ifdef cpu==8051 #define FREQ 6 /*程序段*/ #else #define FREQ 12/*程序段*/ #endif /*這樣下面的原程序不用做任何修改便可以使用于兩種時鐘頻率的單片機系統*/ 四》其他:
1、#error:捕捉不可預料的編譯條件
#if(myv!=0&&myv!=1)/*假定其值必為0或1*/ #error myv must be 1 or 0/*出錯時顯示*/ #endif
2、#pragma:用于在程序中向編譯器傳送各種編譯控制命令 #pragma 編譯命令序列
/*例:想按如下命令編譯ex.c c51 ex.c debug cod large可用:*/
#pragma DB CD LA #pragma disable /*禁止中斷*/
單片機C語言之二_____________________________________________________________________________________ 一》數據類型:
char int long 1:unsinged 0~255 0~65535 0~4294967295 2:signed-128~127-32768~32767-2147483648~2147483647 指針:* 3字節 位標量: sbit 特殊功能寄存器:sfr 16位特殊功能寄存器:sfr16 占2個內存單元,0~65535 可尋址位:sbit利用他可訪問51單片機的內部RAM中的可尋址位或特殊功能寄存器中的可尋址位 sfr P0=0x80;sbit P0_1=P0^1;/*將P0口的口地址定義為80H,將P0.1位定義為P1_1*/ 二》數據存貯類型
表1.C51數據存貯類型
━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━ 數據存貯類型 ┃ 與存貯空間的對應關系
━━━━━━━╋━━━━━━━━━━━━━━━━━━━━━━━━━━ data ┃ 直接尋址片內數據存貯區,訪速度快 bdata ┃ 可位尋址片內數據存貯區,允許位與字節混合訪問 idata ┃ 間接尋址片內數據存貯區,可訪問片內全部RAM地址空間
pdata ┃ 分頁尋址片外數據存貯區(256字節)由MOVX @R0訪問 xdata ┃ 片外數據存貯區(64K),由MOVX @DPTR訪問 code ┃ 代碼存貯區(64K),由MOVC @DPTR訪問
━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━ 變量的存貯類型定義: char data var /*字符變量var被定義為data存貯類型,C51編譯器將把該變量定位在51單片機片內數據區存貯區中*/ bit bdata flag /*位變量flag被定義為bdata存貯類型,C51編譯器將把該變量定位在51單片機片內數據區存貯區(RAM)中的位尋址區:20H--2FH*/
三》typedef:重新定義數據類型
typedef 已有數據類型 新的數據類型 typedef int word;/*將word定義為整型*/ word i,j;/*將i,j定義為整型*/ 四》位運算符:
━━━━┳━━━━━┳━━━━━┳━━━━━━┳━━━━━━┳━━━━━━ ~ ┃ & ┃ | ┃ ^ ┃ << ┃ >> ━━━━╋━━━━━╋━━━━━╋━━━━━━╋━━━━━━╋━━━━━━
按位取反┃ 按位與 ┃ 按位或 ┃ 按位異或 ┃ 左移 ┃ 右移
━━━━┻━━━━━┻━━━━━┻━━━━━━┻━━━━━━┻━━━━━━
對移位:如<< ,a<<2,即為將二進制的a左移兩位,若a=0x8f,即10001111,a=a<<2,將導致a=0x3c(00111100),右邊補零。五》條件運算符:
邏輯表達式? 表達式1:表達式2 六》指針與地址運算符: *取內容 &取地址
七》強制類型轉換:(類型)=表達式(char *)0xb000 八》sizeof 取數據類型、變量以及表達式的字節數的運算符; 九》continue:中斷語句:結束本次循環。
單片機C語言之三_____________________________________________________________________________________ 函數:
一》中斷服務函數與寄存器組定義:
函數類型 函數名(形式參數表)[interrupt n][using n] n為中斷號,0~31:
━━━━┳━━━━━┳━━━━━ 中斷編號┃ 中斷向量┃ 入口地址 ━━━━╋━━━━━╋━━━━━ 0 ┃ 外中斷0 ┃ 0003H ━━━━╋━━━━━╋━━━━━ 1 ┃ 定時器0 ┃ 000BH ━━━━╋━━━━━╋━━━━━ 2 ┃ 外中斷1 ┃ 0013H
━━━━╋━━━━━╋━━━━━ 3 ┃ 定時器1 ┃ 001BH ━━━━╋━━━━━╋━━━━━ 4 ┃ 串行口 ┃ 0023H ━━━━┻━━━━━┻━━━━━
后面的n指的是四個工作寄存器組的一個:0~3 對函數目標代碼影響如下:
在函數入口處將當前工作寄存器組保護到堆棧中;指定的工作寄存器內容不會改變,函數返回前將被保護的工作寄存器組從堆棧中恢復!例(定時1ms):
#include
1、如果中斷函數中用到浮點運算,必須保存浮點寄存器的狀態。(在math.h中保存浮點寄存器函數為pfsave, 恢復浮點寄存器的狀態函數為fprestore)
2、如果在中斷函數中調用了其他函數,則被調函數所使用的工作寄存器組與中斷函數的一致!*/
單片機C語言之四_____________________________________________________________________________________
一、局部變量與全局變量(外部變量):
1、全局變量若不在開頭定義則加extern
2、全局變量會使代碼長,占用內存多
二、存儲方式:
自動變量(auto):缺省,函數調用存在,退出消失。
內部變量 靜態變量(static):static int a=5;始終存在,退出不消失,但不能訪問。寄存器變量(register):速度最快。通常只給編譯器一個建議,由編譯器根 據實際情況確定。(見下)變量 全局變量(global): 外部變量
靜態變量(static): 寄存器變量例: #include
三、函數的參數和局部變量的存儲器模式: 三種存儲器模式:small,compact,large.一個函數的存儲器模式確定了函數的參數和局部變量在內存中的地址空間 small:內部ram compact, large:外部RAM 函數類型 函數名(形式參數表)[存儲器模式] 例:
#pragma large /*默認存儲器模式為large*/ extern int calc(char I,int b)small;/*指定small模式*/ extern int func(int I,float f)large;/*指定large模式*/ int large_te(int I,int k)/*未指定,按默認的large模式處理*/ { return(mtest(I,k)+2);}
利用存儲器混合模式編程,充分利用有限的存儲空間,還可加快程序的執行速度!
單片機C語言之五_____________________________________________________________________________________ 數組 1>初始化數組: unsigned char a[5]={0x11,0x22,0x33,0x44,0x55} 或
unsigned char a[ ] ={0x11,0x22,0x33,0x44,0x55,0x66} 3>數組作為函數的參數:不但可以由變量作為函數的參數外,還可以用數組名作為函數的參數。一個數組數組名表示該數組的首地址。用一個數組名作為函數的參數時,在執行函數調用的過程中參數傳遞方式采用的是地址傳遞。將實際參數數組首地址傳遞給被調函數中的形式參數數組,這樣一來兩個數組就占有同一段內存單元。見下圖:
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9] 起始地址1000 b[0] b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8] b[9] 用數組名作為函數的參數,應該在主調函數和被調函數中分別進行數組定義而不能只在一方定義數組。而且在兩個函數中定義的數組類型必須一致,如果類型不一致將導致編譯出錯。實參數組和型參數組的長度可以一致可以不一致,編譯器對形參數組的長度不做檢查,直只是將實參數組的首地址傳遞給行參數組。如果希望行參數組能得到實參數組的全部元素,則應使兩個數組的長度一致。定義型參數組時可以不指定長度,只在數組名后面跟一個方括號[]。這時為了在被調函數中處理數組元素的需要,應另外設置一個參數來傳遞數組元素的個數。
例:用數組作為函數的參數,計算兩個不同長度的數組中所有元素的平均值 #include float pot_1[2]={99.9,88.8};float pot_2[3]={11,22,33.3};average(pot_1,2);average(pot_1,3);} 單片機C語言之六_____________________________________________________________________________________ 軟件法去干擾: 工程上我們在采集數據時一般要求精度達到5%%,大于這個值將認為無效。我在實際應用中采用8535對32路數據進行采集(8535帶10位AD,帶看門狗),發現數據跳動有時達7%%,這是由于各種干擾造成的。主要來自于隨機干擾,下面就各種干擾的方法給出簡單的去除方法: 1、白噪聲:最重要的統計特性為平均值為0,可采取每路數據采集幾次求平均的方法; 2、隨機干擾:該點明顯高于或低于附近正常采樣值,故采取中值濾波法,即對被測信號連續采樣M次,進行大小排序,取大小居中的1/3個采樣值進行算術平均; 3、電源干擾:特點是有固定周期,故可采用定時采樣求平均的方法。 由于各種排序與求平均算法用C易于實現,故C常常用于采集系統中軟件去干擾。至于排序算法可參考上一篇文章,有一個經典的程序。 在實際中我們采用每路猜9個值,排序,取中間3個,求平均。然后。,每路數據幾乎不動! 單片機C語言之七_____________________________________________________________________________________ 指針:可對內存地址直接操作 基于存貯器的指以貯器類為參量,它在編譯時才被確定。因此為指針選擇存貯器的方法可以省掉,以這些指針的長度可為1個字節(idata *,data *,pdata *)或2個這節(code *,xdata *)。char xdata *address;ADC0809具有8個模擬量輸入通道,采用中斷方式,在中斷函數中讀取8個通道的A/D轉換值,分別存儲在外部RAM的1000H~1007H單元。ADC0809端口地址為00F0H。 程序定義了兩個指針變量* ADC和* ADCdata,分別指向ADC0809端口地址(00F0H)和外部RAM單元地址(1000H~1007H) 由*ADC=I送入通道數,啟動ADC0809進行A/D轉換,轉換結束時產生INT1中斷。在中斷服務函數int1()中通過temp=*ADC和*ADCdata=temp;讀取A/D轉換結果并存到外部RAM中。#include void main(){ ADC=0x00f0;/*定義端口地址和數據緩沖器地址*/ ADCdata=0x1000;I=8;/* ADC0809有8個模擬輸入通道*/ EA=1;EX1=1;IT1=1;/*開中斷*/ *ADC=I;/*啟動ADC0809*/ WHILE(I);/*等待8個通道A/D轉換完*/ } void int1()interrupt 2 { unsigned char tmp;temp=*ADC;/*讀取A/D轉換結果*/ *ADCdata=temp;/*結果值存到數據緩沖區*/ ADCdata++;/*數據緩沖區地址加1*/ i—;*ADC=I;/*啟動下一個模擬輸入通道A/D轉換*/ } 除了用指針變量來實現對內存地址的直接操作外,c51編譯器還提供一組宏,該宏定義文件為:“absacc.h”,利用它可十分方便地實現對任何內存空間的直接操作,改寫上面的程序: #include char *s=”abcdef”;int strlen(char *s);printf(“n length of ‘%%s’=%%dn”,s,strlen(s));} int strlen(char *s){ char *p=s;while(*p!=’
主站蜘蛛池模板:
国产福利视频在线观看|
狼人大香伊蕉国产www亚洲|
男女性高爱潮是免费国产|
色拍自拍亚洲综合图区|
久久久这里只有免费精品|
色噜噜av亚洲色一区二区|
亚洲国产精品高清久久久|
天天澡夜夜澡狠狠久久|
香蕉av福利精品导航|
丝袜无码专区人妻视频|
狠狠综合久久久久综合网址|
精品少妇一区二区三区免费观|
美女网站免费观看视频|
五十路熟妇亲子交尾|
无码国产欧美一区二区三区不卡|
熟女人妻aⅴ一区二区三区60路|
免费无码又黄又爽又刺激|
久久久久久久综合综合狠狠|
国产午夜福利在线观看红一片|
成熟了的熟妇毛茸茸|
亚洲 日韩 欧美 成人 在线观看|
av无码精品一区二区三区四区|
亚洲精品无码久久久久sm|
美女被?到高潮喷出白浆漫画入口|
337p西西人体大胆瓣开下部|
成人国产一区二区三区|
午夜视频体内射.com.com|
国产偷录视频叫床高潮|
乱人伦中文字幕成人网站在线|
亚洲精品夜夜夜|
色欲天天婬色婬香综合网完整版|
亚洲男人av天堂午夜在|
婷婷四房综合激情五月在线|
国产成人精品无缓存在线播放|
久久久噜噜噜久久熟女|
精品无码三级在线观看视频|
精品人妻少妇一区二区|
www.一区二区三区在线 | 欧洲|
伊人情人综合网|
免费无码午夜福利片|
亚洲aⅴ无码专区在线观看春色|