流水灯程序总结:关于Crol和cror的用法

本文介绍了一个基于51单片机的流水灯程序实现方法,通过_crol_和_cror_函数实现LED灯从左到右及从右到左的位移效果,并利用延时函数控制闪烁节奏。

流水灯程序总结


#include<reg51.h>

#include<stdio.h>
#include<intrins.h>  //crol和cror函数调用头文件   


#define LoopLed P2  //P2管脚重命名


void sleep(unsigned int a);


void main()
{
unsigned char i;
LoopLed = 0xFE;   //11111110——11111101位移的实现


while(1)
{
for(i = 0; i < 7 ; i++)   
{
LoopLed = _crol_(LoopLed,2);  //从右边到左边
sleep(1000); //延时达到跳闪的效果
}
for(i = 0; i<7; i++)
{
LoopLed = _cror_(LoopLed,2); //从左到右
sleep(500); //ms //延时
}
}
}


void sleep(unsigned int a) //延时程序us
{
   unsigned int b;
   for(;a>0;a--)
    for(b = 200; b > 0; b--);
<think>好的,我现在需要帮用户解决如何使用定时器移位函数crol实现延时1秒的流水灯效果的问题。首先,用户提到了使用定时器1crol函数,而且参考了之前的两个引用内容,里面涉及到了定时器的初始化配置,以及流水灯的控制。 首先,我需要回忆一下51单片机定时器的工作原理。定时器1的工作方式通常有几种,用户提到的引用中提到了定时器0的工作方式1,但用户这里需要用定时器1。工作方式1是16位定时模式,最大计数值是65535。假设用户使用的是12MHz的晶振,那么每个机器周期是1微秒,因为12MHz分频后是1MHz,即每个计数周期1微秒。 用户需要定时1秒,但定时器1在方式1下最大只能定时约65.535毫秒(65535微秒)。因此,必须采用中断的方式,多次累积中断次数。比如,如果定时器每次定时1毫秒,那么中断1000次就是1秒。这用户提到的引用1中的思路一致,即初值设置为1ms,然后在中断服务函数中计数到1000次。 接下来,需要配置定时器1的工作方式。根据引用2中的TMOD寄存器设置,定时器1的方式1需要设置M1M0为01,但因为TMOD的高四位控制定时器1,低四位控制定时器0,所以需要将TMOD的高四位设置为0001,即TMOD = 0x10。同时,C/T位设为0表示定时器模式,GATE设为0表示不受外部控制。 然后计算定时器1的初值。假设12MHz晶振,1毫秒需要计数1000次,每个计数1微秒,所以初值为65536 - 1000 = 64536,转换成十六进制是0xFC18。因此,TH1 = 0xFC,TL1 = 0x18。 接下来需要编写中断服务函数。在函数中,每次中断发生,重置定时器初值,然后增加一个计数变量count。当count达到1000时,说明1秒到了,这时候改变流水灯的方向或者移位。 关于流水灯的实现,用户提到使用crol函数,这是C51库中的循环左移函数,需要包含intrins.h头文件。初始时,P1口设置为0xFE(即11111110),然后每次移位一次。当到达最右边后,切换方向,改为循环右移cror,或者反过来。 但用户的问题可能只需要单向流动,但题目中提到需要先从左到右,再从右到左,所以需要判断方向。每次1秒后改变方向。比如,定义一个变量direction,当count达到1000时,切换direction的值,然后根据direction选择左移或右移。 需要注意的是,流水灯的移动是通过改变P1口的输出值来实现的。每次定时到1秒时,执行一次移位,然后更新P1的值。而移位函数crolcror的参数是当前的值移位的位数,比如crol(P1, 1)将当前P1的值循环左移一位。 可能还需要处理当移动到最左边或最右边时的情况,比如当P1为0x7F(01111111)时,下一次左移会变成0xFE?或者可能需要使用不同的初始值。或者,可能需要使用循环移位,这样当灯移动到最右边后,继续循环到左边。 另外,需要确保定时器中断的开启,即ET1=1EA=1,以及启动定时器TR1=1。 总结步骤: 1. 初始化定时器1为方式1,设置初值为1ms。 2. 开启定时器中断全局中断。 3. 在中断服务函数中累计次数,达到1000次时,执行移位操作。 4. 使用crolcror函数改变P1口的状态,实现流水灯效果。 5. 处理方向切换,每隔1秒改变移位方向。 需要检查代码是否正确配置了TMOD,是否正确处理了中断服务函数的重装初值,以及移位函数的正确使用。此外,流水灯的初始状态移位方向切换逻辑也需要正确实现。</think>### 使用定时器`crol`函数实现1秒延时流水灯的方法 以下是基于51单片机的实现步骤(以定时器1循环左移函数`crol`为例): --- #### **1. 定时器1初始化** **目标**:定时1ms,通过中断累积达到1s。 **计算初值**(假设晶振频率为12MHz): - 每个机器周期为$1\mu s$,定时1ms需计数1000次。 - 初值为: $$TH1 = (65536 - 1000) / 256 = 0xFC$$ $$TL1 = (65536 - 1000) \% 256 = 0x18$$ **配置寄存器**: - `TMOD`:设置定时器1为模式1(16位定时器),即`TMOD |= 0x10`[^2]。 - `TCON`:启动定时器1,即`TR1 = 1`。 - 允许定时器1中断:`ET1 = 1; EA = 1;` --- #### **2. 中断服务函数设计** 在中断中累积计数,每1000次(即1秒)触发流水灯移位: ```c unsigned int count = 0; bit direction = 0; // 方向标志:0表示左移,1表示右移 void Timer1_ISR() interrupt 3 { TH1 = 0xFC; // 重装初值 TL1 = 0x18; count++; if (count >= 1000) { // 达到1秒 count = 0; if (!direction) { P1 = _crol_(P1, 1); // 左移一位 if (P1 == 0x7F) direction = 1; // 到达最左端后切换方向 } else { P1 = _cror_(P1, 1); // 右移一位 if (P1 == 0xFE) direction = 0; // 到达最右端后切换方向 } } } ``` --- #### **3. 主函数流水灯初始化** ```c #include <reg52.h> #include <intrins.h> // 包含_crol_函数 void main() { TMOD = 0x10; // 定时器1模式1 TH1 = 0xFC; // 1ms初值 TL1 = 0x18; TR1 = 1; // 启动定时器1 ET1 = 1; // 允许定时器1中断 EA = 1; // 全局中断使能 P1 = 0xFE; // 初始状态:第一个LED亮(二进制11111110) while(1); // 主循环等待中断 } ``` --- #### **关键点说明** - **定时器配置**:定时器1的初值需根据晶振频率调整,若为11.0592MHz,需重新计算。 - **方向切换**:通过`direction`标志`if`条件判断实现双向流动。 - **移位函数**:`_crol_``_cror_`是C51标准库函数,需包含`intrins.h`[^2]。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值