Stm32f1xx-hal adc cannot read data

this is my code

#[entry]
fn main()->! {

    let cp =cortex_m::Peripherals::take().unwrap();
    let dp = pac::Peripherals::take().unwrap();
    let mut rcc = dp.RCC.constrain();
    let mut flash=dp.FLASH.constrain();
    let clocks= rcc.cfgr.sysclk(72.MHz()).pclk2(72.MHz()).adcclk(12.MHz()).freeze(&mut flash.acr);
    let mut gpioa=dp.GPIOA.split();
    let mut led= gpioa.pa1.into_push_pull_output(&mut gpioa.crl);

    let mut myadc1 = adc::Adc::adc1(dp.ADC1, clocks);
    // myadc1.set_sample_time(SampleTime::T_239);
    // let mut gpiob=dp.GPIOB.split();
    // let mut adc_pin=gpiob.pb0.into_analog(&mut gpiob.crl);
    let mut adc_pin = gpioa.pa7.into_analog(&mut gpioa.crl);
    let mut delay = cp.SYST.delay(&clocks);

    let usart_tx=gpioa.pa9.into_alternate_push_pull(&mut gpioa.crh);
    let usart_rx=gpioa.pa10.into_pull_up_input(&mut gpioa.crh);
    let mut afio=dp.AFIO.constrain();

    let serial=Serial::new(dp.USART1, (usart_tx,usart_rx),&mut afio.mapr, Config::default().baudrate(9600.bps()), &clocks);
    let (mut tx,rx)=serial.split();
    let data:u16 =myadc1.read(&mut adc_pin).unwrap_or(999_u16);
    
    loop {
        delay.delay_ms(1000_u16);
        led.toggle();
        let data:u16 =myadc1.read_vref();
        writeln!(tx,"data:{}\n ,",data).unwrap();
        // writeln!(tx,"{}",data).unwrap();
        writeln!(tx,"data:\n ,").unwrap();

    }
}

When the program reaches this point, it gets stuck

let data:u16 =myadc1.read(&mut adc_pin).unwrap_or(999_u16);

I am sure that there is no problem with my proteus simulation because I can read the ADC value normally when using C

After generating the file I used this to convert to hex file

cargo  objcopy --release --target thumbv7em-none-eabi -- -O ihex txx.hex

I'm confused as to what went wrong. :sob:

how did you figure out where it stuck? if you have a debugger attached, you can step into the function to see what went wrong.

what flashing/downloading tool are you using? commonly used tools like probe-rs and OpenOCD, support ELF files just fine, it's rarely necessary to convert ELF to HEX.

I tried to use comments to open or close this line of code. The result was that after I commented this line of code, my program could run normally (led flashes, serial port outputs normally). I used proteus to simulate, and it could not run directly using the compiled file. So I thought of using hex to load it.

I don't have personal experience with the f1xx family of chips, so I can only provide some generic directions. we need to wait for someone whos is real expert to get a definite answer.

mean while, I checked the source code, and I found there's some comments around the convert() method (the one called by read()):

it seems to be workaround for some quirky behavior or corner cases. since you are running on a simulator, there's a chance the simulator didn't simulate the hardware behavior precisely and caused the code to loop endlessly.

if you have a devboard at hand, the best way to verify is to run the program on real hardware and see if it behaves differently from the simulator.

also, I wonder does the simulator have a integrated debugger? if so, you can try to single step through the function in the debugger to locate which line of code caused the issue.

btw, the relevant code was introduced in this commit:

which was part of the realese 0.6.0, maybe you can try older version of the crate, just to verify whether it was the real cause.

last but not least, did you check if this is a know issue of the device's simulation model? if it was a known issue, it might be already fixed in newer version.

3 Likes

thank you very much,i will try it

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.