Commit c0d51e9b authored by Oleg Nikulin's avatar Oleg Nikulin

Повышение частоты ШИМ (до ~15 кГц) через изменение параметров таймеров. Две…

Повышение частоты ШИМ (до ~15 кГц) через изменение параметров таймеров. Две тестовые прошивки с повышенной частотой
parent e254348a
#include <Wire.h>
struct fan { //Данные о вентиляторе
int pin; //Номер пина тахометра
bool type; //Тип датчика. 0 = униполярный, 1 = биполярный
volatile bool state; //Состояние тахометра
volatile uint16_t revs; //Количество оборотов (просто, не в минуту)
uint16_t rpm[5]; //Обороты в минуту
};
fan fans[6] = {
{
14,
1,
0,
0,
0
},
{
15,
1,
0,
0,
0
},
{
16,
1,
0,
0,
0
},
{
17,
1,
0,
0,
0
},
{
18,
1,
0,
0,
0
},
{
19,
1,
0,
0,
0
}
};
ISR(TIMER2_COMPA_vect) { //Функция, вызываемая при прерывании 2A
PORTD |= 0b01000000; //вкл питание на пине 6
for (int i = 2; i < 2; i++) { //проверка тахометров 0-1
bool currentState = (PINC >> (fans[i].pin - 14)) & 0x01;
if (currentState == 0 && fans[i].state == 0) { //сигнал тахометра появился
fans[i].state = 1;
//digitalWrite(13, 1);
}
else if (currentState == 1 && fans[i].state == 1) { //сигнал тахометра пропал
//digitalWrite(13, 0);
fans[i].state = 0;
fans[i].revs++; //засчитывается оборот
}
}
}
ISR(TIMER2_COMPB_vect) { //Функция, вызываемая при прерывании 2B
PORTD &= 0b10111111; //выкл питание на пине 6
}
ISR(TIMER1_COMPA_vect) { //Функция, вызываемая при прерывании 1A
PORTD &= 0b11110111; //выкл питание на пине 3
}
ISR(TIMER1_COMPB_vect) { //Функция, вызываемая при прерывании 1B
PORTD &= 0b11011111; //выкл питание на пине 5
}
ISR(TIMER1_OVF_vect) { //Функция, вызываемая при переполнении таймера 1
PORTD |= 0b00100000; //вкл питание на пине 5
PORTD |= 0b00001000; //вкл питание на пине 3
for (int i = 2; i < 6; i++) { //проверка тахометров 2-5
bool currentState = (PINC >> (fans[i].pin - 14)) & 0x01;
if (currentState == 0 && fans[i].state == 0) { //сигнал тахометра появился
fans[i].state = 1;
//digitalWrite(13, 1);
}
else if (currentState == 1 && fans[i].state == 1) { //сигнал тахометра пропал
//digitalWrite(13, 0);
fans[i].state = 0;
fans[i].revs++; //засчитывается оборот
}
}
}
void setup() {
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
for (int i = 0; i < 6; i++) {
pinMode(fans[i].pin, INPUT_PULLUP);
}
//Таймеры 0 и 2 - 8 бит, таймер 1 - 16 бит
//Таймер 1 сравнение A - пин 3
//Таймер 1 сравнение B - пин 5
//Таймер 2 сравнение B - пин 6
TCCR2A = 0;
TCCR2B = 0;
//Режим CTC для таймера 2
//TCCR2B |= (1 << WGM22);
TCCR2A |= (1 << WGM21);
//TCCR2A |= (1 << WGM20);
TIMSK2 |= (1 << OCIE2A); //вкл. вызов прерывания таймера 2 по сравнению A
TIMSK2 |= (1 << OCIE2B); //вкл. вызов прерывания таймера 2 по сравнению B
//TIMSK2 |= (1 << TOIE2); //вкл. вызов прерывания при переполнении таймера 2
//Деление частоты на 8 для таймера 2
//TCCR2B |= (1 << CS20);
TCCR2B |= (1 << CS21);
//TCCR2B |= (1 << CS22);
OCR2A = 127; //Верхняя граница счетчика таймера 2
OCR2B = 64; //Значение для сравнения 2B (скважность пина 6)
TCCR1A = 0;
TCCR1B = 0;
//Режим CTC (ICR1) для таймера 1
TCCR1A |= (1 << WGM11);
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << WGM13);
TIMSK1 |= (1 << OCIE1A); //вкл. вызов прерывания таймера 1 по сравнению A
TIMSK1 |= (1 << OCIE1B); //вкл. вызов прерывания таймера 1 по сравнению B
TIMSK1 |= (1 << TOIE1); //вкл. вызов прерывания при переполнении таймера 1
//Деление частоты на 8 для таймера 1
TCCR1B |= (1 << CS11);
ICR1 = 127; //Верхняя граница счетчика таймера 1
OCR1A = 100; //Значение для сравнения 1A (скважность пина 3)
OCR1B = 5; //Значение для сравнения 2A (скважность пина 5)
}
uint32_t a = 0;
bool b = 0;
void loop() {
if (uint32_t(millis() - a) >= 500) {
a = millis();
b = !b;
digitalWrite(13, b);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment