После создания блока FLprog код перестает работать
Добавлено: 30 апр 2025, 12:48
Добрый день. написал код для управления Шим, самостоятельно через IDE работает прекрасно, решил создать блок и тут тупик Может кто подскажет? или свежи взгляд ,,, СПАСИБО
Рабочий код...
Код из блока Flprog компилируется но не работает нет сигналов..
Рабочий код...
Код: Выделить всё
/*==============================================================================
DECLARE SECTION
==============================================================================*/
#include <avr/interrupt.h>
// ===== НАСТРОЙКИ =====
const int pinT1 = 9; // 9 (OC1A) или 10 (OC1B)
const int pinT2 = 3; // 3 (OC2B) или 11 (OC2A)
volatile float Per = 50.0; // Начальная частота [Гц]
volatile float pulseT1 = 2.5; // Начальная длительность T1 [мс]
volatile float pulseT2 = 10.2;// Начальная длительность T2 [мс]
volatile float phaseShift = -1.3; // Начальный сдвиг фазы [мс]
// ===== СЛУЖЕБНЫЕ ПЕРЕМЕННЫЕ =====
volatile bool isT2Active = false;
volatile uint16_t icr1_value, ocr1_value, ocr2_start, ocr2_pulse;
volatile uint8_t prescaler1, prescaler2_start, prescaler2_pulse;
bool use_OC1A = false;
bool use_OC2A = false;
// ===== ПРОТОТИПЫ ФУНКЦИЙ =====
bool validateParameters();
void configureTimers();
void setTimer1Prescaler(float period_us);
void setTimer1Registers();
uint16_t calculateTimer2(float ms, uint8_t* prescaler);
void handleT1Interrupt();
uint16_t scalerValueTimer1(uint8_t prescaler);
void updateParameters(float newPer, float newPulseT1, float newPulseT2, float newPhaseShift);
void updatePer(float newPer);
void updatePulses(float newPulseT1, float newPulseT2);
void updatePhaseShift(float newPhaseShift);
/*==============================================================================
SETUP SECTION
==============================================================================*/
void setup() {
use_OC1A = (pinT1 == 9);
use_OC2A = (pinT2 == 11);
pinMode(pinT1, OUTPUT);
pinMode(pinT2, OUTPUT);
if (!validateParameters()) while(1); // Блокировка при ошибке
configureTimers();
sei(); // Разрешение прерываний
}
/*==============================================================================
FUNCTION SECTION
==============================================================================*/
bool validateParameters() {
float period_ms = 1000.0 / Per;
return !(
(pinT1 != 9 && pinT1 != 10) ||
(pinT2 != 3 && pinT2 != 11) ||
(Per < 0.2 || Per > 1000.0) || // Диапазон частот
(pulseT1 < 0.1 || pulseT2 < 0.1) || // Минимальная длительность
(pulseT1 >= period_ms) || // T1 не должен заполнять весь период
(pulseT1 + phaseShift + pulseT2 >= period_ms) // Наложение сигналов
);
}
void configureTimers() {
float period_us = 1e6 / Per;
// Настройка Timer1 (16-битный)
TCCR1A = TCCR1B = 0;
setTimer1Prescaler(period_us);
setTimer1Registers();
// Настройка Timer2 (8-битный)
TCCR2A = (use_OC2A) ? (1 << COM2A1) : (1 << COM2B1); // Режим сравнения
TCCR2B = 0; // Предделитель пока выключен
// Расчет параметров для Timer2
float startTime = pulseT1 + phaseShift;
ocr2_start = calculateTimer2(fabs(startTime), &prescaler2_start);
ocr2_pulse = calculateTimer2(pulseT2, &prescaler2_pulse);
// Настройка прерываний Timer1
TIMSK1 = (1 << TOIE1) | ((phaseShift >= 0) ?
(use_OC1A ? (1 << OCIE1A) : (1 << OCIE1B)) : 0);
}
void setTimer1Prescaler(float period_us) {
const float scalers[] = {1.0, 8.0, 64.0, 256.0, 1024.0};
for(int i = 4; i >= 0; i--) {
icr1_value = (period_us * 16.0 / scalers[i]) - 1;
if(icr1_value <= 65535) {
prescaler1 = (i == 4) ? 0x05 : (i == 3) ? 0x04 :
(i == 2) ? 0x03 : (i == 1) ? 0x02 : 0x01;
return;
}
}
icr1_value = 65535; // Максимальное значение при ошибке
}
void setTimer1Registers() {
TCCR1A = (1 << WGM11); // Fast PWM (ICR1)
TCCR1B = (1 << WGM13) | (1 << WGM12) | prescaler1;
// Расчет OCR1
float ticks = (pulseT1 * 1000.0 * 16.0) / scalerValueTimer1(prescaler1);
ocr1_value = constrain(ticks - 1, 1, icr1_value);
// Настройка вывода
TCCR1A &= ~((1 << COM1A1) | (1 << COM1B1));
if(use_OC1A) {
TCCR1A |= (1 << COM1A1); // Неинверсный режим
OCR1A = ocr1_value;
} else {
TCCR1A |= (1 << COM1B1);
OCR1B = ocr1_value;
}
ICR1 = icr1_value; // Установка периода
}
uint16_t calculateTimer2(float ms, uint8_t* prescaler) {
const float scalers[] = {1.0, 8.0, 32.0, 64.0, 128.0, 256.0};
float target_ticks = ms * 1000.0 * 16.0;
for(uint8_t i = 0; i < 6; i++) {
float val = target_ticks / scalers[i];
if(val <= 256.0) {
*prescaler = (i == 0) ? 0x01 : (i == 1) ? 0x02 :
(i == 2) ? 0x03 : (i == 3) ? 0x04 :
(i == 4) ? 0x05 : 0x07;
return val - 1;
}
}
return 255; // Максимальное значение
}
uint16_t scalerValueTimer1(uint8_t prescaler) {
switch(prescaler) {
case 0x01: return 1;
case 0x02: return 8;
case 0x03: return 64;
case 0x04: return 256;
case 0x05: return 1024;
default: return 1;
}
}
void updateParameters(float newPer, float newPulseT1, float newPulseT2, float newPhaseShift) {
cli();
float oldParams[4] = {Per, pulseT1, pulseT2, phaseShift};
Per = newPer;
pulseT1 = newPulseT1;
pulseT2 = newPulseT2;
phaseShift = newPhaseShift;
if(!validateParameters()) { // Откат при ошибке
Per = oldParams[0];
pulseT1 = oldParams[1];
pulseT2 = oldParams[2];
phaseShift = oldParams[3];
} else {
configureTimers();
}
sei();
}
void updatePer(float newPer) {
float newPulseT1 = (pulseT1 * Per) / newPer; // Сохранение скважности
updateParameters(newPer, newPulseT1, pulseT2, phaseShift);
}
void updatePulses(float newPulseT1, float newPulseT2) {
updateParameters(Per, newPulseT1, newPulseT2, phaseShift);
}
void updatePhaseShift(float newPhaseShift) {
cli();
while(isT2Active); // Ожидание завершения импульса T2
updateParameters(Per, pulseT1, pulseT2, newPhaseShift);
}
/*==============================================================================
INTERRUPT SECTION
==============================================================================*/
ISR(TIMER1_COMPA_vect) {
if(phaseShift >= 0 && use_OC1A) handleT1Interrupt();
}
ISR(TIMER1_COMPB_vect) {
if(phaseShift >= 0 && !use_OC1A) handleT1Interrupt();
}
ISR(TIMER1_OVF_vect) {
if(phaseShift < 0) handleT1Interrupt();
}
void handleT1Interrupt() {
TCNT2 = 0; // Сброс счетчика Timer2
OCR2A = ocr2_start;
TCCR2B = prescaler2_start; // Запуск Timer2
TIMSK2 |= (1 << OCIE2A); // Разрешение прерывания
}
ISR(TIMER2_COMPA_vect) {
if(!isT2Active) {
digitalWrite(pinT2, HIGH); // Начало импульса
OCR2A = ocr2_pulse;
TCCR2B = prescaler2_pulse; // Установка длительности
isT2Active = true;
} else {
digitalWrite(pinT2, LOW); // Конец импульса
TCCR2B = 0; // Остановка Timer2
TIMSK2 &= ~(1 << OCIE2A);
isT2Active = false;
}
}
/*==============================================================================
LOOP SECTION
==============================================================================*/
void loop() {
}
Код: Выделить всё
#include "flprogUtilites.h"
#include <avr/interrupt.h>
float Per_193484155_1;
float pulseT1_193484155_1;
float pulseT2_193484155_1;
float phaseShift_193484155_1;
const float MIN_FREQ_193484155_1= 0.2; // ~0.2 Гц (период ~5 сек)
const float MAX_FREQ_193484155_1= 1000.0; // 1 кГц (период 1 мс)
volatile bool isT2Active_193484155_1= false;
volatile uint16_t icr1_value, ocr1_value, ocr2_start, ocr2_pulse_193484155_1;
volatile uint8_t prescaler1, prescaler2_start, prescaler2_pulse_193484155_1;
int use_OC1A_193484155_1= false;
int use_OC2A_193484155_1= false;
bool validateParameters_193484155_1();
void configureTimers_193484155_1();
void setTimer1Prescaler_193484155_1(float period_us);
void setTimer1Registers_193484155_1();
uint16_t calculateTimer2_193484155_1(float ms, uint8_t* prescaler);
void handleT1Interrupt_193484155_1();
uint16_t scalerValueTimer1_193484155_1(uint8_t prescaler);
void updateParameters_193484155_1(float newPer, float newPulseT1, float newPulseT2, float newPhaseShift);
void updatePer_193484155_1(float newPer);
void updatePulses_193484155_1(float newPulseT1, float newPulseT2);
void updatePhaseShift_193484155_1(float newPhaseShift);
void setup()
{
// Проверка параметров
use_OC1A_193484155_1 = (9 == 9);
use_OC2A_193484155_1 = (3 == 11);
pinMode(9, OUTPUT);
pinMode(3, OUTPUT);
if (!validateParameters_193484155_1()) while(1); // Блокировка при ошибке
configureTimers_193484155_1();
sei(); // Разрешение прерываний
}
void loop()
{
//Плата:1
Per_193484155_1 = 50.00;
pulseT1_193484155_1 = 2.5;
pulseT2_193484155_1 = 10.2;
phaseShift_193484155_1 = 1.3;
// Основная логика нет, работа через прерывания
}
bool validateParameters_193484155_1()
{
// ===== ПРОВЕРКА ПАРАМЕТРОВ =====
float period_ms = 1000.0 / Per_193484155_1;
return !((9 != 9 && 9 != 10) || (3 != 3 && 3 != 11) || (Per_193484155_1 < 0.2 || Per_193484155_1 > 1000.0) || // Диапазон частот
(pulseT1_193484155_1 < 0.1 || pulseT2_193484155_1 < 0.1) || // Минимальная длительность
(pulseT1_193484155_1 >= period_ms) || // T1 не должен заполнять весь период
(pulseT1_193484155_1 + phaseShift_193484155_1 + pulseT2_193484155_1 >= period_ms) // Наложение сигналов
);
}
void configureTimers_193484155_1()
{
// ===== КОНФИГУРАЦИЯ ТАЙМЕРОВ =====
// Расчет периода (мкс)
float period_us = 1e6 / Per_193484155_1;
// Настройка Timer1
TCCR1A = TCCR1B = 0;
setTimer1Prescaler_193484155_1(period_us);
setTimer1Registers_193484155_1();
// Настройка Timer2
TCCR2A = (use_OC2A_193484155_1) ? (1 << COM2A1) : (1 << COM2B1); // Режим сравнения
TCCR2B = 0; // Предделитель пока выключен
// Конфигурация Timer2
float startTime = pulseT1_193484155_1 + phaseShift_193484155_1;
phaseShift_193484155_1 >= -pulseT1_193484155_1;
ocr2_start = calculateTimer2_193484155_1(fabs(startTime), &prescaler2_start);
ocr2_pulse_193484155_1 = calculateTimer2_193484155_1(pulseT2_193484155_1, &prescaler2_pulse_193484155_1);
// Разрешение прерываний
TIMSK1 = (1 << TOIE1) | ((phaseShift_193484155_1 >= 0) ? (use_OC1A_193484155_1 ? (1 << OCIE1A) : (1 << OCIE1B)) : 0);
}
void setTimer1Prescaler_193484155_1(float period_us)
{
const float scalers[] = {1.0, 8.0, 64.0, 256.0, 1024.0};
for(int i = 4; i >= 0; i--)
{
icr1_value = (period_us * 16.0 / scalers[i]) - 1;
if(icr1_value <= 65535)
{
prescaler1 = (i == 4) ? 0x05 : (i == 3) ? 0x04 :
(i == 2) ? 0x03 : (i == 1) ? 0x02 : 0x01;
return;
}
}
icr1_value = 65535; // Максимальное значение при ошибке
}
void setTimer1Registers_193484155_1()
{
TCCR1A = (1 << WGM11); // Fast PWM (ICR1)
TCCR1B = (1 << WGM13) | (1 << WGM12) | prescaler1;
// Расчет OCR1
float ticks = (pulseT1_193484155_1 * 1000.0 * 16.0) / scalerValueTimer1_193484155_1(prescaler1);
ocr1_value = constrain(ticks - 1, 1, icr1_value);
// Настройка вывода
TCCR1A &= ~((1 << COM1A1) | (1 << COM1B1));
if(use_OC1A_193484155_1)
{
TCCR1A |= (1 << COM1A1); // Неинверсный режим
OCR1A = ocr1_value;
}
else
{
TCCR1A |= (1 << COM1B1);
OCR1B = ocr1_value;
}
ICR1 = icr1_value; // Установка периода
}
uint16_t calculateTimer2_193484155_1(float ms, uint8_t* prescaler)
{
const float scalers[] = {1.0, 8.0, 32.0, 64.0, 128.0, 256.0};
float target_ticks = ms * 1000.0 * 16.0;
for(uint8_t i = 0; i < 6; i++)
{
float val = target_ticks / scalers[i];
if(val <= 256.0)
{
*prescaler = (i == 0) ? 0x01 : (i == 1) ? 0x02 :
(i == 2) ? 0x03 : (i == 3) ? 0x04 :
(i == 4) ? 0x05 : 0x06;
return val - 1;
}
}
return 255; // Максимальное значение
}
uint16_t scalerValueTimer1_193484155_1(uint8_t prescaler)
{
switch(prescaler)
{
case 0x01: return 1;
case 0x02: return 8;
case 0x03: return 64;
case 0x04: return 256;
case 0x05: return 1024;
default: return 1;
}
}
void updateParameters_193484155_1(float newPer, float newPulseT1, float newPulseT2, float newPhaseShift)
{
cli();
float oldParams[4] = {Per_193484155_1, pulseT1_193484155_1, pulseT2_193484155_1, phaseShift_193484155_1};
Per_193484155_1 = newPer;
pulseT1_193484155_1 = newPulseT1;
pulseT2_193484155_1 = newPulseT2;
phaseShift_193484155_1 = newPhaseShift;
if(!validateParameters_193484155_1())
{
// Откат при ошибке
Per_193484155_1 = oldParams[0];
pulseT1_193484155_1 = oldParams[1];
pulseT2_193484155_1 = oldParams[2];
phaseShift_193484155_1 = oldParams[3];
}
else
{
configureTimers_193484155_1();
}
sei();
}
void updatePer_193484155_1(float newPer)
{
float newPulseT1 = (pulseT1_193484155_1 * Per_193484155_1) / newPer; // Сохранение скважности
updateParameters_193484155_1(newPer, newPulseT1, pulseT2_193484155_1, phaseShift_193484155_1);
}
void updatePulses_193484155_1(float newPulseT1, float newPulseT2)
{
updateParameters_193484155_1(Per_193484155_1, newPulseT1, newPulseT2, phaseShift_193484155_1);
}
void updatePhaseShift_193484155_1(float newPhaseShift)
{
cli();
while(isT2Active_193484155_1); // Ожидание завершения импульса T2
updateParameters_193484155_1(Per_193484155_1, pulseT1_193484155_1, pulseT2_193484155_1, newPhaseShift);
}
ISR(TIMER1_COMPA_vect)
{
if(phaseShift_193484155_1 >= 0 && use_OC1A_193484155_1) handleT1Interrupt_193484155_1();
}
ISR(TIMER1_COMPB_vect)
{
if(phaseShift_193484155_1 >= 0 && !use_OC1A_193484155_1) handleT1Interrupt_193484155_1();
}
ISR(TIMER1_OVF_vect)
{
if(phaseShift_193484155_1 < 0) handleT1Interrupt_193484155_1();
}
void handleT1Interrupt_193484155_1()
{
TCNT2 = 0; // Сброс счетчика Timer2
OCR2A = ocr2_start;
TCCR2B = prescaler2_start; // Запуск Timer2
TIMSK2 |= (1 << OCIE2A); // Разрешение прерывания
}
ISR(TIMER2_COMPA_vect)
{
if(!isT2Active_193484155_1)
{
digitalWrite(3, HIGH); // Начало импульса
OCR2A = ocr2_pulse_193484155_1;
TCCR2B = prescaler2_pulse_193484155_1; // Установка длительности
isT2Active_193484155_1 = true;
}
else
{
digitalWrite(3, LOW); // Конец импульса
TCCR2B = 0; // Остановка Timer2
TIMSK2 &= ~(1 << OCIE2A);
isT2Active_193484155_1 = false;
}
}