51单片机学习笔记 STC89C52RC (02)流水灯

普通发光二极管工作压降为:1.6V~2.1V,工作压降的意思是发光二极管被点亮后,如接入5V电压通过二极管阳极用万用表进行测量阳极,此时电压为3V,二极管工作电流为:1~20m

复制代码
#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char

uchar temp;//LED灯相关变量
//延时函数,ms 毫秒
void delay(uint ms) {
    uint x,y;
    for(x = ms; x > 0; x--) {
        for(y = 114; y > 0; y--);
    }
}

void main() {
// 流水灯 
    temp = 0xfe;
    P1 = temp;
    while(1) {
        temp = _crol_(temp, 1);
        P1 = temp;
        delay(50);
    }
}
复制代码

 

 

下面两个方法属于  头文件 #include <intrins.h> 里面的

字符型循环左移:_crol_

字符型循环右移:_cror_

它与二进制位移符(左移:<<; 右移:>>)的区别

 

// _crol_ 与 _cror_ 的一个例子
unsigned int temp;
temp = 0xFE; // 二进制为 1111 1110,0x为十六进制前缀,前面笔记有写
//_crol_("要位移的变量", "位移几位")
temp = _crol_(temp, 1);// 1111 1110  ->  1111 1101,就像贪吃蛇一样,从左边屏幕进去,从右边出来

 

而左移 << 和 右移 >> 我在之前的笔记里面有写,这里再举个例子

unsigned  int temp;
temp = 0xFE;  // 二进制为 1111 1110
temp = temp << 1;//1111 1110  ->  0001 1111 1100
//而一个 int 在 51 单片机下是 2 个字节,一个字节是8bit,所以它实际的二进制值是 0000 0000 1111 1110  ->  0000 0001 1111 1100,只不过前面的0省略了
//这时可能又有疑问了,那这个靠近左边的头一个 1 一直移动到最左边是不是和上面那个一样呢,当然不是的
temp = 0xFFFF;//此时二进制为 1111 1111 1111 1111,左移一位变成 1111 1111 1111 1110,超过16bit的舍去,右边补0,右移我前面的位运算符有写,这里就不举例了

 

以上就是字符循环 左/右 移和二进制位移符的区别

 

下面这个是单纯用运算符实现流水灯效果的代码

复制代码
#include 

unsigned  int i;

void main() {
// 流水灯
/*
    二               十六
    0000 0001       1  
    0000 0010       2
    0000 0100       4
    0000 1000       8
    0001 0000       10
    0010 0000       20
    0100 0000       40
    1000 0000       80
*/
    unsigned  short j = 0;
    P1 = ~0x1;  // 0x1 的 二进制 0000 0001,取反后为 1111 1110;
    i = 65535;
    while (i--);
    for (;j < 7;j++){
        P1 = ~(~P1 << 1); // 先取反成为二进制的1后进行左移,再取反使其只亮一个灯
        i = 65535;
        while (i--);
    }
}
复制代码

 

posted @   沉默的王さん  阅读(376)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示