51單片機C語言程序100例分析(1)IO+C語言+頭文件
\\\插播一條:文章末尾有驚喜喲~///
P1=0xfe;//P1=11111110B,即P1.0輸出低電平}
分析:通過這短短的幾行代碼就能夠讓51單片機的P1.0引腳輸出低電平,首先#include<>>這句代碼是包含51單片機寄存器定義的頭文件,51單片機是寄存器和IO統一編址的,所以你往相應的寄存器中寫1就會在對應引腳輸出高電平,寫0就會輸出低電平,我們知道51共32個引腳作為IO端使用,所以只須要四個寄存器(一個寄存器是8位,這取決於數據總線),翻開頭文件就會發現P0和0X80這個地址綁定了,所以編程的實質就是往內存中寫值,又由於單片機是數字器件,所以只能讀懂二進位,為什麼是二進位?由於0對應低電平0V,1對應高電平5V足夠了,沒有第三種明確的狀態。注意加粗的地方,要細品。單片機是控制器件而不是驅動器件,由於輸出電流很小,不足以驅動某些須要大電流的外設。
//實例2:用單片機控制一個燈閃爍:認識單片機的工作頻次
#include //包含單片機寄存器的頭文件
/****************************************
函數功能:延時一段時長
*****************************************/
void delay(void) //兩個void意思分別為沒需返回值,沒有參數傳遞
{
unsigned int i; //定義沒符號整數,最大取值范圍65535
for(i=0;i/做20000次空循環
; //什麼也不做,等待一個機器周期
}
/*******************************************************
函數功能:主函數(C語言規定必需有也只能有1個主函數)
********************************************************/
void main(void)
{
while(1) //沒限循環
{
P1=0xfe; //P1=11111110B,P1.0輸出低電平
delay(); //延時一段時長
P1=0xff; //P1=11111111B,P1.0輸出高電平
delay(); //延時一段時長
}
}
分析:寫程序是自下而上的過程,而讀程序是自上而下的過程,所以編寫程序和讀程序的流程是不同的。從零初始編寫程序一般要先構思,再走一步看一步,當然我更喜愛修改代碼以完成目標,所以提前準備典型實例能夠大大提高編程效率。對於讀代碼是很常見的,準備典型案例的時候就要讀懂,畢竟讀懂是修改的前提,事實證明有些代碼讀著都費力,自己是萬萬寫不出來的,所以在不適宜的時長選擇發揮主觀能動性就是愚昧的表現,你花你個月的時長未必能到達寫代碼的那個人的水平,但我看懂加修改用不了多久,剩下的時長我又分析的大量的案例,51的功能也進一步把握,這難道不香嗎?也不說不提倡創造,而是不提倡閉門造車,創造力應該用在人類沒有突破的地方,獨有更多的人到達那個階段才更有希望。每個人的人生經歷都不一樣,所以每個人都是一種可能,別人做不到不代表你做不到,他可能就是少了一點必要的經歷,但只有可能多了,總有一個人會成功推進。
讀程序能夠直接看主函數,看到未定義的函數和變量再往外找,事實上編程也能夠這樣,先做方案再找人。這個代碼沒什麼好說的,還是在圍繞著引腳玩。在我的上一篇文章中,我說編程就像做菜一樣,沒看過的能夠先去看一下,這裡的頭文件就是菜庫,4個IO埠只占了其中的4個菜種。
//實例3:將P1口狀態分別送入P0、P2、P3口:認識I/O口的引腳功能
#include//包含單片機寄存器的頭文件
/*******************************************************
函數功能:主函數(C語言規定必需有也只能有1個主函數)
********************************************************/
void main(void)
{
while(1) //沒限循環
{
P1=0xff; //P1=11111111B,熄滅LED
P0=P1; // 將P1口狀態送入P0口
P2=P1; // 將P1口狀態送入P2口
P3=P1; // 將P1口狀態送入P3口
}
}
分析:內存的值只有沒有代碼去變更就會保持。這裡關於埠的四個菜都上齊了,IO埠當然能夠輸寫也能夠輸出。
//實例4:使用P3口流水點亮8位LED
#include //包含單片機寄存器的頭文件
/****************************************
函數功能:延時一段時長
*****************************************/
void delay(void)
{
unsigned char i,j;
for(i=0;i
for(j=0;j
;
}
/*******************************************************
函數功能:主函數
********************************************************/
void main(void)
{
while(1)
{
P3=0xfe;//第一個燈亮
delay();//調用延時函數
P3=0xfd;//第二個燈亮
delay();//調用延時函數
P3=0xfb;//第三個燈亮
delay();//調用延時函數
P3=0xf7;//第四個燈亮
delay();//調用延時函數
P3=0xef;//第五個燈亮
delay();//調用延時函數
P3=0xdf;//第六個燈亮
delay();//調用延時函數
P3=0xbf;//第七個燈亮
delay();//調用延時函數
P3=0x7f;//第八個燈亮
delay();//調用延時函數
}
}
分析:注意二進位和16進位的轉換就好啦,另外這裡的例子都沒有波及到位操作,不要著急,下面會有的。
//實例5:通過對P3口地址的操作流水點亮8位LED
#include //包含單片機寄存器的頭文件
sfr x=0xb0; //P3口在存儲器中的地址是b0H,通過sfr可定義8051內核單片機
//的所有內部8位特殊功能寄存器,對地址x的操作也就是對P1口的操作
/****************************************
函數功能:延時一段時長
*****************************************/
void delay(void)
{
unsigned char i,j;
for(i=0;i
for(j=0;j
; //利用循環等待若干機器周期,從而延時一段時長
}
/*****************************************
函數功能:主函數
******************************************/
void main(void)
{
while(1)
{
x=0xfe; //第一個燈亮
delay(); //調用延時函數
x=0xfd; //第二個燈亮
delay(); //調用延時函數
x=0xfb; //第三個燈亮
delay(); //調用延時函數
x=0xf7; //第四個燈亮
delay(); //調用延時函數
x=0xef; //第五個燈亮
delay(); //調用延時函數
x=0xdf; //第六個燈亮
delay(); //調用延時函數
x=0xbf; //第七個燈亮
delay(); //調用延時函數
x=0x7f; //第八個燈亮
delay(); //調用延時函數
}
}
分析:sfr還能夠在頭文件之外使用哦,雖然意義不大,但是你又學到了一個操作不是嗎?這裡能夠不用包含頭文件。
//實例6:用不同數據類型控制燈閃爍時長
如何使用 KEIL下載 HEX文件?
熟悉 KEIL的人都知道,KEIL下載時使用 axf格式的文件,裡面不僅有代碼指令信息,也包含了調試信息,假如C代碼和彙編代碼之間的對應關係(這些信息不會下載到單片機中,不然單片機可能裝不下,哈哈),地址信息等。
事實上,KEIL也能下載 HEX文件,同時也能保存數據為HEX文件。
很多道友可能會問,既然有 axf文件,為啥還要學 HEX文件下載呢?我們知道,公司為了保密或者其他一些理由,不會給你原始碼編譯後再下載,還有一種可能是單片機有兩份程序,BOOT_LOADER程序可能是別人編寫與維護的,只給你 HEX文件,假如說你掌握了 KEIL下載方式,那麼就不須要找其他工具下載了,方便快速(還有一種情況,代碼使用 GCC編譯,文件格式為 elf)。
所以,掌握 KEIL下載 HEX文件的方法還是很重要的。
那麼今天魚鷹就教你如何使用 KEIL下載 HEX文件到單片機中。
首先,複製一個 STM32工程模板(假如沒有,去魚鷹的公眾號後台回復關鍵字獲取)。
翻動工程,看看有沒有勾選 HEX文件生成功能:
勾選這個只是為了讓工程生成一個 HEX文件,方便我們做測試,在實際 HEX文件下載過程中,不須要勾選這個。
最後生成的文件的文件名你會發現和axf文件名是一致的,只是後綴不同,變成了 hex:
所以你在工程目錄下能夠搜到 rtthread-stm32.hex文件,為了接下來更好的進行說明,魚鷹將這個文件名修改為 rtthread.hex,這樣就不會認為我們接下來下載的是 axf文件了。
下載 HEX文件最關鍵的兩點來了:
最後選擇適宜的調試器,配置好下載 axf文件時的相關參數(即能用調試器正常下載 axf文件即可)。
最後點擊下載按鈕即可完成下載。
是不是很簡略?
假如說經常須要下載hex文件,每次要新建一個工程、翻動工程、然後再修改參數,還是挺麻煩的,為了方便起見,我們能夠為常用工程添加一個下載的宗旨,即多宗旨工程,類似這種:
這樣一來,只有事先設置好,切換宗旨後,即可快捷完成下載,方便快速。
什麼,你還不知道怎麼設置多宗旨工程?看這裡:
《STM32工程模板建設之Simu宗旨》
《STM32工程模板建設之RAM宗旨》
好了,魚鷹再說說怎麼保存 FLASH或者 RAM數據的問題。
有些時候,FLASH或 RAM保存了很多參數或者代碼,假如通過串口助手之類的工具列印出來再保存不免有些麻煩,事實上 KEIL有命令能夠幫助你快捷將一塊數據保存為 HEX文件,假如魚鷹想保存從地址 0x0800 0000初始,大小為 0xC00的數據,那麼只有在 KEIL命令行輸寫以下命令即可完成保存,方便快速,你值得擁有:
當然,你也能夠在該命令後增加以下參數(後面加一個逗號再跟這個參數)以實現不同的訪問方式,是不是很貼心啊。
假如命令執行正確的話(上圖表示命令已執行正確,假如不正確會報錯的),你應該就能在工程目錄下找到你所需的 data.hex文件了,然後用 HEX文件查看工具即可輕鬆查看,再也不須要串口列印啦!
彩蛋:最近有同學跟我要單片機的資料,我特意花幾個月時間,總結了我10年產品研發經驗,資料包幾乎覆蓋了C語言、單片機、模電數電、原理圖和PCB設計、單片機高級編程等等,非常適合初學者入門和進階。除此以外,再含淚分享我壓箱底的22個熱門開源項目,包含源碼+原理圖+PCB+說明文檔,不是市面上打包賣的那種課程,我認為教程多未必是好事,10年前我自學快,除了自身執行力以外,還有就是教程少。不要害羞做伸手黨,等你一個小紅點。後期我也會組建一些純技術交流的小圈子,讓大家能認識更多的大佬,有個好的圈子,你對行業的認知一定是最前沿的。