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;
}