利用Mega16的T/C1,设计直流电机驱动信号—相位可调的PWM波,驱动直流电机工作。功能要求: 采用4MHz的系统时钟作为T/C1的计数脉冲源,驱动电机的PWM信号的频率是8KHz,通过调整该驱动信号的占空比实现直流电机速度的调整。 在外部中断——INT0引脚接按键,通过一个按键,控制电机4档速度的切换(其中有一档电机基本停止)。根据上面完成下面代码利用Mega16的T/C1,设计直流电机驱动信号—相位可调的PWM波,驱动直流电机工作。功能要求: 采用4MHz的系统时钟作为T/C1的计数脉冲源,驱动电机的PWM信号的频率是8KHz,通过调整该驱动信号的占空比实现直流电机速度的调整。 在外部中断——INT0引脚接按键,通过一个按键,控制电机4档速度的切换(其中有一档电机基本停止)。
时间: 2023-06-16 20:03:18 浏览: 110
直流电机的PWM速度控制
5星 · 资源好评率100%
下面是基于Mega16的T/C1的直流电机驱动信号的设计代码:
```c
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 4000000UL
#include <util/delay.h>
volatile uint8_t speed = 0; // 电机速度
volatile uint8_t phase = 0; // PWM相位
volatile uint8_t step = 0; // 速度档位
void setup_timer1() {
// 设置T/C1的计数脉冲源为系统时钟,分频系数为8
TCCR1B |= (1 << CS11);
// 设置PWM波的频率为8KHz,相位可调
TCCR1A |= (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11);
TCCR1B |= (1 << WGM13) | (1 << WGM12);
ICR1 = 249; // TOP值,频率为8KHz
OCR1A = OCR1B = 0; // 占空比为0
}
void setup_interrupt0() {
// 设置INT0引脚为下降沿触发
MCUCR |= (1 << ISC01);
MCUCR &= ~(1 << ISC00);
// 开启INT0中断
GICR |= (1 << INT0);
}
ISR(TIMER1_COMPA_vect) {
// 相位加1
phase++;
}
ISR(TIMER1_COMPB_vect) {
// 相位加1
phase++;
}
ISR(INT0_vect) {
// 切换速度档位
step = (step + 1) % 4;
switch (step) {
case 0: // 停止
OCR1A = OCR1B = 0;
break;
case 1: // 25%
OCR1A = OCR1B = 62;
break;
case 2: // 50%
OCR1A = OCR1B = 124;
break;
case 3: // 75%
OCR1A = OCR1B = 186;
break;
}
}
int main() {
// 配置PWM输出引脚为输出模式
DDRB |= (1 << PB1) | (1 << PB2);
// 设置PWM引脚为非反相输出模式
TCCR1A &= ~(1 << COM1A0) & ~(1 << COM1B0);
// 设置PWM引脚为输出模式
TCCR1A |= (1 << COM1A1) | (1 << COM1B1);
// 设置PWM引脚的初始占空比为0
OCR1A = OCR1B = 0;
// 开启定时器1的比较匹配中断
TIMSK |= (1 << OCIE1A) | (1 << OCIE1B);
// 设置相位为0
phase = 0;
// 初始化定时器1
setup_timer1();
// 初始化外部中断INT0
setup_interrupt0();
// 全局中断使能
sei();
// 无限循环
while (1) {
_delay_ms(100);
}
return 0;
}
```
在上述代码中,我们使用了定时器1的比较匹配中断和外部中断INT0来实现直流电机的驱动信号。定时器1以4MHz的系统时钟作为计数脉冲源,分频系数为8,从而产生8KHz的PWM波。我们通过调整该PWM波的占空比来实现直流电机速度的调整。在外部中断INT0中,我们通过一个按键来控制电机4档速度的切换。根据按键状态,我们切换速度档位并设置PWM引脚的占空比,从而实现直流电机速度的调整。
阅读全文