SAMR21 在调试时跳过部分代码

问题描述 投票:0回答:1

我的代码应该读取ADC 3次,然后取平均值,如果小于满量程值的一半,则板载LED应关闭,如果高于满量程值的一半,则应打开。 据我通过调试得知,adc 部分工作正常,它按应有的方式进行测量,但是当我进入比较值的部分时,代码会跳过打开或关闭 LED 的部分,然后返回到主循环的开始,然后返回到 while(1) 循环(所有这些都使用 atmel studio 上的逐步按钮)

这是代码:


/*
 * Include header files for all drivers that have been imported from
 * Atmel Software Framework (ASF).
 */
/*
 * Support and FAQ: visit <a href="https://www.microchip.com/support/">Microchip Support</a>
 */
#include <asf.h>


int main (void)
{
    system_init();
    uint32_t result = 0;
    uint8_t samp = 0;
    
    PORT->Group[0].DIRSET.reg |= 1<<19;
    
    ADC->DBGCTRL.reg = 1;
    
    SYSCTRL->OSC8M.reg |= 1<<30 | 1<<6 | 0b10;
    
    //ADC Pin6 Config
    PORT->Group[0].DIRCLR.reg |= 1<<6;
    PORT->Group[0].PMUX[3].reg = 0x1;
    PORT->Group[0].PINCFG[6].reg &= ~(0b11);
    PORT->Group[0].PINCFG[6].reg |= 1;
    
    //ADC CLK Config
    PM->APBCMASK.reg |= PM_APBCMASK_ADC; //Enable clk bus
    
    
    /* Enable GCLK1 for the ADC */
    GCLK->GENDIV.reg = 0;
    
    while (GCLK->STATUS.bit.SYNCBUSY) {};
    GCLK->GENCTRL.reg = 1<<21 | 1<<19 | 1<<17 | 1<<16 | 1<<10 | 1<<9;
    while (GCLK->STATUS.bit.SYNCBUSY) {};
        
    GCLK->CLKCTRL.reg = 1<<14 | 0x1E;

    /* Wait for bus synchronization. */
    while (GCLK->STATUS.bit.SYNCBUSY) {};
    
    uint32_t bias = (*((uint32_t *) ADC_FUSES_BIASCAL_ADDR) & ADC_FUSES_BIASCAL_Msk) >> ADC_FUSES_BIASCAL_Pos;
    uint32_t linearity = (*((uint32_t *) ADC_FUSES_LINEARITY_0_ADDR) & ADC_FUSES_LINEARITY_0_Msk) >> ADC_FUSES_LINEARITY_0_Pos;
    linearity |= ((*((uint32_t *) ADC_FUSES_LINEARITY_1_ADDR) & ADC_FUSES_LINEARITY_1_Msk) >> ADC_FUSES_LINEARITY_1_Pos) << 5;

    /* Wait for bus synchronization. */
    while (ADC->STATUS.bit.SYNCBUSY) {};

    /* Write the calibration data. */
    ADC->CALIB.reg = ADC_CALIB_BIAS_CAL(bias) | ADC_CALIB_LINEARITY_CAL(linearity);
    
    /* Wait for bus synchronization. */
    while (ADC->STATUS.bit.SYNCBUSY) {};

    /* Use the internal VCC reference. This is 1/2 of what's on VCCA.
       since VCCA is typically 3.3v, this is 1.65v.
    */
    ADC->REFCTRL.reg = 2;

    /* Only capture one sample. The ADC can actually capture and average multiple
       samples for better accuracy, but there's no need to do that for this
       example.
    */
    ADC->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_1;

    /* Set the clock prescaler to 512, which will run the ADC at
       8 Mhz / 512 = 31.25 kHz.
       Set the resolution to 12bit.
    */
    while (ADC->STATUS.bit.SYNCBUSY) {};
    ADC->CTRLB.reg = 0;

    /* Configure the input parameters.

       - GAIN_DIV2 means that the input voltage is halved. This is important
         because the voltage reference is 1/2 of VCCA. So if you want to
         measure 0-3.3v, you need to halve the input as well.

       - MUXNEG_GND means that the ADC should compare the input value to GND.

       - MUXPOST_PIN3 means that the ADC should read from AIN3, or PB09.
         This is A2 on the Feather M0 board.
    */
    while (ADC->STATUS.reg == STATUS_BUSY) {}
    ADC->INPUTCTRL.reg = 0b1111<<24 | 0b11 << 11 | 6;
    /* Wait for bus synchronization. */
    while (ADC->STATUS.bit.SYNCBUSY) {};

    /* Enable the ADC. */
    ADC->CTRLA.reg = 0b10;
    /* Wait for bus synchronization. */
    while (ADC->STATUS.bit.SYNCBUSY) {};


    while (1) {
        
        while (ADC->STATUS.bit.SYNCBUSY) {};
        /* Wait for the result ready flag to be set. */
        ADC->SWTRIG.bit.START = 1;
        while(ADC->INTFLAG.bit.RESRDY == 0){};
        
        /* Clear the flag. */
        ADC->INTFLAG.reg = ADC_INTFLAG_RESRDY;

        /* Read the value. */
        result += ADC->RESULT.reg;
        samp++;

        if(samp >= 3){
            if((result/3) < 2045){
                PORT->Group[0].OUTSET.reg |= 1<<19;
            }   
            else{
                PORT->Group[0].OUTCLR.reg |= 1<<19;
            }
            
            result = 0;
            samp = 0;
        }
            
        
    }
        
}


尝试逐行调试,期望执行

PORT->Group[0].OUT
行,但行不执行,代码跳转到
main()
的开头,然后跳转到
while(1)

的开头
c microcontroller cortex-m
1个回答
0
投票

TL;DR 继续单步执行并享受使用调试器的乐趣。

很长的故事(不是真的)。变量

uint32_t result
uint8_t samp = 0
在循环之前未使用。编译器已将其初始化移至循环体。只需继续单步执行代码,指令指针将分两步返回到循环体。

© www.soinside.com 2019 - 2024. All rights reserved.