Я тут как раз на PUYA - PY32F003L18 (восьминожка) основу скетча под преобразователь запилил, всё одно к одному видимо )))
#include <Arduino.h>
#define MAX_PWM 1148
#define MIN_PWM 7
// Медианный фильтр
#define MEDIAN_SIZE 5
uint16_t adc0_median_buffer[MEDIAN_SIZE];
uint16_t adc1_median_buffer[MEDIAN_SIZE];
uint8_t median_index = 0;
uint16_t medianFilter(uint16_t new_value, uint16_t buffer[], uint8_t size, uint8_t *index) {
buffer[*index] = new_value;
*index = (*index + 1) % size;
// Создаем временный буфер для сортировки
uint16_t temp_buffer[size];
for (uint8_t i = 0; i < size; i++) {
temp_buffer[i] = buffer[i];
}
// Простая пузырьковая сортировка
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size; j++) {
if (temp_buffer[i] > temp_buffer[j]) {
uint16_t temp = temp_buffer[i];
temp_buffer[i] = temp_buffer[j];
temp_buffer[j] = temp;
}
}
}
return temp_buffer[size / 2]; // Возвращаем медиану
}
void setup() {
Serial.begin(115200);
Serial.println("PY32F003L18 в работе");
// Включение тактирования
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; // Порт A
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // АЦП1
// Настройка выводов АЦП в аналоговый режим
// PA0, PA1, PA2, PA3 - аналоговые входы
GPIOA->MODER |= GPIO_MODER_MODER0 | GPIO_MODER_MODER1 |
GPIO_MODER_MODER2 | GPIO_MODER_MODER3;
// Настройка АЦП
ADC1->CFGR1 = 0; // Сброс конфигурации
ADC1->CFGR2 = 0; // Сброс конфигурации 2
// Время выборки: 71.5 циклов (для PY32)
ADC1->SMPR |= ADC_SMPR_SMP_0 | ADC_SMPR_SMP_1 | ADC_SMPR_SMP_2;
// Настройка последовательности: 2 канала
ADC1->CHSELR = 0;
ADC1->CHSELR |= ADC_CHSELR_CHSEL8; // Канал 8 (PA0)
ADC1->CHSELR |= ADC_CHSELR_CHSEL9; // Канал 9 (PA1)
// Длина последовательности: 2 преобразования
ADC1->SQR1 = 0; // 1 преобразование в последовательности
// Для PY32 последовательность настраивается через CHSELR
ADC1->CR = ADC_CR_ADEN; // Включение АЦП
while (!(ADC1->ISR & ADC_ISR_ADRDY)); // Ожидание готовности
// ИНИЦИАЛИЗАЦИЯ ШИМ НА TIM2 ------------
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // Тактирование TIM2
// Настройка PA0 как альтернативной функции (TIM2_CH1)
GPIOA->MODER &= ~GPIO_MODER_MODER0;
GPIOA->MODER |= (2 << GPIO_MODER_MODER0_Pos); // Alternate function
GPIOA->AFR[0] |= (1 << GPIO_AFRL_AFSEL0_Pos); // AF1 = TIM2
// Настройка таймера
TIM2->PSC = 0; // Предделитель = 1
TIM2->ARR = 1151; // Период (11-битное разрешение)
TIM2->CCR1 = 575; // Начальная скважность 50%
// Настройка ШИМ режима 1
TIM2->CCMR1 |= (6 << TIM_CCMR1_OC1M_Pos); // PWM mode 1
TIM2->CCMR1 |= TIM_CCMR1_OC1PE; // Preload enable
TIM2->CCER |= TIM_CCER_CC1E; // Включение канала 1
TIM2->CR1 |= TIM_CR1_ARPE; // Auto-reload preload
TIM2->CR1 |= TIM_CR1_CEN; // Запуск таймера
Serial.println("ШИМ инициализирован на PA0");
Serial.print("Частота ШИМ: ");
Serial.print(SystemCoreClock / (TIM2->PSC + 1) / (TIM2->ARR + 1));
Serial.println(" Hz");
// Инициализация буферов медианного фильтра
for (int i = 0; i < MEDIAN_SIZE; i++) {
adc0_median_buffer[i] = 2048;
adc1_median_buffer[i] = 2048;
}
}
volatile unsigned int adc[2];
float result;
void loop() {
// Запуск одиночного преобразования
ADC1->CR |= ADC_CR_ADSTART;
// Ожидание завершения преобразования
while (!(ADC1->ISR & ADC_ISR_EOC));
// Чтение значений (последовательно для каждого канала)
// PY32F003 преобразует каналы по очереди согласно CHSELR
uint16_t raw_adc0 = ADC1->DR; // Первое чтение - канал 8
// Запуск второго преобразования
ADC1->CR |= ADC_CR_ADSTART;
while (!(ADC1->ISR & ADC_ISR_EOC));
uint16_t raw_adc1 = ADC1->DR; // Второе чтение - канал 9
// Применение медианного фильтра
adc[0] = medianFilter(raw_adc0, adc0_median_buffer, MEDIAN_SIZE, &median_index);
adc[1] = medianFilter(raw_adc1, adc1_median_buffer, MEDIAN_SIZE, &median_index);
result = (float)adc[0] * 3.3f / 4095.0f;
Serial.print("A0 = ");
Serial.print(result, 3);
Serial.print(" ");
result = (float)adc[1] * 3.3f / 4095.0f;
Serial.print("A1 = ");
Serial.print(result, 3);
// Управление ШИМ
uint16_t pwmm = adc[0] / 4;
if (pwmm > MAX_PWM) pwmm = MAX_PWM;
if (pwmm < MIN_PWM) pwmm = MIN_PWM;
TIM2->CCR1 = pwmm;
Serial.print(" PWM: ");
Serial.print(pwmm);
Serial.print(" (");
Serial.print((pwmm * 100) / 1151);
Serial.println("%)");
delay(100);
}
PS я так понял здесь больше некому
