added firmware section

This commit is contained in:
cpu
2026-05-18 21:55:20 +02:00
parent 68cb57af28
commit c0273190d1

View File

@@ -18,9 +18,11 @@
// Constants // Constants
#define FLOW_CONVERSION_FACTOR 5.5 // L/min = Hz / 5.5 (Adjust for ZJ-S401) #define FLOW_CONVERSION_FACTOR 5.5 // L/min = Hz / 5.5 (Adjust for ZJ-S401)
#define ADC_UP_BTN_MAX 200 // Button 1 range: 50..200 (center ~93) // Button ladder
#define ADC_UP_BTN_MIN 20 #define ADC_UP_BTN_MAX 15 // UP connects direct to GND -> ~0V -> ADC ~0
#define ADC_DOWN_BTN_MAX 15 // Button 2 range: 0..15 (should read ~0) #define ADC_UP_BTN_MIN 0
#define ADC_DOWN_BTN_MAX 200 // DOWN connects via 1k -> ~0.45V -> ADC ~93
#define ADC_DOWN_BTN_MIN 50
#define DEBOUNCE_DELAY_MS 200 #define DEBOUNCE_DELAY_MS 200
@@ -48,31 +50,38 @@ void Init_Hardware(void) {
// 1. Enable Clocks for GPIOA, GPIOC, GPIOD, ADC, AFIO // 1. Enable Clocks for GPIOA, GPIOC, GPIOD, ADC, AFIO
RCC->APB2PCENR |= RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO; RCC->APB2PCENR |= RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO;
// [NEW FIX] Set ADC Clock Prescaler to DIV8 (48MHz / 8 = 6MHz). Must be <= 14MHz!
RCC->CFGR0 &= ~RCC_ADCPRE; // Clear prescaler bits
RCC->CFGR0 |= RCC_ADCPRE_DIV8; // Set to divide by 8
// 2. Configure ALARM_TRIGGER Output (PA2) - Push-Pull // 2. Configure ALARM_TRIGGER Output (PA2) - Push-Pull
GPIOA->CFGLR &= ~(0xF << (4 * ALARM_PIN)); GPIOA->CFGLR &= ~(0xF << (4 * ALARM_PIN));
GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * ALARM_PIN); GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * ALARM_PIN);
GPIOA->BSHR = (1 << (16 + ALARM_PIN)); // Default to ALARM STATE (Low = MOSFET OFF) GPIOA->BSHR = (1 << (16 + ALARM_PIN));
// 3. Configure FLOW_PULSE_MCU Input (PD6) - Pull-up // 3. Configure FLOW_PULSE_MCU Input (PD6) - Pull-up
GPIOD->CFGLR &= ~(0xF << (4 * FLOW_PIN)); GPIOD->CFGLR &= ~(0xF << (4 * FLOW_PIN));
GPIOD->CFGLR |= (GPIO_CNF_IN_PUPD) << (4 * FLOW_PIN); GPIOD->CFGLR |= (GPIO_CNF_IN_PUPD) << (4 * FLOW_PIN);
GPIOD->BSHR = (1 << FLOW_PIN); // Enable pull-up GPIOD->BSHR = (1 << FLOW_PIN);
// Setup EXTI on PD6 (CH32V003 has single EXTICR, 2 bits per pin, Port D = 0b11) AFIO->EXTICR |= (0b11 << (FLOW_PIN * 2));
AFIO->EXTICR |= (0b11 << (FLOW_PIN * 2)); // PD6: Port D=0b11, bits [13:12] EXTI->INTENR |= (1 << FLOW_PIN);
EXTI->INTENR |= (1 << FLOW_PIN); // Enable EXTI interrupt on line 6 EXTI->FTENR |= (1 << FLOW_PIN);
EXTI->FTENR |= (1 << FLOW_PIN); // Falling edge trigger NVIC_EnableIRQ(EXTI7_0_IRQn);
NVIC_EnableIRQ(EXTI7_0_IRQn); // Enable interrupt in NVIC
// 4. Configure BUTTON_ADC Input (PC4 / AIN2) - Analog mode (no pull) // 4. Configure BUTTON_ADC Input (PC4 / AIN2) - Analog mode
GPIOC->CFGLR &= ~(0xF << (4 * BUTTON_PIN)); GPIOC->CFGLR &= ~(0xF << (4 * BUTTON_PIN));
// Setup ADC // Setup ADC
ADC1->CTLR2 |= ADC_ADON; // Turn on ADC ADC1->CTLR2 |= ADC_ADON;
ADC1->RSQR3 = 2; // PC4 is ADC Channel 2 (AIN2) ADC1->RSQR3 = 2;
ADC1->SAMPTR2 = 7 << (3 * 2); // Max sampling time for CH2 ADC1->SAMPTR2 = 7 << (3 * 2);
ADC1->CTLR2 |= ADC_RSTCAL; // Reset & calibrate // [NEW FIX] Must configure EXTTRIG and EXTSEL for SWSTART to actually work
ADC1->CTLR2 |= ADC_EXTSEL; // Select SWSTART trigger (111)
ADC1->CTLR2 |= ADC_EXTTRIG; // Enable external trigger
ADC1->CTLR2 |= ADC_RSTCAL;
while(ADC1->CTLR2 & ADC_RSTCAL); while(ADC1->CTLR2 & ADC_RSTCAL);
ADC1->CTLR2 |= ADC_CAL; ADC1->CTLR2 |= ADC_CAL;
while(ADC1->CTLR2 & ADC_CAL); while(ADC1->CTLR2 & ADC_CAL);
@@ -146,19 +155,19 @@ int main() {
} }
// --- 3. BUTTON HANDLING (ADC Resistor Ladder) --- // --- 3. BUTTON HANDLING (ADC Resistor Ladder) ---
// Thresholds match actual voltages: no-press ~1023, BTN1 ~93, BTN2 ~0.
uint16_t adc_val = Read_ADC(); uint16_t adc_val = Read_ADC();
if ((current_time - last_button_time) > (DEBOUNCE_DELAY_MS * DELAY_US_TIME * 1000)) { if ((current_time - last_button_time) > (DEBOUNCE_DELAY_MS * DELAY_US_TIME * 1000)) {
if (adc_val >= ADC_UP_BTN_MIN && adc_val <= ADC_UP_BTN_MAX) { if (adc_val >= ADC_UP_BTN_MIN && adc_val <= ADC_UP_BTN_MAX) {
// Button 1: voltage divider 10k+1k -> ~0.30V -> ADC ~93 // Button UP pressed
threshold_ml_min += 100; threshold_ml_min += 100;
last_button_time = current_time; last_button_time = current_time;
printf("[SET] Threshold increased to: %lu mL/min\r\n", threshold_ml_min); printf("[SET] Threshold increased to: %lu mL/min\r\n", threshold_ml_min);
Update_Display(flow_rate_ml_min, threshold_ml_min); Update_Display(flow_rate_ml_min, threshold_ml_min);
} }
else if (adc_val <= ADC_DOWN_BTN_MAX) { else if (adc_val >= ADC_DOWN_BTN_MIN && adc_val <= ADC_DOWN_BTN_MAX) {
// Button 2: direct to GND -> ~0V -> ADC ~0 // Button DOWN pressed
if (threshold_ml_min >= 100) threshold_ml_min -= 100; if (threshold_ml_min >= 100) threshold_ml_min -= 100;
last_button_time = current_time; last_button_time = current_time;
printf("[SET] Threshold decreased to: %lu mL/min\r\n", threshold_ml_min); printf("[SET] Threshold decreased to: %lu mL/min\r\n", threshold_ml_min);