#![no_std] #![no_main] #![feature(type_alias_impl_trait)] #![feature(impl_trait_in_assoc_type)] // Simple 555-like oscillator implemented in firmware. // - Q output: PB2 (also drives the on-board LED if present) // - Combined Trigger/Threshold analog input: PA0 (capacitor node) // Wiring suggestion: // Q (PB2) --[R]--+-- C -- GND // | // PA0 (ADC input) // The firmware toggles Q high when PA0 <= 1/3 Vref and low when PA0 >= 2/3 Vref. use embassy_executor::Spawner; use embassy_time::Timer; use hal::gpio::{Level, Output}; use {ch32_hal as hal, panic_halt as _}; use hal::adc::{Adc, SampleTime}; #[embassy_executor::main(entry = "qingke_rt::entry")] async fn main(_spawner: Spawner) -> ! { let p = hal::init(Default::default()); // Q output on PB2 let mut q = Output::new(p.PB2, Level::Low, Default::default()); // ADC on PA0 for combined Trigger/Threshold input let mut adc = Adc::new(p.ADC1, Default::default()); let mut trig_thres = p.PA0; // analog-capable pin used as ADC channel // ADC characteristics: assume 12-bit if HAL doesn't expose it. // If the HAL provides a method to query resolution, prefer that. let full_scale: u16 = 4095; // 12-bit default let thr_low: u16 = (full_scale as u32 / 3) as u16; // ~1/3 Vref let thr_high: u16 = ((full_scale as u32 * 2) / 3) as u16; // ~2/3 Vref // Start with Q low. State variable to avoid redundant toggles. let mut q_high = false; q.set_low(); loop { // Read capacitor node voltage via ADC let sample: u16 = adc.convert(&mut trig_thres, SampleTime::CYCLES239_5); // Implement Schmitt trigger behavior like NE555 using thresholds if !q_high && sample <= thr_low { // Trigger: voltage fell below 1/3 Vref -> set output high q.set_high(); q_high = true; } else if q_high && sample >= thr_high { // Threshold: voltage rose above 2/3 Vref -> set output low q.set_low(); q_high = false; } // Small delay to reduce CPU usage; adjust for responsiveness/noise Timer::after_micros(200).await; } }