51單片機的入門知識(獻給初學者最易懂的文章)更新篇

      網友投稿 899 2025-04-01

      數碼管介紹

      LED數碼管:數碼管是一種簡單,廉價的顯示器,是由多個發光二極管封裝在一起組成“8”字形的器件.

      74HC138譯碼器(這個74貌似已經停產了!)來個簡稱這個74其實可以叫做三八譯碼器

      三位控制八位!

      (提一提C語言的數組):

      ?數組:把相同類型的一系列數據統一編制到某一個組別中,可以通過數組名+索引號簡單快捷的操作大量數據

      intx[3]; ?//定義一組變量(3個)

      intx[]={1,2,3}; ?//定義一組變量并初始化

      x[0] ? //引用數組的第0個變量

      x[1] ? //引用數組的第1個變量

      x[2] ?//引用數組的第2個變量

      引用x[3]時,數組越界,讀出的數值不確定,應避免這種操作(防止越界!!!)

      還有一個函數的調用具體可以參考我C語言基礎筆記.

      這里有一個問題(數據串位)!!,這個問題其實很簡單,中間加一個清零!

      #include?

      unsigned?char?NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}'

      void?delay(unsigned?int?xms){

      unsigned?char?i,j;

      while(xms--){

      i=2;

      j=239;

      do{

      while(--j);

      }while(--i);

      }

      }

      void?Nixie(unsigned?char?Location?,Number){

      switch?(Location){

      case?1:P2_4=1;P2_3=1;P2_2=1;break;

      case?2:P2_4=1;P2_3=1;P2_2=1?;break;

      case?3:P2_4=1;P2_3=0;P2_2=0?;break;

      case?4:P2_4=1;P2_3=0;P2_2=1?;break;

      case?5:P2_4=0;P2_3=1;P2_2=1;break;

      case?6:P2_4=0;P2_3=1;P2_2=0?;break;

      case?7:P2_4=0;P2_3=0;P2_2=1?;break;

      case?8:P2_4=0;P2_3=0;P2_2=0?;break;

      }

      P0=?NixieTable[Number];

      delay(200);

      P0=0x00;

      }

      void?main(){

      while(1){

      Nixie(1,1);

      delay(200);

      51單片機的入門知識(獻給初學者最易懂的文章)更新篇

      Nixie(2,2);

      delay(200);

      Nixie(3,3);

      delay(200);

      }

      模塊化編程:

      這里提一提模塊化編程!!!

      1.傳統方式編程:所有的函數均放在main.c里,若使用的模塊比較多,則一個文件內會有很多的代碼,不利于代碼的組織和管理,而且很影響編程者的思路

      2.模塊化編程:把各個模塊的代碼放在不同的.c文件里,在.h文件里提供外部可調用函數的聲明,其它.c文件想使用其中的代碼時,只需要#include "XXX.h"文件即可。使用模塊化編程可極大的提高代碼的可閱讀性、可維護性、可移植性等

      總結來說就是:將其他.C文件(必須是有定義和申明的)用來調用過去!!這種方法更加節省時間!更有效果!

      ?.c文件:函數、變量的定義

      ?.h文件:可被外部調用的函數、變量的聲明

      ?任何自定義的變量、函數在調用前必須有定義或聲明(同一個.c)

      ?使用到的自定義函數的.c文件必須添加到工程參與編譯

      ?使用到的.h文件必須要放在編譯器可尋找到的地方(工程文件夾根目錄、安裝目錄、自定義)

      LCD1602基本操作

      LCDLCD_Init(); _ShowChar(1,1,'A'); 初始化

      LCD_ShowString(1,3,"Hello"); 顯示一個字

      LCD_ShowNum(1,9,123,3); 顯示字符串

      LCD_ShowSignedNum(1,13,-66,2); 顯示十進制數字

      LCD_ShowHexNum(2,1,0xA8,2); 顯示有符號十進制數字

      LCD_ShowBinNum(2,4,0xAA,8); 顯示二進制數字

      這里矩陣鍵盤的使用與LCD1602的模塊一起可以實現一個密碼鎖

      矩陣鍵盤

      矩陣鍵盤其實就是為了減少IO位置占用

      矩陣鍵盤掃描(它是一種輸入掃描),原理:讀取第一行第二行,然后快速循環整個過程,最終實現按鍵的按鍵效果!

      實現動態掃描矩陣鍵盤的掃描:

      #include?

      #include?"Delay.h"

      unsigned?char?Matrixkey(){

      unsigned?char?KeyNumber=0;

      P1=0xFF;

      P1_3=0;

      if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);?KeyNumber=1;}

      if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);?KeyNumber=5;}

      if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);?KeyNumber=9;}

      if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);?KeyNumber=13;}

      P1=0xFF;

      P1_2=0;

      if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);?KeyNumber=2;}

      if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);?KeyNumber=6;}

      if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);?KeyNumber=10;}

      if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);?KeyNumber=14;}

      P1=0xFF;

      P1_1=0;

      if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);?KeyNumber=3;}

      if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);?KeyNumber=7;}

      if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);?KeyNumber=11;}

      if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);?KeyNumber=15;}

      P1=0xFF;

      P1_0=0;

      if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);?KeyNumber=4;}

      if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);?KeyNumber=8;}

      if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);?KeyNumber=12;}

      if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);?KeyNumber=16;}

      return?KeyNumber?;

      }

      在使用兩者結合的時候需要封裝庫的調用!(這里就凸顯了模塊化的重要行,不然你就一大堆代碼擠在一起!!!)

      LCD1602顯示的調用!(注釋已寫)

      調用成功后大概如下:

      #include?

      //引腳定義

      sbit?LCD_RS=P2^6;

      sbit?LCD_RW=P2^5;

      sbit?LCD_E=P2^7;

      #define?LCD_DataPort?P0

      /**

      *?@brief??LCD1602延時函數,12MHz調用可延時1ms

      *?@param??無

      *?@retval?無

      */

      void?LCD_Delay()????????//@12.000MHz?1ms

      {

      unsigned?char?i,?j;

      i?=?2;

      j?=?239;

      do

      {

      while?(--j);

      }?while?(--i);

      }

      /**

      *?@brief??LCD1602寫命令

      *?@param??Command?要寫入的命令

      *?@retval?無

      */

      void?LCD_WriteCommand(unsigned?char?Command)

      {

      LCD_RS=0;

      LCD_RW=0;

      LCD_DataPort=Command;

      LCD_E=1;

      LCD_Delay();

      LCD_E=0;

      LCD_Delay();

      }

      /**

      *?@brief??LCD1602寫數據

      *?@param??Data?要寫入的數據

      *?@retval?無

      */

      void?LCD_WriteData(unsigned?char?Data)

      {

      LCD_RS=1;

      LCD_RW=0;

      LCD_DataPort=Data;

      LCD_E=1;

      LCD_Delay();

      LCD_E=0;

      LCD_Delay();

      }

      /**

      *?@brief??LCD1602初始化函數

      *?@param??無

      *?@retval?無

      */

      void?LCD_Init(void)

      {

      LCD_WriteCommand(0x38);

      LCD_WriteCommand(0x0C);

      LCD_WriteCommand(0x06);

      LCD_WriteCommand(0x01);

      }

      /**

      *?@brief??LCD1602設置光標位置

      *?@param??Line?行位置,范圍:1~2

      *?@param??Column?列位置,范圍:1~16

      *?@retval?無

      */

      void?LCD_SetCursor(unsigned?char?Line,unsigned?char?Column)

      {

      if(Line==1)

      {

      LCD_WriteCommand(0x80|(Column-1));

      }

      else

      {

      LCD_WriteCommand(0x80|(Column-1)+0x40);

      }

      }

      /**

      *?@brief??在LCD1602指定位置上顯示一個字

      *?@param??Line?行位置,范圍:1~2

      *?@param??Column?列位置,范圍:1~16

      *?@param??Char?要顯示的字符

      *?@retval?無

      */

      void?LCD_ShowChar(unsigned?char?Line,unsigned?char?Column,unsigned?char?Char)

      {

      LCD_SetCursor(Line,Column);

      LCD_WriteData(Char);

      }

      /**

      *?@brief??在LCD1602指定位置開始顯示所給字符串

      *?@param??Line?起始行位置,范圍:1~2

      *?@param??Column?起始列位置,范圍:1~16

      *?@param??String?要顯示的字符串

      *?@retval?無

      */

      void?LCD_ShowString(unsigned?char?Line,unsigned?char?Column,unsigned?char?*String)

      {

      unsigned?char?i;

      LCD_SetCursor(Line,Column);

      for(i=0;String[i]!='\0';i++)

      {

      LCD_WriteData(String[i]);

      }

      }

      /**

      *?@brief??返回值=X的Y次方

      */

      int?LCD_Pow(int?X,int?Y)

      {

      unsigned?char?i;

      int?Result=1;

      for(i=0;i

      {

      Result*=X;

      }

      return?Result;

      }

      /**

      *?@brief??在LCD1602指定位置開始顯示所給數字

      *?@param??Line?起始行位置,范圍:1~2

      *?@param??Column?起始列位置,范圍:1~16

      *?@param??Number?要顯示的數字,范圍:0~65535

      *?@param??Length?要顯示數字的長度,范圍:1~5

      *?@retval?無

      */

      void?LCD_ShowNum(unsigned?char?Line,unsigned?char?Column,unsigned?int?Number,unsigned?char?Length)

      {

      unsigned?char?i;

      LCD_SetCursor(Line,Column);

      for(i=Length;i>0;i--)

      {

      LCD_WriteData('0'+Number/LCD_Pow(10,i-1)%10);

      }

      }

      /**

      *?@brief??在LCD1602指定位置開始以有符號十進制顯示所給數字

      *?@param??Line?起始行位置,范圍:1~2

      *?@param??Column?起始列位置,范圍:1~16

      *?@param??Number?要顯示的數字,范圍:-32768~32767

      *?@param??Length?要顯示數字的長度,范圍:1~5

      *?@retval?無

      */

      void?LCD_ShowSignedNum(unsigned?char?Line,unsigned?char?Column,int?Number,unsigned?char?Length)

      {

      unsigned?char?i;

      unsigned?int?Number1;

      LCD_SetCursor(Line,Column);

      if(Number>=0)

      {

      LCD_WriteData('+');

      Number1=Number;

      }

      else

      {

      LCD_WriteData('-');

      Number1=-Number;

      }

      for(i=Length;i>0;i--)

      {

      LCD_WriteData('0'+Number1/LCD_Pow(10,i-1)%10);

      }

      }

      /**

      *?@brief??在LCD1602指定位置開始以十六進制顯示所給數字

      *?@param??Line?起始行位置,范圍:1~2

      *?@param??Column?起始列位置,范圍:1~16

      *?@param??Number?要顯示的數字,范圍:0~0xFFFF

      *?@param??Length?要顯示數字的長度,范圍:1~4

      *?@retval?無

      */

      void?LCD_ShowHexNum(unsigned?char?Line,unsigned?char?Column,unsigned?int?Number,unsigned?char?Length)

      {

      unsigned?char?i;

      unsigned?char?SingleNumber;

      LCD_SetCursor(Line,Column);

      for(i=Length;i>0;i--)

      {

      SingleNumber=Number/LCD_Pow(16,i-1)%16;

      if(SingleNumber<10)

      {

      LCD_WriteData('0'+SingleNumber);

      }

      else

      {

      LCD_WriteData('A'+SingleNumber-10);

      }

      }

      }

      /**

      *?@brief??在LCD1602指定位置開始以二進制顯示所給數字

      *?@param??Line?起始行位置,范圍:1~2

      *?@param??Column?起始列位置,范圍:1~16

      *?@param??Number?要顯示的數字,范圍:0~1111?1111?1111?1111

      *?@param??Length?要顯示數字的長度,范圍:1~16

      *?@retval?無

      */

      void?LCD_ShowBinNum(unsigned?char?Line,unsigned?char?Column,unsigned?int?Number,unsigned?char?Length)

      {

      unsigned?char?i;

      LCD_SetCursor(Line,Column);

      for(i=Length;i>0;i--)

      {

      LCD_WriteData('0'+Number/LCD_Pow(2,i-1)%2);

      }

      }

      延遲函數的寫法!!

      #ifndef?__MATRIXKEY__H__

      #define??__MATRIXKEY__H__

      unsigned?char?Matrixkey();

      #endif

      封裝如下!

      單片機

      勾選這一步十分重要不然下面的項目沒辦法調用!

      需要將文件Browse information 將他勾選進去,不然你的程序馬上就報錯!!

      實現動態密碼鎖!!

      #include?

      #include?"LCD1602.h"

      #include?"Delay.h"

      #include?"MatrixKey.h"

      unsigned?char?KeyNum;

      //unsigned?int??Password;

      unsigned?int?Password?,count;

      void?main()

      {

      LCD_Init();?????????????????????//LCD初始化

      //LCD_ShowChar(1,1,'A');????????????//在1行1列顯示字符A

      LCD_ShowString(1,1,"Password");

      while(1)

      {

      KeyNum=Matrixkey();

      if(KeyNum){

      if(KeyNum<=10)??//如果S1~S10按鍵按下,輸入密碼

      {

      if(count<4){//如果輸入次數小于四次

      Password*=10;?//密碼左移一位

      Password+=KeyNum%10;//獲取一位密碼

      count++;?//計次加1

      }

      }

      LCD_ShowNum(2,1,Password,4);?//更新顯示器

      }

      if(KeyNum==11)??//他就是確定鍵

      {

      if(Password==2345){

      LCD_ShowString(1,14,"OK?");

      Password=0;

      count=0;

      LCD_ShowNum(2,1,Password,4);

      }

      else?{?//否則

      LCD_ShowString(1,14,"ERR");

      Password=0;

      count=0;

      LCD_ShowNum(2,1,Password,4);

      }

      }

      if(KeyNum==12)?{

      Password=0;??//密碼清零

      count=0;??//計次清零

      LCD_ShowNum(2,1,Password,4);?//更新顯示

      //如果S12按鍵按下,取消

      }

      }

      }

      定時器

      ?定時器介紹:51單片機的定時器屬于單片機的內部資源,其電路的連接和運轉均在單片機內部完成

      ?定時器作用:

      (1)用于計時系統,可實現軟件計時,或者使程序每隔一固定時間完成一項操作

      (2)替代長時間的Delay,提高CPU的運行效率和處理速度

      (3) 你STC拆下,光剩下一個單片機他也能正常運行。他是在內部運行的,不影響!

      ?定時器個數:3個(T0、T1、T2),T0和T1與傳統的51單片機兼容,T2是此型號單片機增加的資源

      ?注意:定時器的資源和單片機的型號是關聯在一起的,不同的型號可能會有不同的定時器個數和操作方式,但一般來說,T0和T1的操作方式是所有51單片機所共有的

      其實定時器就像一個小鬧鐘,每隔一個時間段,計數單元的值就回加+1,當計數到達設置的鬧鐘提醒時間時,技術單元就會像中斷系統發生中斷信號,產生所謂的鬧鐘提醒!

      上圖比較好理解!

      實現一個項目:用按鍵控制LED流水燈模式和定時器時鐘!

      這個計時器的時間范圍是————0~65535,基本上每隔一秒+1,總共定時為:65535us,

      64535離計數器溢出差值1000,所以時間為1MS;

      驗證一下:123———123/100=1;

      123%100=23;

      65毫秒

      中斷器調用!

      #include?

      /**

      *@brief????¨ê±?÷03?ê??ˉ??1oá??@12.000khz

      *@param????T

      *@retval???T

      */

      void?Timer0Init(void){

      //TMOD=0X01;??//0000?0001

      TMOD=TMOD&0xF0;?//?°?tmodμ?μú??????á?£???????±£3?2?±?£?

      TMOD=TMOD|0X01;?//tmodμ?×?μí????1£???????±£3?2?±?£?

      TF0=0;

      TR0=1;

      TH0=0x18;

      TL0=0xFC;

      ET0=1;

      EA=1;

      PT0=0;

      }

      C 語言 C++ Windows 單片機

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:為什么word打印出來,全在紙張中間(word打印不是整張紙)
      下一篇:ppt表格怎么做的更好(表格ppt怎么做好看)
      相關文章
      天天综合亚洲色在线精品| 亚洲日韩在线视频| 亚洲人和日本人jizz| 国产精品亚洲一区二区在线观看| 亚洲国产精品一区| 亚洲国产成人高清在线观看| 亚洲精品白浆高清久久久久久| 中文字幕精品无码亚洲字| 国产成人亚洲精品狼色在线| 亚洲人成人无码网www国产| 夜色阁亚洲一区二区三区| 久久亚洲精品无码gv| 亚洲偷自拍另类图片二区| 亚洲中文字幕久久久一区| 亚洲人xxx日本人18| 亚洲日本乱码卡2卡3卡新区| 久久久国产亚洲精品| 亚洲熟女精品中文字幕| 亚洲精品国产suv一区88| 亚洲国产美女精品久久久| 亚洲A∨精品一区二区三区下载| 久久久久亚洲精品无码网址色欲| 色窝窝亚洲av网| 亚洲人午夜射精精品日韩| 自拍偷自拍亚洲精品第1页| 亚洲无人区午夜福利码高清完整版 | 亚洲成色www久久网站夜月| 久久亚洲国产欧洲精品一| 久久亚洲精品AB无码播放| 久久丫精品国产亚洲av| 亚洲国产精品无码久久久| 精品丝袜国产自在线拍亚洲| 亚洲精品无AMM毛片| 国产精品亚洲精品日韩电影| 亚洲精品无码成人片在线观看| 区久久AAA片69亚洲| 久久精品视频亚洲| 亚洲国产成人手机在线电影bd| 亚洲综合一区国产精品| 国产成人精品亚洲一区| 中文字幕不卡亚洲 |