单片机学习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
posted @ 2020-10-05 13:32  那个白熊  阅读(1608)  评论(0编辑  收藏  举报