AnsweredAssumed Answered

Rotary potentiometer code

Question asked by piovan.stefano on Oct 10, 2011
Hi all,

some piece of code to manage a rotary encoder potentiometer. The model I use is from the chinese market maybe by TREXON. I'll propose both interrupt and polling mode. The interrupt code has been adapted from http://www.arduino.cc/playground/Main/RotaryEncoders and the polling one from http://stackoverflow.com/questions/34735/using-a-rotary-encoder-with-avr-micro-controller. Find also the interrupt handler (just modify the stm8s_it.c code as indicated).
The code is a part of a hobby project which is a PLL 2.4GHz signal reference generator.
The rotary potentiometer if for making a "knob" for such a generator to move the output frequency of the PLL. The project also has a 12 keys keypad and a LCD 16x2 display, which I have already posted.
The rotary potentiometer CHA goes into GPIOB.PIN0 and the CHB into the GPIOB.PIN1.

Hope it helps.
Stefano

________________________

main()

{
..
..


while(1)
    {
        
#ifdef _POLLMODE_

        wheel = (GPIO_ReadInputData(GPIOB) & 0x03);
        if(dir == 0)
        {
            if(wheel == 0x01)
                dir = 2;
            else if (wheel == 0x02)
                dir = 4;
            else
                dir = 0;
        }
        else if (dir == 2)
        {
            if (wheel == 0x01)
                dir = 2;
            else if (wheel == 0x00)
            {
                // decrease frequency
                VCOFreq -=100;
                PLL_SetFreq(VCOFreq);
                LCD_Cmd(LINE_2);
                Int2Str(sz_Val, VCOFreq);
                pos = 7;
                LCD_Str(sz_Val);
                dir = 0;
            }
            else
                dir = 0;
        }
        else if (dir == 4)
        {
            if (wheel == 0x02)
                dir = 4;
            else if (wheel == 0x00)
            {
                // increase frequency
                VCOFreq +=100;
                PLL_SetFreq(VCOFreq);
                LCD_Cmd(LINE_2);
                Int2Str(sz_Val, VCOFreq);
                pos = 7;
                LCD_Str(sz_Val);
                dir = 0;
            }
            else
                dir = 0;
        }
        else if (wheel == 0x03)
        {
            dir = 0;
        }

#else // INT MODE
    if (changed)
        {
            BEEP_Cmd(ENABLE);
            VCOFreq = counter;
            PLL_SetFreq(VCOFreq);
            LCD_Cmd(LINE_2);
            Int2Str(sz_Val, VCOFreq);
            pos = 7; // force cursor position <> 0 to simulate typing a new value from the keyboard
            LCD_Str(sz_Val);
            changed = 0;
            BEEP_Cmd(DISABLE);
        }
#endif


____________________


/**
  * @brief External Interrupt PORTB Interruption routine.
  * @par Parameters:
  * None
  * @retval
  * None
*/
#ifdef _COSMIC_
@far @interrupt void EXTI_PORTB_IRQHandler(void)
#else /* _RAISONANCE_ */
void EXTI_PORTB_IRQHandler(void) interrupt 4
#endif /* _COSMIC_ */
{    

    u8 portval;
    
    portval = (GPIO_ReadInputData(GPIOB) & 0x03);

    if ((portval == 0x03) || (portval == 0x00))
    {
        counter-=200;
    }
    else
    {
        counter+=200;
    }

    changed = 1; // this is to tell the main to display the new value
    
}

Outcomes