2020-01-03 21:30:15 weixin_45073181 阅读数 159
  • 单片机控制第一个外设-LED-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    3995 人正在学习 去看看 朱有鹏

隔了两周没看,再重新学习时发现之前花了好久搞懂的内容又都让我还回去了,所以记录总结下还是很有必要的。。。。。。。。。。。。。。
##51单片机 流水灯
在这里插入图片描述
上图即为流水灯的模块电路,具体连线如下,强调一下程序段用的是单片机的JP00端口与J12(8个并行排线)相连。初级阶段 模块电路中的74HC245可简单理解为一个通透的驱动电路,输入低电平(高电平),输出也为低电平(高电平)RP20101是限流电阻,LED灯亮度的调节可通过改变限流电阻的大小。如上图D11……D18即LED灯,它的阴极端接地,所以当阳极端输入高电平时LED灯点亮。所以流水灯程序的重点在于使J12的8位并行接口循环为1即要求P0端口循环输出1,我们可以通过for循环和循环左移_CROL_,循环右移_CROR_,来实现,接下来为具体的代码实现段。

(MCS-51单片机有4个8位的并行端口:p0,p1,p2,p3,每个端口都是8位准双向口,共占用32条引脚。)所以当我们想使用其它端口时,让之与J12端口相连即可。
在这里插入图片描述
/************************************************************************************** LED流水灯实验 *
实现现象:下载程序后LED呈现流水灯效果进行左移右移滚动
***************************************************************************************/

#include “reg52.h” //此文件中定义了单片机的一些特殊功能寄存器
#include<intrins.h> //因为要用到左右移函数,所以加入这个头文件

typedef unsigned int u16; //对数据类型进行声明定义,分别是无符号整型
typedef unsigned char u8; //无符号字符型

#define led P0 //因为用的是P0口控制LED的循环点亮,所以将P0口定义为led 具有易读性,后面就可以使用led代替P0口。

void main()
{
u8 i;
led=0x01; 以0x的数据表示16进制,写成二进制即0000 0001,正好对应P0的8个端口。
delay(50000); //大约延时450ms
while(1)
{

	for(i=0;i<7;i++)	 //将led左移一位
	{
		led=_crol_(led,1); //_crol_(led,1)左移函数,从led=0x01=0000 0001开始左移,左移七次即变成1000 0000
		delay(50000); //大约延时450ms	,之所以延时,是因为P0口的指令执行是非常快的,不延时肉眼观察不出流水灯的效果。
	}
	for(i=0;i<7;i++)	//将led右移一位 ,
	{
		led=_cror_(led,1);//紧接着从1000 0000,循环右移七次,在变成0000 0001
		delay(50000); //大约延时450ms	
	}
}		

} //在While循环中,所以反复执行左移7位右移7位即流水灯的效果。

2019-11-19 23:46:21 Dolorous_yuanshao 阅读数 112
  • 单片机控制第一个外设-LED-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    3995 人正在学习 去看看 朱有鹏

1、通过对P1口地址的操作实现流水灯

#include<reg51.h> //包含单片机寄存器的头文件
//要点sfr!
sfr x=0xb0; //P1口在存储器中的地址是90H,通过sfr可定义8051内核单片机
     //的所有内部8位特殊功能寄存器,对地址x的操作也就是对P1口的操作
/****************************************
函数功能:延时一段时间
*****************************************/
void delay(void)
 {
 unsigned char i,j;
 for(i=0;i<250;i++)
   for(j=0;j<250;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(); //调用延时函数
 }
 }

2、用自增运算控制P0口流水灯

#include<reg51.h> //包含单片机寄存器的头文件
/******************************************************
函数功能:延时一段时间
******************************************************/
void delay(void)
{
 unsigned int i;
 for(i=0;i<20000;i++);
}
/******************************************************
函数功能  :主函数
******************************************************/
void main(void)
{
 unsigned char i;
 for(i=0;i<255;i++) //注意i的值不能超过255
 {
     
     P0=i; //将i的值送P0口
     delay(); //调用延时函数
 }
}

3、用右移运算点亮P1口流水灯

#include<reg51.h> //包含单片机寄存器的头文件
/*****************************
函数功能:延时一段时间
*****************************/
void delay(void)
{
 unsigned int n;
 for(n=0;n<30000;n++);
}
/*****************************
函数功能:主函数
*****************************/
void main(void)
{
 unsigned char i;
 while(1)
 {
     P1=0xff;
     delay();
   for(i=0;i<8;i++)//设置循环次数为8
   {
       P1=P1>>1; //每次循环P1的各二进位右移1位,高位补0
       delay(); //调用延时函数
   }
 }
 
}

4、用switch语句的控制P0口流水灯

#include<reg51.h> //包含单片机寄存器的头文件
sbit S1=P3^4; //将S1位定义为P3.4,可自行定义按键,4,5,6,7都可以
/*****************************
函数功能:延时一段时间
*****************************/
void delay(void)
{
 unsigned int n;
 for(n=0;n<10000;n++);
}
/*****************************
函数功能:主函数
*****************************/
void main(void)
{
 unsigned char i;
 i=0; //将i初始化为0
 while(1)
 {
   if(S1==0) //如果S1键按下
   {
     delay(); //延时一段时间
     if(S1==0) //如果再次检测到S1键按下
     i++; //i自增1
     if(i==9) //如果i=9,重新将其置为1
     i=1;
   }
   switch(i) //使用多分支选择语句
       {
       case 1: P1=0xfe; //第一个LED亮
             break;
         case 2: P1=0xfd; //第二个LED亮
         break;
         case 3:P1=0xfb; //第三个LED亮
         break;
         case 4:P1=0xf7; //第四个LED亮
         break;
         case 5:P1=0xef; //第五个LED亮
         break;
         case 6:P1=0xdf; //第六个LED亮
         break;
         case 7:P1=0xbf; //第七个LED亮
       break;
         case 8:P1=0x7f; //第八个LED亮
         break;
         default: //缺省值,关闭所有LED
         P0=0xff;
       }
   } 
}

5、用while语句控制LED流水灯

#include<reg51.h> //包含单片机寄存器的头文件
/****************************************
函数功能:延时约60ms (3*100*200=60000μs)
****************************************/
void delay60ms(void)
{
 unsigned char m,n;
 for(m=0;m<100;m++)
 for(n=0;n<200;n++);
}
/****************************************
函数功能:主函数
****************************************/
void main(void)
{
 unsigned char i;
 while(1) //无限循环
 {
 i=0; //将i初始化为0
   while(i<0xff) //当i小于0xff(255)时执行循环体
   {
         P1=i; //将i送P0口显示
         delay60ms(); //延时
         i++; //i自增1
   }
 }
}

6、用do-while语句控制P1口流水灯

#include<reg51.h> //包含单片机寄存器的头文件
/****************************************
函数功能:延时约60ms (3*100*200=60000μs)
****************************************/
void delay60ms(void)
{
 unsigned char m,n;
 for(m=0;m<100;m++)
 for(n=0;n<200;n++);
}
/****************************************
函数功能:主函数
****************************************/
void main(void)
{
 do
 {
   P1=0xfe; //第一个LED亮
   delay60ms();
   P1=0xfd; //第二个LED亮
   delay60ms();
   P1=0xfb; //第三个LED亮
   delay60ms();
   P1=0xf7; //第四个LED亮
   delay60ms();
   P1=0xef; //第五个LED亮
   delay60ms();
   P1=0xdf; //第六个LED亮
   delay60ms();
   delay60ms();
   P1=0xbf; //第七个LED亮
   delay60ms();
   P1=0x7f; //第八个LED亮
   delay60ms();
 }while(1); //无限循环,使8位LED循环流水点亮
}

7、用字符数组控制P1口流水灯

#include<reg51.h> //包含单片机寄存器的头文件
/****************************************
函数功能:延时约60ms (3*100*200=60000μs)
****************************************/
void delay60ms(void)
{
 unsigned char m,n;
 for(m=0;m<100;m++)
 for(n=0;n<200;n++);
}
/****************************************
函数功能:主函数
****************************************/
void main(void)
{ 
 unsigned char i;
 unsigned char code Tab[ ]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定义无符号字符型数组 
 while(1)
 {
 for(i=0;i<8;i++)
 {
 P1=Tab[i];//依次引用数组元素,并将其送P0口显示
 delay60ms();//调用延时函数
 }
 }
}

8、用P1口显示字符串常量实现流水灯

#include<reg51.h> //包含单片机寄存器的头文件
/*************************************************
函数功能:延时约150ms (3*200*250=150)
*************************************************/
void delay150ms(void)
{
 unsigned char m,n;
 for(m=0;m<200;m++)
 for(n=0;n<250;n++);
}
/*************************************************
函数功能:主函数
*************************************************/
void main(void)
{ 
 unsigned char str[]={"Now,Temperature is :"}; //将字符串赋给字符型全部元素赋值
 unsigned char i;
 while(1)
 {
 i=0; //将i初始化为0,从第一个元素开始显示
 while(str[i]!='\0') //只要没有显示到结束标志'\0'
 {
   P1=str[i]; //将第i个字符送到P0口显示
   delay150ms(); //调用150ms延时函数
   i++; //指向下一个待显字符
   }
 }
}

9、用数组的指针控制P1口流水灯

#include<reg51.h>
/*************************************************
函数功能:延时约150ms (3*200*250=150)
*************************************************/
void delay150ms(void)
{
 unsigned char m,n;
 for(m=0;m<200;m++)
 for(n=0;n<250;n++);
}
/*************************************************
函数功能:主函数
*************************************************/
void main(void)
{ 
 unsigned char code Tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
 unsigned char *p[ ]={&Tab[0],&Tab[1],&Tab[2],&Tab[3],&Tab[4],&Tab[5],
 &Tab[6],&Tab[7]};
 unsigned char i; //定义无符号字符型数据
 while(1)
 {
 for(i=0;i<8;i++)
   {
     P1=*p[i];
     delay150ms();
   }
 }
}

10、用数组的指针控制P1口流水灯(多花样)

#include<reg51.h>
/*************************************************
函数功能:延时约150ms (3*200*250=150)
*************************************************/
void delay150ms(void)
{
 unsigned char m,n;
 for(m=0;m<200;m++)
 for(n=0;n<250;n++);
}
/*************************************************
函数功能:主函数
*************************************************/
void main(void)
{ 
 unsigned char i; 
 unsigned char Tab[ ]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,
                   0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,
             0xFE,0xFC,0xFB,0xF0,0xE0,0xC0,0x80,0x00,
           0xE7,0xDB,0xBD,0x7E,0x3C,0x18,0x00,0x81,
         0xC3,0xE7,0x7E,0xBD,0xDB,0xE7,0xBD,0xDB};
               //流水灯控制码
 unsigned char *p; //定义无符号字符型指针
 p=Tab; //将数组首地址存入指针p
 while(1)
 {
 for(i=0;i<32;i++) //共32个流水灯控制码
   {
     P1=*(p+i); //*(p+i)的值等于a[i]
     delay150ms(); //调用150ms延时函数
   }
 }
}

11、用字符数组控制P1口流水灯速度快慢

#include<reg51.h>
/*************************************************
函数功能:延时一段时间
*************************************************/
void delay(unsigned char x)
{
 unsigned char m,n;
 for(m=0;m<x;m++)
 for(n=0;n<200;n++);
}
/*************************************************
函数功能:主函数
*************************************************/
void main(void)
{ 
 unsigned char i; 
 unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; 
               //流水灯控制码 
 while(1)
 {
 //快速流水点亮LED
 for(i=0;i<8;i++) //共8个流水灯控制码
   {
     P1=Tab[i];
     delay(100); //延时约60ms, (3*100*200=60 000μs)
   }
 //慢速流水点亮LED
 for(i=0;i<8;i++) //共8个流水灯控制码
 {
     P1=Tab[i];
     delay(250); //延时约150ms, (3*250*200=150 000μs)
 }
 }
}

12、用数组做参数控制流水灯

#include<reg51.h>
/*************************************************
函数功能:延时约150ms
*************************************************/
void delay(void)
{
 unsigned char m,n;
 for(m=0;m<200;m++)
 for(n=0;n<250;n++);
}
/*************************************************
函数功能:流水点亮P0口8位LED
*************************************************/
void led_flow(unsigned char a[8])
{
 unsigned char i;
 for(i=0;i<8;i++)
 {
 P1=a[i];
 delay();
 }
}
/*************************************************
函数功能:主函数
*************************************************/
void main(void)
{ 
 unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; 
               //流水灯控制码 
 led_flow(Tab);
 
}

13、用指针作函数参数控制P1流水灯

#include<reg51.h>
/*************************************************
函数功能:延时约150ms
*************************************************/
void delay(void)
{
 unsigned char m,n;
 for(m=0;m<200;m++)
 for(n=0;n<250;n++);
}
/*************************************************
函数功能:流水点亮P0口8位LED
*************************************************/
void led_flow(unsigned char *p) //形参为无符号字符型指针
{
   unsigned char i;
while(1)
 {
 i=0; //将i置为0,指向数组第一个元素
 while(*(p+i)!='\0') //只要没有指向数组的结束标志
 {
   P1=*(p+i);// 取的指针所指变量(数组元素)的值,送P0口
   delay(); //调用延时函数
   i++; //指向下一个数组元素
 }
 }
}
/*************************************************
函数功能:主函数
*************************************************/
void main(void)
{ 
 unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F, 
                   0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,
                   0xFF,0xFE,0xFC,0xFB,0xF0,0xE0,0xC0,0x80,
                   0x00,0xE7,0xDB,0xBD,0x7E,0xFF,0xFF,0x3C,
                   0x18,0x0,0x81,0xC3,0xE7,0xFF,  0xFF,0x7E};
                   //流水灯控制码 
 unsigned char *pointer;
 pointer=Tab;
 led_flow(pointer);
 
}

14、用函数指针控制P1流水灯

#include<reg51.h> //包含51单片机寄存器定义的头文件
unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
//流水灯控制码,该数组被定义为全局变量
/**************************************************************
函数功能:延时约150ms
**************************************************************/
 void delay(void) 
{
 unsigned char m,n;
 for(m=0;m<200;m++)
 for(n=0;n<250;n++);
 }
/**************************************************************
函数功能:流水灯左移
**************************************************************/
void led_flow(void)
{
 unsigned char i;
 for(i=0;i<8;i++) //8位控制码
 {
   P1=Tab[i];
   delay();
 }
 
}
/**************************************************************
函数功能:主函数
**************************************************************/ 
 void main(void)
 {
 void (*p)(void); //定义函数型指针,所指函数无参数,无返回值  
 p=led_flow; //将函数的入口地址赋给函数型指针p
 while(1)
 (*p)(); //通过函数的指针p调用函数led_flow()
}

15、用指针数组作为函数的参数显示多个字符串实现花样流水灯

#include<reg51.h> //包含51单片机寄存器定义的头文件
unsigned char code str1[ ]="Temperature is tested by DS18B20";//C语言中,字符串是作为字符数组来处理的
unsigned char code str2[ ]="Now temperature is:"; //所以,字符串的名字就是字符串的首地址 
unsigned char code str3[ ]="The Systerm is designed by Zhang San";
unsigned char code str4[ ]="The date is 2008-9-30";
unsigned char *p[ ]={str1,str2,str3,str4}; //定义p[4]为指向4个字符串的字符型指针数组 
/**************************************************************
函数功能:延时约150ms
**************************************************************/
 void delay(void) 
{
 unsigned char m,n;
 for(m=0;m<200;m++)
 for(n=0;n<250;n++);
 }
/**************************************************************
函数功能:流水点亮P0口8位LED
**************************************************************/
void led_display(unsigned char *x[ ]) //形参必须为指针数组
{
 unsigned char i,j;    
 for(i=0;i<4;i++) //有4个字符串要显示
 {
   j=0; //指向待显字符串的第0号元素
 while(*(x[i]+j)!='\0') //只要第i个字符串的第j号元素不是结束标志
   {
      P1=*(x[i]+j); //取得该元素值送到P0口显示
      delay(); //调用延时函数
      j++; //指向下一个元素
   }
   }      
}
/**************************************************************
函数功能:主函数
**************************************************************/ 
 void main(void)
 {
 unsigned char i;
 while(1)
 {
 for(i=0;i<4;i++)
   led_display(p); //将指针数组名作实际参数传递
 }
}

16、用定时器T0查询方式P1口控制8位LED闪烁(不是流水灯)

#include<reg51.h> // 包含51单片机寄存器定义的头文件
/**************************************************************
函数功能:主函数
**************************************************************/
void main(void)
{
 // EA=1; //开总中断
//  ET0=1; //定时器T0中断允许 
 TMOD=0x01; //使用定时器T0的模式1
 TH0=(65536-46083)/256; //定时器T0的高8位赋初值
 TL0=(65536-46083)%256; //定时器T0的高8位赋初值
 TR0=1; //启动定时器T0
 TF0=0;
 P1=0xff;
 while(1)//无限循环等待查询
 {
   while(TF0==0);
   TF0=0;
   P1=~P1;
 TH0=(65536-46083)/256; //定时器T0的高8位赋初值
 TL0=(65536-46083)%256; //定时器T0的高8位赋初值
 }
 }

后续方法慢慢总结。

2014-12-26 11:27:38 songze_lee 阅读数 1256
  • 单片机控制第一个外设-LED-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    3995 人正在学习 去看看 朱有鹏

       51单片机驱动流水灯可以更好的理解IO口,这一节就主要来用查表法和移位法来实现流水灯,首先先看电路图。

        电路比较简单,发光二极管正极接5V电源,负极接470Ω限流电阻,接单片机P0口,限流电阻470Ω怎么计算?来看看,普通发光二极管正向饱和电压为1.6~2.1V,正向饱和电流为5~20mA,但不同颜色的发光二极管参数有所差异。这里没必要精确计算,我们取中间值电压1.8V,电流10mA。由欧姆定律,解得R=(5-1.8)/10=320Ω,图中电阻选用常用的470Ω。

        由电路图可以知道,单片机P0口只需要输出低电平,就可以点亮LED灯。图中采用低电平驱动,主要是P0口低电平驱动能力比较好。

        现在先来看个闪烁灯的程序。

/*********************************************
**程序名称:LED闪烁灯
**程序功能:一个LED闪烁,频率为2HZ
**编写:李松泽
**时间:2014-12-25
**********************************************/
#include <reg52.h>
sbit LED=P0^0;//位定义
#define uchar unsigned char
#define uint unsigned int
/*********************************************
**函数名称:void delay_ms(uint x)
**函数功能:延时xms
**入口参数:uint x
**出口参数:
*********************************************/
void delay_ms(uint x)
{
    uint i,j;
    for(i=x;i>0;i--)
        for(j=110;j>0;j--);
}
/*********************************************
**函数名称:void main()
**函数功能:主函数
**入口参数:
**出口参数:
*********************************************/
void main()
{
    while(1)
    {
        LED=0;//LED亮
        delay_ms(500);
        LED=1;//LED灭
        dealy_ms(500);		
    }
}	 

          这个程序比较简单,但同时也说明了51单片机可以对单个位定义操作,在16位MSP430单片机中就不能单独操作一个位。在程序的编写中就比较方便。       

流水灯程序以下用两种方法,首先先看查表法,部分程序说明在代码中解释。

/*********************************************
**程序名称:驱动流水灯
**程序功能:8个LED依次从左到右,从右到左点亮,频率为500ms
**编写:李松泽
**时间:2014-12-25
**********************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,
             0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//赋给P0口的数据
/*********************************************
**函数名称:void delay_ms(uint x)
**函数功能:延时xms
**入口参数:uint x
**出口参数:
*********************************************/
void delay_ms(uint x)
{
    uint i,j;
    for(i=x;i>0;i--)
        for(j=110;j>0;j--);
}
/*********************************************
**函数名称:void main()
**函数功能:主函数
**入口参数:
**出口参数:
*********************************************/
//查表法:
void main()
{
     while(1)
    {
         uchar i;
	 for(i=0;i<16;i++)
	 {
             P0=tab[i];
             delay_ms(500);
	 }
    }
}


移位法:

/*********************************************
**程序名称:驱动流水灯
**程序功能:8个LED依次从左到右,从右到左点亮,频率为500ms
**编写:李松泽
**时间:2014-12-25
**********************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
/*********************************************
**函数名称:void delay_ms(uint x)
**函数功能:延时xms
**入口参数:uint x
**出口参数:
*********************************************/
void delay_ms(uint x)
{
    uint i,j;
    for(i=x;i>0;i--)
        for(j=110;j>0;j--);
}
/*********************************************
**函数名称:void main()
**函数功能:主函数
**入口参数:
**出口参数:
*********************************************/
//移位法:
void main()
{
    uchar i,j;
    while(1)
    {
        P0=0xfe;
        for(i=0;i<8;i++)
        {
            delay_ms(500);//进入循环,先延时500ms
            P0<<=1; //P0口数据左移
            P0|=0x01; //将低位置1
            }
        P0=0x7f;
        for(i=0;i<8;i++)
        {
            delay_ms(500);//进入循环,先延时500ms
            P0>>=1; //P0口数据左移
            P0|=0x80;//将高位置1	
        }
    }
}



2016-10-25 23:22:56 slu_520 阅读数 636
  • 单片机控制第一个外设-LED-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    3995 人正在学习 去看看 朱有鹏
10.25学习总结
       对周六周日的单片机做一部分的总结,周六大自了解了偱迹小车的一部分原理,偱迹小车有二驱和四驱之分,说白了就是有几个轮子是有驱动能力的,四驱的当然比二驱的跑得快,小车前面还有一个万向轮,可以360度旋转,电机装在车轮上用来驱动小车行走,电机驱动是用H桥组成的,H桥的不同接法可以控制轮子的正转和反转,电机的转速是通过PID算法来调节PWM(占空比)来控制电机的转速。
       在小车的前面还有一个单片机外设:红外对光网。小车的轨道是用一定宽度的黑色胶带铺成的,而红外对光网有五个接口,分别接VCC,GND,单片机I/O端口,还有发信息的和收信息的,我们知道黑色和白色对光有不同的反应,白色会反射所有的光,而黑色会吸收所有的光,利用这个特性,红外对光网一端发出光,根据另一个端口能否接受到信息来判断轨道的位置,在小车前面一般放三个红外对光网,分别检测小车的左方,前方和右方。
接下来进入正题,流水灯,先来说说51单片机的内部资源:
      Flash:程序存储空间,它最大的意义是断电后数据不丢失,类似于电脑的硬盘,我们保存了电影,音乐,文档等文件,把电源关掉后,下次重新打开电脑那些文件还在;
      RAM:数据存储空间 ,用来存储程序运行过程中产生的和需要的数据,和电脑的内存是相似的概念;
      SFR:特殊功能寄存器,单片机有很多功能,每个功能都会对应一个或多个SFR,我们通过对SFR的读写来实现单片机的多种多样的功能;
在写单片机的程序时要加上头文件#include<reg52.h>,因为单片机中有一个关键字sfr,用来定义一个单片机特殊功能寄存器,但keil已经把这些声明写好并保存在一个文件中,所在只要在头文件中声明就可以了,如图,是reg52.h中的内容


最重要的一点是在写单片机的程序时一定要记得加一个死循环,这是因为:
比如一个程序空间有100行代码,而我们只写了50行代码,运行这50行之后还会继续运行51行之后的程序,但是这是不确定的内容,一旦执行可能导致程序出错从而导致单片机自动复位或者程序跑飞,所以要加一个死循环让它停留在50行;下面就是几个关于LED灯的程序










流水灯
2015-12-23 15:25:45 u012963417 阅读数 1534
  • 单片机控制第一个外设-LED-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    3995 人正在学习 去看看 朱有鹏

流水灯实验是第一个实验,比较简单。LED的阳极串联一个电阻,然后连接到电源VCC,而LED的阴极连接到单片机的P2口,如果你想点亮一盏LED就对把单片机相对应的IO赋为低电平。
我总结了两种方法,其实还有更多。
方法一、

#include <reg51.h>
#include <intrins.h> //左移右移函数头文件 
#define GPIO_LED P2 //将P2口另外取名GPIO_LED 
void Delay10ms(unsigned int); //误差0μs 
void main(void)
{
    unsigned char n;
    GPIO_LED=0xfe; //
    while(1)
    {
            for(n=0;n<7;n++)
            {
                GPIO_LED = _crol_(GPIO_LED,1);
                Delay10ms(50);
            }
            for(n=0;n<7;n++)
            {
                GPIO_LED = _cror_(GPIO_LED,1);
                Delay10ms(50);
            }
    }
}
void Delay10ms(unsigned int c) //0~65535
{
    unsigned char a,b;
    for(;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}

方法二、

#include <reg51.h>
#define LED_P P2
void Delay10ms(unsigned int c);   //误差 0us
/*低电平时 LED 灯亮 */
/*从左向右依次点亮一盏LED 灯*/
unsigned char led[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
void main()
{
    unsigned char i=0;
    while(1)
    {
        for(i=0;i<8;i++)
        {
            LED_P = led[i];
            Delay10ms(50);
        }
    }
}

DIY心形流水灯

阅读数 2741

迷你版的心形流水灯

博文 来自: qq_38254960

51单片机内部资源

阅读数 3639

没有更多推荐了,返回首页