/* * T1_T2_T3_2023_1.c * * Created: 2023/5/30 22:49:53 * Author : XY */ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> void device_init(void) { DDRD |= 0xf0; PORTD &= 0x0f; DDRB |= (_BV(PB4)|_BV(PB6)); DDRE |= _BV(PE7); } void timer1_init(void) { TCCR1B = 0x00; //stop OCR1AH = 0x3D; //TOP of T1 OCR1AL = 0x08; OCR1BH = 0x3D; OCR1BL = 0x08; TCCR1A = 0x10; TCCR1C = 0x00; TCCR1B = 0x0B; //start Timer } void timer2_init(void) { TCCR2B = 0x00; //stop ASSR = 0x20; //set async mode OCR2A = 0x80; TCCR2A = 0x42; TCCR2B = 0x06; //start } void timer3_init(void) { TCCR3B = 0x00; //stop OCR3AH = 0x3D; OCR3AL = 0x08; TCCR3A = 0x00; TCCR3C = 0x00; TCCR3B = 0x0B; //start Timer } ISR(TIMER3_COMPA_vect) { PORTE ^= _BV(PE7); } int main(void) { device_init(); timer1_init(); timer2_init(); timer3_init(); TIMSK3 = 0x02; sei(); while (1) { SMCR |= (0x00<<SM0); sleep_mode(); } } 根据程序中 T1、T2、T3 的配置参数(包括工作模式、分频系数、初值),通过更改SMCR |= (0x00<<SM0)为SMCR |= (0x03<<SM0)和SMCR |= (0x02<<SM0)来分析三个定时器驱动 LED 灯的方式有何区别
时间: 2024-03-18 15:46:03 浏览: 46
根据程序中的配置参数,T1、T2、T3 都是以 CTC 模式工作,且都设置了比较匹配 A 和 B 通道的输出比较值,其中 T1 和 T3 的初值相同,而 T2 的初值为0。分频系数分别是 T1:1/64,T2:1/256,T3:1/64。
通过更改 SMCR 中的 SM0 位可以改变进入睡眠模式时 MCU 的振荡源选择,其中 0x00 表示使用主时钟源,0x02 表示使用外部晶振,0x03 表示使用时钟输出 CKO,即使用 T1 的比较匹配 A 通道的输出信号作为振荡信号。
当 SMCR |= (0x00<<SM0) 时,MCU 进入睡眠模式后,T1 和 T3 的比较匹配 A 通道的输出信号作为振荡信号,而 T2 的比较匹配 A 通道的输出信号被忽略。因此,LED 灯的驱动方式是 T1 和 T3 交替驱动,T2 无效。
当 SMCR |= (0x03<<SM0) 时,MCU 进入睡眠模式后,使用外部晶振作为振荡源,T1、T2、T3 的比较匹配 A 通道的输出信号都被忽略,LED 灯不会亮起。
当 SMCR |= (0x02<<SM0) 时,MCU 进入睡眠模式后,使用 T1 的比较匹配 A 通道的输出信号作为振荡信号,LED 灯的驱动方式是 T1 驱动,T2 和 T3 无效。
相关问题
阅读下列程序,完成填空。 // //////////////////////////////////////////////////////// // 简介: // 通过接口Runnable构造线程的例程。 // //////////////////////////////////////////////////////// /**********FILL**********/ public class J_ThreadRunnable implements ___________{ private int m_threadID; public J_ThreadRunnable(int i) { m_threadID=i; System.out.println("创建线程: " + i ); } // J_ThreadRunnable构造方法结束 /**********FILL**********/ public ____________( ) { for(int i=0; i<2; i++) { System.out.println("运行线程: " + m_threadID); try { Thread.sleep((int)(Math.random( ) * 1000)); } catch (InterruptedException e ){ System.err.println("异常InterruptedException: " + e); e.printStackTrace( ); } // try-catch结构结束 } // for循环结束 } // 方法run结束 public static void main( String args[ ] ){ Thread t1= new Thread(new J_ThreadRunnable(1)); Thread t2= new Thread(new J_ThreadRunnable(2)); /**********FILL**********/ ________ ; /**********FILL**********/ ________ ; System.out.println("方法main结束"); } // 方法main结束 } // 类J_ThreadRunnable结束
第一空应填写Runnable,第二空应填写run方法,第三空应该是t1.start(),第四空应该是t2.start()。修正后的代码如下:
```
public class J_ThreadRunnable implements Runnable {
private int m_threadID;
public J_ThreadRunnable(int i) {
m_threadID=i;
System.out.println("创建线程: " + i );
}
public void run() {
for(int i=0; i<2; i++) {
System.out.println("运行线程: " + m_threadID);
try {
Thread.sleep((int)(Math.random() * 1000));
} catch (InterruptedException e) {
System.err.println("异常InterruptedException: " + e);
e.printStackTrace();
}
}
}
public static void main(String args[]) {
Thread t1 = new Thread(new J_ThreadRunnable(1));
Thread t2 = new Thread(new J_ThreadRunnable(2));
t1.start();
t2.start();
System.out.println("方法main结束");
}
}
```
/* * T1_T2_T3_2023_1.c * * Created: 2023/5/30 22:49:53 * Author : XY */ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> void device_init(void) { DDRD |= 0xf0; PORTD &= 0x0f; DDRB |= (_BV(PB4)|_BV(PB6)); DDRE |= _BV(PE7); } void timer1_init(void) { TCCR1B = 0x00; //stop OCR1AH = 0x3D; //TOP of T1 OCR1AL = 0x08; OCR1BH = 0x3D; OCR1BL = 0x08; TCCR1A = 0x10; TCCR1C = 0x00; TCCR1B = 0x0B; //start Timer } void timer2_init(void) { TCCR2B = 0x00; //stop ASSR = 0x20; //set async mode OCR2A = 0x80; TCCR2A = 0x42; TCCR2B = 0x06; //start } void timer3_init(void) { TCCR3B = 0x00; //stop OCR3AH = 0x3D; OCR3AL = 0x08; TCCR3A = 0x00; TCCR3C = 0x00; TCCR3B = 0x0B; //start Timer } ISR(TIMER3_COMPA_vect) { PORTE ^= _BV(PE7); } int main(void) { device_init(); timer1_init(); timer2_init(); timer3_init(); TIMSK3 = 0x02; sei(); while (1) { SMCR |= (0x00<<SM0); sleep_mode(); } }在SMCR |= (0x00<<SM0),SMCR |= (0x00<<SM0),SMCR |= (0x02<<SM0)三种情况下的运行结果
在 SMCR |= (0x00<<SM0)的情况下,MCU 进入 Power-save 模式,此时所有定时器正常工作,LED 灯的亮灭由程序控制。由于程序中没有设定 LED 灯的状态,因此 LED 灯可能会一直亮着或熄灭,具体状态不确定。
在 SMCR |= (0x00<<SM0)的情况下,MCU 仍然进入 Power-save 模式,定时器 T1 和 T3 仍然正常工作,LED 灯的亮灭由定时器控制。定时器 T2 停止工作,LED 灯将保持上一次的状态。由于程序中没有设定 LED 灯的初始状态,因此 LED 灯可能会一直亮着或熄灭,具体状态不确定。
在 SMCR |= (0x02<<SM0)的情况下,MCU 进入 Idle 模式,定时器 T1 和 T3 仍然正常工作,LED 灯的亮灭由定时器控制。定时器 T2 停止工作,LED 灯将保持上一次的状态。由于 MCU 进入 Idle 模式,处理器将停止工作,直到下一个中断出现。因此程序中的 while(1) 循环将不再执行,程序将停留在 sleep_mode() 语句处,直到下一个中断出现。在该模式下,MCU 的功耗比 Power-save 模式低,但是定时器 T2 停止工作,可能会影响系统的实时性能。
阅读全文