單片機學習01__跑起你的流水燈


本次實驗使用的是普中51-單核-A2開發板。

一、原理圖

1.1 單片機核心

1.2 LED模塊

RP9/RP10 是這塊電路板上第幾個排阻的意思。
471是其阻值,47*10^1=470歐姆。

二、程序代碼

2.1 實驗目的

根據原理圖我們可以知道,8個led燈在P2上,低位亮起。
我們可以根據這個原理進行實現各式各樣的跑馬燈。

2.2 編寫程序

2.2.1 亮起1個燈

#include<reg51.h>
void main()
{
    P2 = ~0x01;
    while(1){}
}

在這個例子中,我們將最低位置1然后取反,也就是將最低位設為0,低電位亮起。
加一個while死循環是為了讓程序困在我們的代碼中,防止跑到未知代碼擾亂電位狀態。

開頭引用的reg51.h其實也沒什么神秘的,在keil中編寫代碼的時候,可以在reg51上面右鍵查看其內容。

我們可以看到這里面無非就是定義了一些端口或者寄存器什么的。
而我們的這個程序就用到了一個P2,所以我們可以直接在程序里面寫而不引用文件嗎?
當然可以的!
所以我們的程序可以寫為:

sfr P2   = 0xA0;
void main()
{
    P2 = ~0x01;
    while(1){}
}

編譯之后,就可以燒錄進板子了。

2.2.2 亮起兩個燈,再閃一下

要想亮起燈,我們就要把8個燈相應的位置0

D8 D7 D6 D5 D4 D3 D2 D1
8 4 2 1 8 4 2 1

比如我們想讓兩端的燈亮起,則需要將D8&D1對應的位置0
在這里我們將其設置為0x81然后取反即可。

#include "reg51.h"

void delay(unsigned int z)
{
    while(--z);
}

void main()
{
    P2 = 0x81;
    while(1)
    {
        delay(10000);
        P2 = ~P2;
    }
}

2.2.3 跑馬燈

實驗現象:燈左右來回跑動。
程序編寫:使用置0位移實現。

#include "reg51.h"

void delay(unsigned int z)
{
    while(--z);
}

void main()
{
    P2 = 0xfe;
    while(1)
    {
        P2 <<= 1;
        P2 |= 0x01;
        delay(10000);
        if (P2 == 0x7f)
        {
            while(1)
            {
                P2 >>= 1;
                P2 |= 0x80;
                delay(10000);
                if (P2 == 0xfe)
                {
                    break;
                }
            }
        }
    }
}

優化版:

#include "reg51.h"
#include "intrins.h"

void delay(unsigned int z)
{
    while(--z);
}

void main()
{
    unsigned char i;
    P2 = ~0x01;
    while(1)
    {
        for(i = 0; i < 7; i++)
        {
            delay(10000);
            P2 = _crol_(P2, 1);
        }
        
        for(i = 0; i < 7; i++)
        {
            delay(10000);
            P2 = _cror_(P2, 1);
        }
    }
}

在此程序中:

P2 = _crol_(P2, 1);
相當於:
P2 = 0x01;
P2 <<= 1;
P2 |= 0x01;

P2 = _cror_(P2, 1)
相當於:
P2 = 0x7f;
P2 >>= 1;
P2 |= 0x80;

2.2.4 其他參考程序

單向跑馬燈:

#include "reg51.h"
#include "intrins.h"

void delay(unsigned int z)
{
    while(--z);
}

void main()
{
    delay(10000);
    // 左循環移位
    P2 = _crol_(P2, 1);
    // 右循環移位
    //P2 = _cror_(P2, 1);
}

雙向跑馬燈:

/**************************************************************************************
實驗現象:下載程序后"LED&交通燈模塊"的D1-D8呈現流水燈效果
接線說明: 單片機-->LED&交通燈模塊(具體接線圖可見開發攻略對應實驗的“實驗現象”章節)
		   P00-->D1
		   P01-->D2	
		   ...
		   P07-->D8
注意事項:																				  
***************************************************************************************/

#include "reg52.h"			 //此文件中定義了單片機的一些特殊功能寄存器
#include<intrins.h>		//因為要用到左右移函數,所以加入這個頭文件

typedef unsigned int u16;	  //對數據類型進行聲明定義
typedef unsigned char u8;

#define led P2	   //將P2口定義為led 后面就可以使用led代替P2口

/*******************************************************************************
* 函 數 名         : delay
* 函數功能		   : 延時函數,i=1時,大約延時10us
*******************************************************************************/
void delay(u16 i)
{
	while(i--);	
}

/*******************************************************************************
* 函 數 名       : main
* 函數功能		 : 主函數
* 輸    入       : 無
* 輸    出    	 : 無
*******************************************************************************/
void main()
{
	u8 i;
	led=~0x01;
	delay(50000); //大約延時450ms	
	while(1)
	{	
		for(i=0;i<8;i++)
		{
			P2=~(0x01<<i);	 //將1右移i位,然后將結果賦值到P2口
			delay(50000); //大約延時450ms
		}

		
/*		for(i=0;i<7;i++)	 //將led左移一位
		{
			led=_crol_(led,1);
			delay(50000); //大約延時450ms	
		}
		for(i=0;i<7;i++)	//將led右移一位
		{
			led=_cror_(led,1);
			delay(50000); //大約延時450ms	
		}
*/
	}		
}

附:reg51.h的內容:

/*--------------------------------------------------------------------------
REG51.H

Header file for generic 80C51 and 80C31 microcontroller.
Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/

#ifndef __REG51_H__
#define __REG51_H__

/*  BYTE Register  */
sfr P0   = 0x80;
sfr P1   = 0x90;
sfr P2   = 0xA0;
sfr P3   = 0xB0;
sfr PSW  = 0xD0;
sfr ACC  = 0xE0;
sfr B    = 0xF0;
sfr SP   = 0x81;
sfr DPL  = 0x82;
sfr DPH  = 0x83;
sfr PCON = 0x87;
sfr TCON = 0x88;
sfr TMOD = 0x89;
sfr TL0  = 0x8A;
sfr TL1  = 0x8B;
sfr TH0  = 0x8C;
sfr TH1  = 0x8D;
sfr IE   = 0xA8;
sfr IP   = 0xB8;
sfr SCON = 0x98;
sfr SBUF = 0x99;


/*  BIT Register  */
/*  PSW   */
sbit CY   = 0xD7;
sbit AC   = 0xD6;
sbit F0   = 0xD5;
sbit RS1  = 0xD4;
sbit RS0  = 0xD3;
sbit OV   = 0xD2;
sbit P    = 0xD0;

/*  TCON  */
sbit TF1  = 0x8F;
sbit TR1  = 0x8E;
sbit TF0  = 0x8D;
sbit TR0  = 0x8C;
sbit IE1  = 0x8B;
sbit IT1  = 0x8A;
sbit IE0  = 0x89;
sbit IT0  = 0x88;

/*  IE   */
sbit EA   = 0xAF;
sbit ES   = 0xAC;
sbit ET1  = 0xAB;
sbit EX1  = 0xAA;
sbit ET0  = 0xA9;
sbit EX0  = 0xA8;

/*  IP   */ 
sbit PS   = 0xBC;
sbit PT1  = 0xBB;
sbit PX1  = 0xBA;
sbit PT0  = 0xB9;
sbit PX0  = 0xB8;

/*  P3  */
sbit RD   = 0xB7;
sbit WR   = 0xB6;
sbit T1   = 0xB5;
sbit T0   = 0xB4;
sbit INT1 = 0xB3;
sbit INT0 = 0xB2;
sbit TXD  = 0xB1;
sbit RXD  = 0xB0;

/*  SCON  */
sbit SM0  = 0x9F;
sbit SM1  = 0x9E;
sbit SM2  = 0x9D;
sbit REN  = 0x9C;
sbit TB8  = 0x9B;
sbit RB8  = 0x9A;
sbit TI   = 0x99;
sbit RI   = 0x98;

#endif

附:reg52.h

/*--------------------------------------------------------------------------
REG52.H

Header file for generic 80C52 and 80C32 microcontroller.
Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/

#ifndef __REG52_H__
#define __REG52_H__

/*  BYTE Registers  */
sfr P0    = 0x80;
sfr P1    = 0x90;
sfr P2    = 0xA0;
sfr P3    = 0xB0;
sfr PSW   = 0xD0;
sfr ACC   = 0xE0;
sfr B     = 0xF0;
sfr SP    = 0x81;
sfr DPL   = 0x82;
sfr DPH   = 0x83;
sfr PCON  = 0x87;
sfr TCON  = 0x88;
sfr TMOD  = 0x89;
sfr TL0   = 0x8A;
sfr TL1   = 0x8B;
sfr TH0   = 0x8C;
sfr TH1   = 0x8D;
sfr IE    = 0xA8;
sfr IP    = 0xB8;
sfr SCON  = 0x98;
sfr SBUF  = 0x99;

/*  8052 Extensions  */
sfr T2CON  = 0xC8;
sfr RCAP2L = 0xCA;
sfr RCAP2H = 0xCB;
sfr TL2    = 0xCC;
sfr TH2    = 0xCD;


/*  BIT Registers  */
/*  PSW  */
sbit CY    = PSW^7;
sbit AC    = PSW^6;
sbit F0    = PSW^5;
sbit RS1   = PSW^4;
sbit RS0   = PSW^3;
sbit OV    = PSW^2;
sbit P     = PSW^0; //8052 only

/*  TCON  */
sbit TF1   = TCON^7;
sbit TR1   = TCON^6;
sbit TF0   = TCON^5;
sbit TR0   = TCON^4;
sbit IE1   = TCON^3;
sbit IT1   = TCON^2;
sbit IE0   = TCON^1;
sbit IT0   = TCON^0;

/*  IE  */
sbit EA    = IE^7;
sbit ET2   = IE^5; //8052 only
sbit ES    = IE^4;
sbit ET1   = IE^3;
sbit EX1   = IE^2;
sbit ET0   = IE^1;
sbit EX0   = IE^0;

/*  IP  */
sbit PT2   = IP^5;
sbit PS    = IP^4;
sbit PT1   = IP^3;
sbit PX1   = IP^2;
sbit PT0   = IP^1;
sbit PX0   = IP^0;

/*  P3  */
sbit RD    = P3^7;
sbit WR    = P3^6;
sbit T1    = P3^5;
sbit T0    = P3^4;
sbit INT1  = P3^3;
sbit INT0  = P3^2;
sbit TXD   = P3^1;
sbit RXD   = P3^0;

/*  SCON  */
sbit SM0   = SCON^7;
sbit SM1   = SCON^6;
sbit SM2   = SCON^5;
sbit REN   = SCON^4;
sbit TB8   = SCON^3;
sbit RB8   = SCON^2;
sbit TI    = SCON^1;
sbit RI    = SCON^0;

/*  P1  */
sbit T2EX  = P1^1; // 8052 only
sbit T2    = P1^0; // 8052 only
             
/*  T2CON  */
sbit TF2    = T2CON^7;
sbit EXF2   = T2CON^6;
sbit RCLK   = T2CON^5;
sbit TCLK   = T2CON^4;
sbit EXEN2  = T2CON^3;
sbit TR2    = T2CON^2;
sbit C_T2   = T2CON^1;
sbit CP_RL2 = T2CON^0;

#endif

附intrins.h

/*--------------------------------------------------------------------------
INTRINS.H

Intrinsic functions for C51.
Copyright (c) 1988-2010 Keil Elektronik GmbH and ARM Germany GmbH
All rights reserved.
--------------------------------------------------------------------------*/

#ifndef __INTRINS_H__
#define __INTRINS_H__

#pragma SAVE

#if defined (__CX2__)
#pragma FUNCTIONS(STATIC)
/* intrinsic functions are reentrant, but need static attribute */
#endif

extern void          _nop_     (void);
extern bit           _testbit_ (bit);
extern unsigned char _cror_    (unsigned char, unsigned char);
extern unsigned int  _iror_    (unsigned int,  unsigned char);
extern unsigned long _lror_    (unsigned long, unsigned char);
extern unsigned char _crol_    (unsigned char, unsigned char);
extern unsigned int  _irol_    (unsigned int,  unsigned char);
extern unsigned long _lrol_    (unsigned long, unsigned char);
extern unsigned char _chkfloat_(float);
#if defined (__CX2__)
extern int           abs       (int);
extern void          _illop_   (void);
#endif
#if !defined (__CX2__)
extern void          _push_    (unsigned char _sfr);
extern void          _pop_     (unsigned char _sfr);
#endif

#pragma RESTORE

#endif


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM