最近進的公司是一個做路由器的。。很多嵌入式工程師。有個項目( 智能空調控制)是跟嵌入式工程師對接,我做APP+PHP。。他做伺服器。我們用MQTT(由於emqtt是用erlang寫的,所以我也學了點erlang,後期有時間分享一下,這個語言很好,很強大。特別抽象)。這個項目激發了我對嵌入式的興趣,於 ...
最近進的公司是一個做路由器的。。很多嵌入式工程師。有個項目( 智能空調控制)是跟嵌入式工程師對接,我做APP+PHP。。他做伺服器。我們用MQTT(由於emqtt是用erlang寫的,所以我也學了點erlang,後期有時間分享一下,這個語言很好,很強大。特別抽象)。這個項目激發了我對嵌入式的興趣,於是乎。開始從51單片機搞起了。。所以就有了這篇文章。。。今天搞得東西挺多。我最近都是筆記形式,不想以前寫的那麼詳細。。。因為學的東西太多,白天在公司搞項目,沒時間寫太具體。。。
今天學了什麼呢?
>keil安裝和使用,下載程式到開發板
>點亮第一個led燈,這個很簡單。給單片機的p0口 的最低位,輸入一個高電平,就可以點亮一個動態數位管【當然下載程式之後,要連線】
#include <reg52.h> sbit led1 = P0^0; void main(){ led1 = 1; }
>在點亮led之後,再加點程式控制,讓led閃爍。。。閃爍的思路也簡單: 一下高電平。然後延時,再低電平。。再延時。。就OK了。。延時多少秒合適? 可以通過keil軟體模擬算出。模擬的時候,記得把晶振調整跟開發板一樣。我的開發板是12M
#include <reg52.h> sbit led = P0^0; typedef unsigned char u8; typedef unsigned int u16; void delay( u16 i ){ while( i-- ); } void main (){ while( 1 ) { led = 1; //delay( 5000 ); // 通過軟體模擬得出 執行5000次迴圈 需要45ms delay( 50000 ); led = 0; //delay( 5000 ); delay( 50000 ); } }
>點亮led之後,再來一個流水燈,思路就是迴圈設置一個數位管的某一段 為 高電平。其他段為低電平。。然後,延時迴圈。就可以達到流水燈的效果
#include <reg52.h> #include <intrins.h> #include <stdio.h> #define led P0 typedef unsigned char u8; typedef unsigned int u16; void delay( u16 i ){ while( i-- ); } void main (){ u8 i = 0; //led = 0x01; //p0的 最低位為高電平 0x01( p0埠的第8位為1 即,高電平 ) led = 0x80; while( 1 ) { /* 方法一: 不用庫函數 for( i = 0; i < 8; i++ ){ led = ( 0x01 << i ); //迴圈移位, 把p0埠從p0.0--->p0.7迴圈設置為高電平 delay( 50000 ); } */ //方法二,使用庫函數 /* for( i = 0 ; i < 8; i++ ){ led = _crol_( led, 1 ); //每次向左移動1位 delay( 50000 ); } */ for( i = 0 ; i < 8; i++ ){ led = _cror_( led, 1 ); //每次向右移動1位 delay( 50000 ); } } }
>再然後,控制蜂鳴器。。我的開發板是無源蜂鳴器靠頻率驅動。把頻率換算成周期: F = 1 / T,周期通過延時函數實現。 然後改變高低電平的占空比,可以實現蜂鳴器的聲音大小。頻率改變的是蜂鳴器
的音色。
#include <reg52.h> #define led P0 typedef unsigned char u8; typedef unsigned int u16; sbit beep = P1^5; //用p1口的第5位 void delay( u16 i ){ while( i-- ); } void main (){ //無源蜂鳴器靠頻率驅動, 假設10k能驅動, 那麼T = 1 / 10k, T = 0.1 毫秒 //之前的測試是迴圈50000次 = 450 ms(毫秒 ) 那0.1 ms = 12.8次 while( 1 ) { beep = ~beep; //~:取反操作 delay( 50 ); //改變高低電平的占空比(比例) 控制蜂鳴器聲音大小 beep = 1; delay( 50 ); beep = 0; delay( 5 ); } }
>在然後,控制一個繼電器。這個很簡單。跟點亮led燈同樣的思路
#include <reg52.h> #define led P0 typedef unsigned char u8; typedef unsigned int u16; //繼電器控制 sbit relay = P1^4; //用p1口的第4位 void main (){ relay = 0; //給一個低電平 繼電器開啟 while( 1 ) { } }
>再然後,在靜態數位管上做了個迴圈顯示0~F的程式,思路就是 1~F 怎麼在靜態數位管上表示? 因為我的開發板靜態數位管是共陽數位管。要用低電平才能點亮對應的段。然後把每一位數字(0~F)對應的
二進位算出對應的十六進位,就是我程式中定義的那個數組表示的就是( 0 ~ F).
#include <reg52.h> #define led P0 typedef unsigned char u8; typedef unsigned int u16; void delay( u16 i ){ while( i-- ); } void main (){ u8 character [16] = { 0xC0, 0xF9 , 0xA4 , 0xB0 , 0x99 , 0x92, 0x82 , 0xF8 , 0x80 , 0x90 , 0x88 , 0x83, 0xC6 , 0xA1 , 0x86 , 0x8E}; int i = 0; while( 1 ) { for( i = 0; i < 16; i++ ){ led = character[i]; delay( 50000 ); delay( 50000 ); } } }
>在然後,在8個動態數位上顯示1~8,用到38解碼器模塊的輸入,輸出,我的第一版(傻瓜版程式)
#include <reg52.h> sbit A1 = P2^2; sbit B1 = P2^3; sbit C1 = P2^4; #define led P0 typedef unsigned char u8; typedef unsigned int u16; void delay( u16 i ){ while( i-- ); } void main (){ while( 1 ){ A1 = 0x0; B1 = 0x0; C1 = 0x0; //0x06 , 0x5b , 0x4f , 0x66 , 0x6d, 0x7d , 0x07 , 0x7f led = 0x06; delay( 100 ); A1 = 0x1; B1 = 0x0; C1 = 0x0; led = 0x5b; delay( 100 ); A1 = 0x0; B1 = 0x1; C1 = 0x0; led = 0x4f; delay( 100 ); A1 = 0x1; B1 = 0x1; C1 = 0x0; led = 0x66; delay( 100 ); A1 = 0x0; B1 = 0x0; C1 = 0x1; led = 0x6d; delay( 100 ); A1 = 0x1; B1 = 0x0; C1 = 0x1; led = 0x7d; delay( 100 ); A1 = 0x0; B1 = 0x1; C1 = 0x1; led = 0x07; delay( 100 ); A1 = 0x1; B1 = 0x1; C1 = 0x1; led = 0x7f; delay( 100 ); } }
然後經過封裝改造的程式:
#include <reg52.h> sbit A1 = P2^2; sbit B1 = P2^3; sbit C1 = P2^4; #define led P0 typedef unsigned char u8; typedef unsigned int u16; void delay( u16 i ){ while( i-- ); } u8 digital[16] = { 0x3f , 0x06 , 0x5b , 0x4f , 0x66 , 0x6d, 0x7d , 0x07 , 0x7f , 0x6f , 0x77 , 0x7c, 0x39 , 0x5e , 0x79 , 0x71 }; void showDigital(){ int i = 0; for ( i = 0; i < 8; i++ ) { switch( i ) { case 0: //位選第一個數位管 A1 = 0x0; B1 = 0x0; C1 = 0x0; break; case 1: A1 = 0x1; B1 = 0x0; C1 = 0x0; break; case 2: A1 = 0x0; B1 = 0x1; C1 = 0x0; break; case 3: A1 = 0x1; B1 = 0x1; C1 = 0x0; break; case 4: A1 = 0x0; B1 = 0x0; C1 = 0x1; break; case 5: A1 = 0x1; B1 = 0x0; C1 = 0x1; break; case 6: A1 = 0x0; B1 = 0x1; C1 = 0x1; break; case 7: A1 = 0x1; B1 = 0x1; C1 = 0x1; break; } led = digital[ i ]; delay( 100 ); } } void main (){ while( 1 ){ showDigital(); } }