2012-10-31 19:48:19 Jcy8126 阅读数 15398
  • 单片机控制第一个外设-LED灯-第1季第6部分

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

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

51单片机之循环移位函数

今天在看书的时候看到了循环移位函数,想跟大家分享下,呵呵,大牛们不要嘲笑,由于本人刚起步,莫笑。

如果你使用keil软件编写C51程序的话,那么你可以打开Keil下的C51下的HLP文件,里面有个C51lib文件,这是个帮助文件。在这个文件里面就有关于移位函数的原型。

之前,如果我想移位的话(做流水灯的程序时),我会 P2 = (P2 << 1) | 1;你会发现后面需要或上一个1,以控制补0带来的麻烦。不过在移位函数中是可以不需要的,它自动补1。

下面来介绍下这俩个移位函数--_crol_与_cror_(包含在头文件intrins.h中)

_crol_:

比如,移位前是:01110110,那么移位后便是11101100。这个意思就是整体左移一位,之后将原本的首位移到最后一位。

_cror_:

比如,移位前是:01110110,那么移位后便是00111011。道理跟上面的相似。

附上一个简单的程序以说明问题:

#include
#include

#define uint unsigned int
#define uchar unsigned char

void delay(uchar);

uchar temp;

void main()
{
    temp = 0xfe;
    while(1)
    {
        P1 = temp;
        delay(100);
        temp = _crol_(temp,1);
    }
}

void delay(uchar time)
{
    uchar i,j;
    for(i = time;i > 0;--i)
        for(j = 110;j > 0;--j);
}


2019-04-21 15:59:54 weixin_44212493 阅读数 402
  • 单片机控制第一个外设-LED灯-第1季第6部分

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

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

功能说明:利用移位函数操作点亮流水灯

在这里插入图片描述
在这里插入图片描述
程序源代码如下:

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define led P0

void delay (void)
{
uchar a,b;
for(a=0;a<200;a++)
for(b=0;b<200;b++);

}
void main(void)
{

   uchar i,k;
	 
while(1)
{
	k = 0xfe;
   for(i=0;i<8;i++) 
	{
	
	 led  = k;
	 delay();
	 k = _crol_(k,1);
	 i=i++;
 }
	 k = 0x7f;
	 for(i=0;i<8;i++)
	 {
	 led = k;
	 delay();
	 k=_cror_(k,1);
	 i=i++;
	 }
}

}

最后附上51单片机+PROTEUS (C语言程序源代码和PROTEUS源文件),需要请自行下载,下载地址 链接:https://pan.baidu.com/s/1j4qNxr0UussdZBakbBauZA 密码:im0g 谢谢

2019-04-01 22:44:03 qq_39383591 阅读数 307
  • 单片机控制第一个外设-LED灯-第1季第6部分

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

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

单片机

_crol_ 字符循环左移
_cror_ 字符循环右移
_irol_ 整数循环左移 
_iror_ 整数循环右移 
_lrol_ 长整数循环左移  
_lror_ 长整数循环右移 

一些寄存器置位

#define GPIOC_CRL 	 	 *(unsigned int*)(GPIOC_BASE+0x00)
#define RCC_APB2ENR 	 *(unsigned int*)(RCC_BASE+0x18)
RCC_APB2ENR |= 1<<4;//第四位置1,其他位保持
GPIOC_CRL &= ~( 0x0F<< (4*0));//第一个引脚4位置零,其他保持
GPIOC_CRL |= (3<<4*0);//将低2位置1
GPIOC_BSRR=(1<<(16+0));//第16位置1

 

2016-09-08 19:57:49 Valieli 阅读数 21665
  • 单片机控制第一个外设-LED灯-第1季第6部分

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

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

让第一个小灯到最后一个依次闪烁,可以用移位来达到目的。

单片机有一个库文件已经写好了移位函数,储存在#include <intrins.h>库文件里。

先看_crol_ 字符循环左移:

 

#include <reg52.h>
#include <intrins.h>

char tmp;
void delay() //延时函数
{
	int i;
	for(i=0;i<8888;i++)
	;
}
void main()
{
	tmp=0xfe;
	P1=tmp; //第一个小灯亮
	while(1)
	{
		tmp=_crol_(tmp,1); //字符左移
		delay();
		P1=tmp; //第二个小灯亮
	}
}
		

运行程序可以看到第一个小灯,第二个小灯...依次闪烁。

 

_cror_ 字符循环右移:

将代码tmp=_crol_(tmp,1);中的crol改成cror.

 

#include <reg52.h>
#include <intrins.h>

char tmp;
void delay() //延时函数
{
	int i;
	for(i=0;i<8888;i++)
	;
}
void main()
{
	tmp=0xfe;
	P1=tmp; 
	while(1)
	{
		tmp=_cror_(tmp,1); //字符右移
		delay();
		P1=tmp; 
	}
}
		


运行程序后,可以看到第一个小灯,第八个小灯,第七个小灯...依次闪烁。

 

扩展:

加上蜂鸣器,蜂鸣器响一下,灯亮一下:

 

//flow light and beep 
#include <reg51.h>
#include <intrins.h>
unsigned char a,b,k,j;
sbit beep=P2^3;
void delay10ms()
{
   for(a=100;a>0;a--)
     for(b=225;b>0;b--);
}
void main()
{
  k=0xfe;
  while(1)
  {
      delay10ms();
      
      beep=0;
      delay10ms();
      beep=1;
      j=_crol_(k,1);
      k=j;
      P1=j;
   }
}

 

♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥

广告时间:

本宝宝开通了一个公众号,记录日常的深度学习和强化学习笔记。希望大家可以共同进步,嘻嘻嘻!爱你呦!
KeepYourAims

 

 

2016-10-18 11:31:18 morixinguan 阅读数 1191
  • 单片机控制第一个外设-LED灯-第1季第6部分

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

    4002 人正在学习 去看看 朱有鹏
#include <stdio.h>
/*
_lrotr()将一个无符号长整形数左循环移位的函数
原形:unsigned long _lrotr(unsigned long value,int count)
功能:将value向左循环移动count位。
返回值:将value向左循环移动count位后的值。
头文件:stdlib.h
*/
unsigned _rotl (unsigned val,int shift)
{
        register unsigned hibit;        /* non-zero means hi bit set */
        register unsigned num = val;    /* number to rotate */
        shift &= 0x1f;                  /* modulo 32 -- this will also make
                                           negative shifts work */
        while (shift--) {
                hibit = num & 0x80000000;  /* get high bit */
                num <<= 1;              /* shift left one bit */
                if (hibit)
                        num |= 1;       /* set lo bit if hi bit was set */
        }
        return num;
}

//这个函数就是将_rotl函数做再次封装
unsigned long _lrotl (unsigned long val,int shift)
{
        return( (unsigned long) _rotl((unsigned) val, shift) );
}
/*
_lrotr()将一个无符号长整形数右循环移位的函数
原形:unsigned long _lrotr(unsigned long value,int count)
功能:将value向右循环移动count位。
返回值:将value向右循环移动count位后的值。
头文件:stdlib.h
*/
unsigned _rotr (unsigned val,int shift)
{
        register unsigned lobit;        /* non-zero means lo bit set */
        register unsigned num = val;    /* number to rotate */

        shift &= 0x1f;                  /* modulo 32 -- this will also make
                                           negative shifts work */
        while (shift--) {
                lobit = num & 1;        /* get high bit */
                num >>= 1;              /* shift right one bit */
                if (lobit)
                        num |= 0x80000000;  /* set hi bit if lo bit was set */
        }
        return num;
}
//对右移函数做再次封装
unsigned long _lrotr (unsigned long val,int shift)
{
        return( (unsigned long) _rotr((unsigned) val, shift) );
}

int main(void)
{
    unsigned long val = 2;
    unsigned long ret = _lrotl(val , 4) ;
    printf("%d\n",ret);
    unsigned long r = _lrotr(ret,4);
    printf("%d\n",r);
    return 0 ;
}
运行结果:32 2
没有更多推荐了,返回首页