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--); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现