0
\$\begingroup\$

I have been having some trouble getting my ADC to work so I have decided to give it a try by manipulating the registers. I have a textbook which outlines the steps and I think I have it finished, but I can't get it to output anything since the LCD display won't print anything.

The board is an STM32L476 Discovery with a built-in ADC

Here is the code:

char lcd_buffer[6];    // LCD display buffer
__IO uint32_t measuredValue; 

int main(void)
{

    //int n;
    //UART2_Init();         
    //n = sprintf((char *)buffer, "%.2f ", measuredReading);
    //USART_Write(USART2, buffer, n);

    HAL_Init();
    SystemClock_Config();   
    HAL_InitTick(0x0000); // set systick's priority to the highest. 
    BSP_LED_Init(LED4);
    BSP_LED_Init(LED5); 
    BSP_LCD_GLASS_Init();

    // Clear HSI ready
    RCC->CR &= ~(0x1 << 10);
    // Turn on HSI
    RCC->CR |= (1 << 8);    
    // Wait for it to be ready
    while (!(RCC->CR & (0x1 << 10))) {}


    // Enable clock for GPIOC
    RCC->AHB2ENR |= 0x1 << 2;
    // Reset port mode, while setting PIN 0 as analog input (0b11)
    GPIOC->MODER = 0xFFFFFFFF;  
    // Reset PUPD register, while setting PIN 0 as NOPUSHPULL (0b00)
    GPIOC->PUPDR = 0x00000000;

    // Turn on the ADC clock
    RCC->AHB2ENR |= 0x1 << 13;
    // Turn off ADC conversion
    ADC1->CR = 0x1 << 0;
    // Set length of regular channel to 1 (0b0000)
    ADC1->SQR1 = 0x00000000;
    // Set channel 10 as the 1st conversion in regular sequence
    ADC1->SQR1 = (ADC1->SQR1 & ~(63<<6)) | ( 10 << 6 & 63 << 6); //setting SQ1 to channel 10. 0b111111 (63) << 6 is the mask.
    // Configure the sample time register for channel 10
    ADC1->SMPR2 |= 0x07;
    // Enable end of conversion interrupt
    ADC1->IER |= 0x1 << 2;
    // Enable continuous conversion mode
    ADC1->CFGR |= 0x1 << 13;
    // Configure delay selection as delayed until the converted data have been read
    ADC1->CR |= 0x3 << 2;
    ADC1->CFGR |= 0x1 << 14; 

    // Enable and configure the interrupt handler for ADC1
    HAL_NVIC_EnableIRQ(ADC1_IRQn);
    HAL_NVIC_SetPriority(ADC1_IRQn, 1, 0);

    // Configure alignment and resolution
    ADC1->CFGR &= ~( 0x1 << 5 ); // right alignment
    ADC1->CFGR &= ~( 0x3 << 3 ); // 12 bit resolution 

    // Starts conversion.
    ADC1->CR |= 1 << 2;

    // prints output data register
    measuredValue = ADC1->DR;
    sprintf(lcd_buffer,"%d",measuredValue);
    BSP_LCD_GLASS_Clear();
    BSP_LCD_GLASS_DisplayString((uint8_t*)lcd_buffer);

    // dead loop
    while (1)
    {
            BSP_LED_On(LED5);
    } 
}

Just before the dead loop, I try to display the value from the data register, but the LCD displays nothing. If I move those four lines to just after the LCD init function and disable the ADC code it works fine. When I run the ADC code it disables the LCD for some reason.

The program does reach the dead loop, since LED5 turns on.

\$\endgroup\$
  • \$\begingroup\$ It might be helpful if you specified what microcontroller you're using, and if it's not a built-in ADC, the ADC as well. \$\endgroup\$ – Hearth Jan 24 at 21:31
  • \$\begingroup\$ what happens if you comment out all the ADC code? \$\endgroup\$ – jsotola Jan 24 at 21:40
  • \$\begingroup\$ @Hearth The board is an STM32L476 Discovery with a built-in ADC \$\endgroup\$ – Alexander Jan 24 at 22:00
  • \$\begingroup\$ @jstola Oh, when I moved the four lines, I also brought the while loop, so the ADC code was never run. \$\endgroup\$ – Alexander Jan 24 at 22:01
  • \$\begingroup\$ @jstola I just tried to print to the LCD, then run the ADC code and it does not work. The ADC code must be disabling the LCD for some reason. \$\endgroup\$ – Alexander Jan 24 at 22:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.