[STM32F1] Przejście w tryb STANDBY

0

Wita
Mam prosty program do sterowania wyświetlaczem, po resecie na wyświetlaczu pojawia się napis a po naciśnięciu guzika inny i mikrokontroler przechodzi w tryb STANDBY. Obsługa przycisku działa, odpowiedni napis się wyświetla, ale mikrokontroler nie przełącza się w wybrany tryb. Co zrobiłem nie tak? :)

main:


#include "main.h"
#include "delay.h"
#include "bitmap.h"
#include "lcd.h"
#include "stm32f10x_rcc.h"

__IO uint16_t klikniecie;
#define tak 1
#define nie 0

GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef   SPI_InitStructure;
SPI_InitTypeDef spi;
GPIO_InitTypeDef gpio;
																		
void RCC_Conf(void);
void GPIO_Conf(void);
void NVIC_Conf(void);
void EXTI_Conf(void);																			
	
int main(void)
{
  	RCC_Conf();   
  	NVIC_Conf();
  	GPIO_Conf();
  	EXTI_Conf();
	
	SPI_StructInit(&spi);
	spi.SPI_Mode = SPI_Mode_Master;
	spi.SPI_NSS = SPI_NSS_Soft;
	spi.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
	SPI_Init(SPI1, &spi);
	SPI_Cmd(SPI1, ENABLE);
	
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
	if (SysTick_Config(SystemCoreClock / 1000))
			{ 
    /* Przerwanie dzialania, w przypadlu bledu wpada petle */ 
    while (1);
			}
			
		 //Wlacz obsluge wyprowadzenia WKUP (PA0)
  	PWR_WakeUpPinCmd(ENABLE);

  	 //Zezwolenie na dostep do "Backup domain"
  	PWR_BackupAccessCmd(ENABLE);
 
		lcd_setup();
		Delay(1);
		lcd_clear();	
		lcd_draw_text(3,5, "napis testowy");
		lcd_copy();
	
	if(PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)
  	{
		
		// Wyczysc flage PWR_FLAG_SB
		PWR_ClearFlag(PWR_FLAG_SB);
		
		// Czekaj na synchronizacje z APB1
		RTC_WaitForSynchro();
	}
		else
		{
	//System startuje normalnie, wiec nalezy skonfigurowac RTC	

		BKP_DeInit();
		
		// LSE bedzie zrodlem sygnalu zegarowego dla RTC
		RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
		
		// Wlacz taktowanie RTC
		RCC_RTCCLKCmd(ENABLE);
	
		RTC_WaitForLastTask();
		
		// RTC bedzie zliczal pojedyncze sekundy
		RTC_SetPrescaler(32768);
			
	}	
  	while (1)
  	{
  		if(klikniecie == tak)
		{
	Delay(1);
	lcd_clear();			
	lcd_draw_text(2,5, "STANDBY MODE");
			// Wlacz tryb czuwania (standby mode)
		
	lcd_copy();
	klikniecie = nie;
	PWR_EnterSTANDBYMode();
		}	
  	}
}

void RCC_Conf(void)
{  
  	BKP_DeInit();
	
  	// Reset ustawien RCC
  	RCC_DeInit ();

  	// Wlacz HSI
  	RCC_HSICmd(ENABLE);

  	// Czekaj za HSI bedzie gotowy
  	while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET){};

    	FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    	// zwloka dla pamieci Flash
    	FLASH_SetLatency(FLASH_Latency_2);
 	
  		// HCLK = SYSCLK
    
			RCC_HCLKConfig(RCC_SYSCLK_Div2);
  
    	// PCLK2 = HCLK
    	RCC_PCLK2Config(RCC_HCLK_Div1); 

    	// PCLK1 = HCLK
    	RCC_PCLK1Config(RCC_HCLK_Div1);

    	// PLL bedzie zrodlem sygnalu zegarowego
    	RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);
  	
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
}

void GPIO_Conf(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

	GPIO_StructInit(&gpio);
	gpio.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7; // SCK, MOSI
	gpio.GPIO_Mode = GPIO_Mode_AF_PP;
	gpio.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &gpio);

	gpio.GPIO_Pin = LCD_DC|LCD_CE|LCD_RST;
	gpio.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOC, &gpio);
	GPIO_SetBits(GPIOC, LCD_CE|LCD_RST);

	gpio.GPIO_Pin = GPIO_Pin_6;
	gpio.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOB, &gpio);
	
  GPIO_InitTypeDef GPIO_InitStructure;

  // Porty PC13 jako wejscie przycisku z podciaganiem do Vcc
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void EXTI_Conf(void)
{

		EXTI_InitTypeDef EXTI_InitStructure;
  	// Poinformowanie uC o zrodle przerwania
		GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource13);

  	// Bedzie generowane przerwanie na zboczu opadajacym na EXTI_Line0
  	EXTI_InitStructure.EXTI_Line = EXTI_Line0;
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);
}

void NVIC_Conf(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;

	#ifdef  VECT_TAB_RAM  
  		// Jezeli tablica wektorow w RAM, to ustaw jej adres na 0x20000000
  		NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 
	#else  // VECT_TAB_FLASH
  		// W przeciwnym wypadku ustaw na 0x08000000
  		NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   
	#endif

		NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  	NVIC_Init(&NVIC_InitStructure);
}

#ifdef  DEBUG
void assert_failed(uint8_t* file, uint32_t line)
{ 
  	while (1);
}
#endif

Obsługa przerwania od przycisku:

void EXTI0_IRQHandler(void)
{
				if(EXTI_GetITStatus(EXTI_Line0) != RESET)
				{
					// Czyszczenie flagi przerwania
					EXTI_ClearITPendingBit(EXTI_Line0);

					if(!GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13) )
					klikniecie = tak;
					else
					klikniecie = nie;
				}
0

Ło Panie, kto Panu to tak...

#define tak 1
#define nie 0

O stdbool.h słyszał?

Poza tym - po co konfigurujesz RTC jeśli z niego nie korzystasz? Afaik, są przypadki w których RTC potrafi Ci wybudzić procek. Jak jest nieskonfigurowane do końca lub skonfigurowane niepoprawnie, to możesz nie zauważyć nawet trybu standby jak się procek znów obudzi...

0

RTC był pozostałością z innej wersji programu, ok usunąłem wszytko co było z nim związane. Niestety problem dalej pozostaje ten sam.

0

, ale mikrokontroler nie przełącza się w wybrany tryb.

Jak to zaobserwowałeś? Dlaczego akurat wybrałeś tryb standby (najbardziej drastyczny)? Nie wystarczyłby sleep mode? Można np czekać na jakiś event instrukcja __WFE();

0

Mam podłączony miernik do pinu IDD, a STANDBY wybrałem, bo zapewnia najniższe zużycie energii. Tak, wiem, że są inne tryby i jeżeli będę kiedyś potrzebował to też ich użyje, ale póki, co mam problem właśnie z trybem STANDBY.

1 użytkowników online, w tym zalogowanych: 0, gości: 1