diff --git a/firmware/main.c b/firmware/main.c index d0f1ba8..57ad143 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -18,9 +18,11 @@ // Constants #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) -#define ADC_UP_BTN_MIN 20 -#define ADC_DOWN_BTN_MAX 15 // Button 2 range: 0..15 (should read ~0) +// Button ladder +#define ADC_UP_BTN_MAX 15 // UP connects direct to GND -> ~0V -> ADC ~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 @@ -48,31 +50,38 @@ void Init_Hardware(void) { // 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; + // [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 GPIOA->CFGLR &= ~(0xF << (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 GPIOD->CFGLR &= ~(0xF << (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)); // PD6: Port D=0b11, bits [13:12] - EXTI->INTENR |= (1 << FLOW_PIN); // Enable EXTI interrupt on line 6 - EXTI->FTENR |= (1 << FLOW_PIN); // Falling edge trigger - NVIC_EnableIRQ(EXTI7_0_IRQn); // Enable interrupt in NVIC + AFIO->EXTICR |= (0b11 << (FLOW_PIN * 2)); + EXTI->INTENR |= (1 << FLOW_PIN); + EXTI->FTENR |= (1 << FLOW_PIN); + NVIC_EnableIRQ(EXTI7_0_IRQn); - // 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)); // Setup ADC - ADC1->CTLR2 |= ADC_ADON; // Turn on ADC - ADC1->RSQR3 = 2; // PC4 is ADC Channel 2 (AIN2) - ADC1->SAMPTR2 = 7 << (3 * 2); // Max sampling time for CH2 + ADC1->CTLR2 |= ADC_ADON; + ADC1->RSQR3 = 2; + 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); ADC1->CTLR2 |= ADC_CAL; while(ADC1->CTLR2 & ADC_CAL); @@ -146,19 +155,19 @@ int main() { } // --- 3. BUTTON HANDLING (ADC Resistor Ladder) --- - // Thresholds match actual voltages: no-press ~1023, BTN1 ~93, BTN2 ~0. uint16_t adc_val = Read_ADC(); 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) { - // Button 1: voltage divider 10k+1k -> ~0.30V -> ADC ~93 + // Button UP pressed threshold_ml_min += 100; last_button_time = current_time; printf("[SET] Threshold increased to: %lu mL/min\r\n", threshold_ml_min); Update_Display(flow_rate_ml_min, threshold_ml_min); } - else if (adc_val <= ADC_DOWN_BTN_MAX) { - // Button 2: direct to GND -> ~0V -> ADC ~0 + else if (adc_val >= ADC_DOWN_BTN_MIN && adc_val <= ADC_DOWN_BTN_MAX) { + // Button DOWN pressed if (threshold_ml_min >= 100) threshold_ml_min -= 100; last_button_time = current_time; printf("[SET] Threshold decreased to: %lu mL/min\r\n", threshold_ml_min);