NUCLEO-STM32L011x使用GPIO在7段LED显示屏上显示数字

时间:2018-10-31 09:08:48

标签: c stm32 digits nucleo

enter image description here我正在尝试制作一个测试器,其hsd可以计算微动开关被按下的时间。

在下面添加代码:

        #include "stm32l0xx.h"

        #define SYSCLK_FREQ 131072

        void delay(uint16_t n_ms);
        void LEDDisplay(int type);
        void CountTime(int liczydlo);
        void Clear(void);

        int liczydlo = 0; 
        int ileSetek = 0; 
        int ileDziesiatek = 0; 
        int ileJednosci = 0;

        int main(void)
        { // BEGGINING OF MAIN
        RCC->ICSCR = RCC_ICSCR_MSIRANGE_1; //131072Hz //Ustawienie zegara MSI na 131072Hz
            RCC->CR = RCC_CR_MSION; //Wlaczenie zegara MSI
            while(!(RCC->CR & RCC_CR_MSIRDY)); //wait for MSI

            RCC->IOPENR = RCC_IOPENR_GPIOAEN | RCC_IOPENR_GPIOBEN | RCC_IOPENR_GPIOCEN; //Zalaczenie modulow GPIO
            RCC->AHBENR = RCC_AHBENR_DMAEN; //Zalaczenie modulu DMA
            RCC->APB1ENR = RCC_APB1ENR_TIM2EN | RCC_APB1ENR_PWREN; //Zalaczenie modulow TIM2 I LPOW

            RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;

            GPIOA->MODER = GPIO_MODER_MODE0_1 /* Reset */
                            | GPIO_MODER_MODE1_0 | GPIO_MODER_MODE2_0 
                            | GPIO_MODER_MODE3_0 | GPIO_MODER_MODE4_0 | GPIO_MODER_MODE5_0
                            | GPIO_MODER_MODE6_0 | GPIO_MODER_MODE7_0 | GPIO_MODER_MODE8_0 
                            | GPIO_MODER_MODE9_0 | GPIO_MODER_MODE10_0 | GPIO_MODER_MODE11_0
                            | GPIO_MODER_MODE12_0; /* LED PINOUT */

            GPIOB->MODER = GPIO_MODER_MODE7_1 | GPIO_MODER_MODE3_0; /* Mikrolacznik */

            GPIOC->MODER = GPIO_MODER_MODE14_0 | GPIO_MODER_MODE15_0; /* Diody Led */

            //configure exti interupt PA0
            SYSCFG->EXTICR[0] &= (uint16_t)~SYSCFG_EXTICR1_EXTI0_PA; 
            EXTI->IMR |= 0x0001;
            EXTI->RTSR |= 0x0001; 
            NVIC_EnableIRQ(EXTI0_1_IRQn);
            NVIC_SetPriority(EXTI0_1_IRQn,0);

            TIM2->PSC = (SYSCLK_FREQ/10000)-1; //100ms  
            TIM2->EGR = TIM_EGR_UG; //generate update

            while(1)
            {
                Clear();
                if((GPIOB->IDR & GPIO_IDR_ID7)){
                    delay(1000);
                    ++liczydlo;
                } else {
                    CountTime(liczydlo);
                    while(!(GPIOA->IDR & GPIO_IDR_ID0))
                    {
                        GPIOA->BSRR = GPIO_BSRR_BR_12;
                        LEDDisplay(ileSetek);
                        delay(50);
                        GPIOA->BSRR = GPIO_BSRR_BS_12;
                        GPIOB->BSRR = GPIO_BSRR_BR_3;
                        LEDDisplay(ileDziesiatek);
                        delay(50);
                        GPIOB->BSRR = GPIO_BSRR_BS_3;
                        GPIOA->BSRR = GPIO_BSRR_BR_8;
                        LEDDisplay(ileJednosci);
                        delay(50);
                        GPIOA->BSRR = GPIO_BSRR_BS_8;
                    }
                }
            }       
        }

        void Clear(void)
        {
            /*SEGMENTY*/
            GPIOA->BSRR = GPIO_BSRR_BS_12;
            GPIOB->BSRR = GPIO_BSRR_BS_3;
            GPIOA->BSRR = GPIO_BSRR_BS_8;
            /*WYSWIETLACZ*/
            GPIOA->BSRR = GPIO_BSRR_BR_11;
            GPIOA->BSRR = GPIO_BSRR_BR_10;
            GPIOA->BSRR = GPIO_BSRR_BR_7;
            GPIOA->BSRR = GPIO_BSRR_BR_5;
            GPIOA->BSRR = GPIO_BSRR_BR_4;
            GPIOA->BSRR = GPIO_BSRR_BR_3;
            GPIOA->BSRR = GPIO_BSRR_BR_2;
            GPIOA->BSRR = GPIO_BSRR_BR_1;
            /*MIKRUS*/
            GPIOB->BSRR = GPIO_BSRR_BR_7;
            /*LEDY*/
            GPIOC->BSRR = GPIO_BSRR_BR_14;
            GPIOC->BSRR = GPIO_BSRR_BR_15;
            /*RESET*/
            GPIOA->BSRR = GPIO_BSRR_BR_0;
        }

        void CountTime(int liczydlo)
        {
            // Jezeli wiecej niz 100 sec
            if (liczydlo >= 100) 
            {                   
                ileSetek = liczydlo/100;
                ileDziesiatek = ((liczydlo - (ileSetek*100))/10);
                ileJednosci = ((liczydlo - (ileSetek*100)) - (ileDziesiatek*10));
            } 
            // Jezeli wiecej niz 10 sec
            else if (liczydlo >= 10) 
            {                   
                ileDziesiatek = (liczydlo / 10);
                ileJednosci = (liczydlo - (ileDziesiatek * 10));
            } 
            // Jezeli mniej niz 10 sec
            else if (liczydlo < 10) 
            {                       
                ileJednosci = liczydlo;
            }
        }

        void LEDDisplay(int type)
        //wywietl bit
        {
            switch(type){
                case 1:
                {               
                    GPIOA->BSRR = GPIO_BSRR_BR_11; // A
                    GPIOA->BSRR = GPIO_BSRR_BR_10; // F
                    GPIOA->BSRR = GPIO_BSRR_BS_7; // B
                    GPIOA->BSRR = GPIO_BSRR_BR_5; // G
                    GPIOA->BSRR = GPIO_BSRR_BS_4; // C
                    GPIOA->BSRR = GPIO_BSRR_BR_3; // DOT
                    GPIOA->BSRR = GPIO_BSRR_BR_2; // D
                    GPIOA->BSRR = GPIO_BSRR_BR_1; // E
                    break;
                }
                case 2:
                {               
                    GPIOA->BSRR = GPIO_BSRR_BS_11; // A
                    GPIOA->BSRR = GPIO_BSRR_BR_10; // F
                    GPIOA->BSRR = GPIO_BSRR_BS_7; // B
                    GPIOA->BSRR = GPIO_BSRR_BS_5; // G
                    GPIOA->BSRR = GPIO_BSRR_BR_4; // C
                    GPIOA->BSRR = GPIO_BSRR_BR_3; // DOT
                    GPIOA->BSRR = GPIO_BSRR_BS_2; // D
                    GPIOA->BSRR = GPIO_BSRR_BS_1; // E
                    break;
                }
                case 3:
                {               
                    GPIOA->BSRR = GPIO_BSRR_BS_11; // A
                    GPIOA->BSRR = GPIO_BSRR_BR_10; // F
                    GPIOA->BSRR = GPIO_BSRR_BS_7; // B
                    GPIOA->BSRR = GPIO_BSRR_BS_5; // G
                    GPIOA->BSRR = GPIO_BSRR_BS_4; // C
                    GPIOA->BSRR = GPIO_BSRR_BR_3; // DOT
                    GPIOA->BSRR = GPIO_BSRR_BS_2; // D
                    GPIOA->BSRR = GPIO_BSRR_BR_1; // E
                    break;
                }
                case 4:
                {               
                    GPIOA->BSRR = GPIO_BSRR_BR_11; // A
                    GPIOA->BSRR = GPIO_BSRR_BS_10; // F
                    GPIOA->BSRR = GPIO_BSRR_BS_7; // B
                    GPIOA->BSRR = GPIO_BSRR_BS_5; // G
                    GPIOA->BSRR = GPIO_BSRR_BS_4; // C
                    GPIOA->BSRR = GPIO_BSRR_BR_3; // DOT
                    GPIOA->BSRR = GPIO_BSRR_BR_2; // D
                    GPIOA->BSRR = GPIO_BSRR_BR_1; // E
                    break;
                }
                case 5:
                {               
                    GPIOA->BSRR = GPIO_BSRR_BS_11; // A
                    GPIOA->BSRR = GPIO_BSRR_BS_10; // F
                    GPIOA->BSRR = GPIO_BSRR_BR_7; // B
                    GPIOA->BSRR = GPIO_BSRR_BS_5; // G
                    GPIOA->BSRR = GPIO_BSRR_BS_4; // C
                    GPIOA->BSRR = GPIO_BSRR_BR_3; // DOT
                    GPIOA->BSRR = GPIO_BSRR_BS_2; // D
                    GPIOA->BSRR = GPIO_BSRR_BR_1; // E
                    break;
                }
                case 6:
                {               
                    GPIOA->BSRR = GPIO_BSRR_BS_11; // A
                    GPIOA->BSRR = GPIO_BSRR_BS_10; // F
                    GPIOA->BSRR = GPIO_BSRR_BR_7; // B
                    GPIOA->BSRR = GPIO_BSRR_BS_5; // G
                    GPIOA->BSRR = GPIO_BSRR_BS_4; // C
                    GPIOA->BSRR = GPIO_BSRR_BR_3; // DOT
                    GPIOA->BSRR = GPIO_BSRR_BS_2; // D
                    GPIOA->BSRR = GPIO_BSRR_BS_1; // E
                    break;
                }
                case 7:
                {               
                    GPIOA->BSRR = GPIO_BSRR_BS_11; // A
                    GPIOA->BSRR = GPIO_BSRR_BS_10; // F
                    GPIOA->BSRR = GPIO_BSRR_BR_7; // B
                    GPIOA->BSRR = GPIO_BSRR_BS_5; // G
                    GPIOA->BSRR = GPIO_BSRR_BS_4; // C
                    GPIOA->BSRR = GPIO_BSRR_BR_3; // DOT
                    GPIOA->BSRR = GPIO_BSRR_BS_2; // D
                    GPIOA->BSRR = GPIO_BSRR_BS_1; // E
                    break;
                }
                case 8:
                {               
                    GPIOA->BSRR = GPIO_BSRR_BS_11; // A
                    GPIOA->BSRR = GPIO_BSRR_BS_10; // F
                    GPIOA->BSRR = GPIO_BSRR_BS_7; // B
                    GPIOA->BSRR = GPIO_BSRR_BS_5; // G
                    GPIOA->BSRR = GPIO_BSRR_BS_4; // C
                    GPIOA->BSRR = GPIO_BSRR_BR_3; // DOT
                    GPIOA->BSRR = GPIO_BSRR_BS_2; // D
                    GPIOA->BSRR = GPIO_BSRR_BS_1; // E
                    break;
                }
                case 9:
                {               
                    GPIOA->BSRR = GPIO_BSRR_BS_11; // A
                    GPIOA->BSRR = GPIO_BSRR_BS_10; // F
                    GPIOA->BSRR = GPIO_BSRR_BS_7; // B
                    GPIOA->BSRR = GPIO_BSRR_BS_5; // G
                    GPIOA->BSRR = GPIO_BSRR_BS_4; // C
                    GPIOA->BSRR = GPIO_BSRR_BR_3; // DOT
                    GPIOA->BSRR = GPIO_BSRR_BS_2; // D
                    GPIOA->BSRR = GPIO_BSRR_BR_1; // E
                    break;
                }
                case 0:
                {               
                    GPIOA->BSRR = GPIO_BSRR_BS_11; // A
                    GPIOA->BSRR = GPIO_BSRR_BS_10; // F
                    GPIOA->BSRR = GPIO_BSRR_BS_7; // B
                    GPIOA->BSRR = GPIO_BSRR_BR_5; // G
                    GPIOA->BSRR = GPIO_BSRR_BS_4; // C
                    GPIOA->BSRR = GPIO_BSRR_BR_3; // DOT
                    GPIOA->BSRR = GPIO_BSRR_BS_2; // D
                    GPIOA->BSRR = GPIO_BSRR_BS_1; // E
                    break;
                }
                default: break;
            }
        }

        void EXTI0_1_IRQHandler(void)
        //przerwanie na pinie zasilania
        {
            liczydlo = 0;
            EXTI->PR = EXTI_PR_PR0;
        }


        void delay(uint16_t n_ms)
        {
            //upcounting timer - 16bit
            TIM2->CNT = 65535-n_ms;
            TIM2->CR1 = TIM_CR1_CEN | TIM_CR1_OPM; //one-pulse mode
            while(!(TIM2->SR & TIM_SR_UIF)); //wait
            TIM2->SR = 0;
        }

因此,想法是使用Nucleo的GPIO引脚分配来显示数字,但是Nucleo板自行设置了引脚上的高电平状态,最终导致产生意外结果。

有没有办法防止在GPIOA / B / C引脚上获得随机状态?

@EDIT我也不知道为什么在显示信息几秒钟后7段显示器就关闭了。它处于无限while循环中,因此它不应该无限显示吗?

@ EDIT2为了帮助阅读代码。 GPIO PA0-是我的重置按钮,用于清除计数器。 GPRIOA1-12(不多)用于LED显示屏。 GPIOC仅用于某些控制指示灯-目前未使用。板上未使用GPIOB 3(功能为空),并将其用作中间显示屏的阴极(实际上,它可以正常工作)。

0 个答案:

没有答案