我正在尝试制作一个测试器,其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(功能为空),并将其用作中间显示屏的阴极(实际上,它可以正常工作)。