выключите таймер 1
Кроссовер нулевого детектора посылает импульс в arduino, он должен начать отсчет времени x, а затем импульс посылается от arduino, как только таймер достигает времени x, он должен прекратить отсчет и только начать отсчет снова, пока не получит новый импульс детектора пересечения нуля, идея состоит в том, чтобы сделать что-то вроде этого
чего я не знаю так это как держать таймер выключенным все время тофф который появляется на изображении
@edwin vargas, 👍1
Обсуждение2 ответа
способ выключить таймер состоит в том, чтобы установить биты предварительной шкалы CS12, CS11 и CS10 на 0, таким образом сигнал CLK отключается, и таймер прекращает отсчет, когда вы хотите, чтобы таймер продолжал отсчет, они снова устанавливаются на 1 биты предварительной шкалы CS12, CS11 и CS10 в соответствии с выбранным предустановленным значением.
Вы можете инициировать таймер" Один выстрел " при каждом пересечении нуля.
Трюк @Gerben, упомянутый в turn off Timer1 / Timer1 One-shot, в конечном итоге ссылается на код по адресу https://github.com/bigjosh/TimerShot который выполняет функцию одноразового выстрела на Timer2 путем холостого хода таймера при TCNT2=0 с OCR2A=0 и использования пространства TCNT2 выше 0 для управления регулируемым oneshot на OC2B.
Этот трюк можно адаптировать к Timer1:
// The one shot pulses are output on Digital pin OC1B (Arduino Uno D10, Mega D12, Nano D3)
// Modified by Dave Forrest 2020-01-11 for Timer 1
// Based on Josh Levine's Nov 23, 2015 work at https://github.com/bigjosh/TimerShot/blob/master/TimerShot.ino
#define OSP_SET_WIDTH(cycles) (OCR1B = 0xffff-(cycles-1))
// Setup the one-shot pulse generator and initialize with a pulse width that is (cycles) clock counts long
void osp_setup(uint16_t cycles) {
TCCR1B = 0; // Halt counter by setting clock select bits to 0 (No clock source).
// This keeps anything from happeneing while we get set up
TCNT1 = 0x00; // Start counting at bottom.
OCR1A = 0; // Set TOP to 0. This effectively keeps us from counting because the counter just keeps reseting back to 0.
// We break out of this by manually setting the TCNT higher than 0, in which case it will count all the way up to MAX and then overflow back to 0 and get locked up again.
OSP_SET_WIDTH(cycles); // This also makes new OCR values get loaded from the buffer on every clock cycle.
TCCR1A = 0b11<<COM1B0 | 0b11<<WGM10; // OC1B=Set on Match, clear on BOTTOM. Mode 15 Fast PWM.
TCCR1B = (0b11<<WGM12)| (0b001<<CS10); // Start counting now. WGM 15=0b1111 to select Fast PWM mode
//DDRB |= _BV(2); // Set pin to output (Note that OC1B = GPIO port PB2 = Arduino Uno Digital Pin 10)
DDRB |= _BV(6); // Set pin to output (Note that OC1B = GPIO port PB6 = Arduino Mega Digital Pin 12)
//DDRD |= _BV(3); // Set pin to output (Note that OC1B = GPIO port PD3 = Arduino Nano Digital Pin 3)
}
// Setup the one-shot pulse generator
void osp_setup() {
osp_setup(1);
}
// Fire a one-shot pulse. Use the most recently set width.
#define OSP_FIRE() (TCNT1 = OCR1B - 1)
// Test there is currently a pulse still in progress
#define OSP_INPROGRESS() (TCNT1>0)
// Fire a one-shot pulse with the specified width.
// Order of operations in calculating m must avoid overflow of the uint16_t.
// TCNT2 starts one count lower than the match value becuase the chip will block any compare on the cycle after setting a TCNT.
#define OSP_SET_AND_FIRE(cycles) {uint16_t m=0xffff-(cycles-1); OCR1B=m;TCNT1 =m-1;}
void setup()
{
osp_setup();
}
void loop()
{
// Step though 0-11 cycle long pulses for demo purposes
for (uint8_t o = 0; o < 101; o++) {
OSP_SET_AND_FIRE(o);
while (OSP_INPROGRESS()); // This just shows how you would wait if necessary - not necessary in this application.
//_delay_us(1); // Wait to let the audience clap
}
}
Этот код производил импульсы с разрешением 62,5 нс, что находится на грани того, что может измерить мое тестовое оборудование. Вот 6,25 доллара, 100-тактный импульс рядом с 1-тактным импульсом:
С 16-битным диапазоном Timer1 и прескалером /1 вы можете делать импульсы от 62,5 нс до 4us. С прескалером /1024, (TCR1B|=(0b101 <<CS10);
) он может выполнять 64us до 4.194 сек. С прескалером /256, (TCR1B|=(0b100 <<CS10);
) он может делать 16us до 1,05 сек.
Для одного выстрела, срабатывающего при пересечении нуля, вы можете попробовать что-то вроде этого с приведенным выше
void loop()
{
...
int t1_us = 1000000UL/60 /8 ; // 1/8 цикла 60 Гц
if(needOneShot){ // Установить needOneShot с прерыванием, датчиком или чем-то еще
OSP_SET_AND_FIRE(t1_us/16); // 16us тики с /256 прескалером
needOneShot = false;
}
...
}
- Использование millis() и micros() внутри процедуры прерывания
- Как сделать очень долгую функцию delay(), несколько часов
- Разница между «time_t» и «DateTime»
- Получение BPM из данного кода
- Как считать время в секундах?
- Создание таймера с использованием часов реального времени с указанием времени начала и остановки
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Использование TIMER0_COMPB_vect
*Кроссовер с нулевым детектором посылает импульс на arduino*... Как ваш код и проводка теперь обнаруживают нулевое пересечение? Является ли детектор внешним и просто посылает сигнал в Arduino? Разве вы не сбросили бы таймер каждый раз, когда обнаруживали переход на положительный? Или детектор не проводит различия между положительным пересечением и отрицательным? Или вы действительно хотите знать, как выполнить перекрестное обнаружение для синусоидального сигнала?, @lurker
@lurker то, что я получаю от детектора пересечения нуля, - это последовательность импульсов, которая изменяется от 0 до 5 В каждый раз, когда она проходит через ноль, но дело не в этом, создайте ребро ISR, когда сигнал меняется, в это время он должен начать отсчет, остановиться, когда он достигнет времени x, которое мне нужно, и оставаться выключенным до следующего нулевого ребра, в примерах, которые я видел, таймер перезапускается и продолжает отсчет, мне нужно, чтобы он выключился или прекратил отсчет до следующего пересечения нуля, @edwin vargas
Это ответ на ваш вопрос? Управление регулятором вентилятора от Arduino, @Juraj
Вы можете обмануть таймер, сделав один выстрел, установив счетчик на значение выше ВЕРХНЕГО. См. https://hackaday.com/2015/03/24/avr-hardware-timer-tricked-into-one-shot/, @Gerben