02.07.2012
ZL31ARM: sterowanie kulki i obroty bryły w 3D za pomocą czujnika MEMS LIS35
Konfiguracja linii portów we/wy wykorzystywanych przez joystick, 2 diody, wyświetlacz LCD oraz akcelerometr LIS35 jest zawarta w pliku SystemInit.c:
void GPIO_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; // LCD lines configuration RCC_APB2PeriphClockCmd(RCC_APB2Periph_ctrl, ENABLE); GPIO_InitStructure.GPIO_Pin = DATA | CLK | CS | RES ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(PORT_ctrl, &GPIO_InitStructure); // Joystick direction lines configuration RCC_APB2PeriphClockCmd(RCC_APB2Periph_JOY, ENABLE); GPIO_InitStructure.GPIO_Pin = JOY_UP | JOY_DOWN | JOY_LEFT | JOY_RIGHT; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(JOY_PORT, &GPIO_InitStructure); // Joystick OK line configuration RCC_APB2PeriphClockCmd(RCC_APB2Periph_JOYOK, ENABLE); GPIO_InitStructure.GPIO_Pin = JOY_OK; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(JOY_PORT_OK, &GPIO_InitStructure); // 2 LEDs configuration RCC_APB2PeriphClockCmd(RCC_APB2Periph_LEDs | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin = LED_1 | LED_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(LED_PORT, &GPIO_InitStructure); }
Konfiguracja kontrolera przerwań NVIC:
void NVIC_Configuration(void){ EXTI_InitTypeDef EXTI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; 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 // Wybranie grupy priorytetow NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // Konfiguracja NVIC i wlaczenie obslugi przerwania dla linii INT1 ukladu MEMS 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); // Konfiguracja NVIC i wlaczenie obslugi przerwania dla linii INT2 ukladu MEMS NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); // Konfiguracja wyprowadzenia PA0 i PA1 jako wejscie podciagniete do + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_INT1 | GPIO_Pin_INT2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); // Poinformowanie uC o zrodle przerwania GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0 | GPIO_PinSource1); // Bedzie generowane przerwanie na zboczu opadajacym na EXTI_Line0 i EXTI_Line1 EXTI_InitStructure.EXTI_Line = EXTI_Line0 | EXTI_Line1; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); }
Konfiguracja sygnałów zegarowych:
void RCC_Configuration(void){ ErrorStatus HSEStartUpStatus; //zmienna opisujaca rezultat uruchomienia HSE RCC_DeInit(); //Reset ustawien RCC RCC_HSEConfig(RCC_HSE_ON); //Wlaczenie HSE HSEStartUpStatus = RCC_WaitForHSEStartUp(); //Odczekaj az HSE bedzie gotowy if(HSEStartUpStatus == SUCCESS) { FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); FLASH_SetLatency(FLASH_Latency_2); //ustaw zwloke dla pamieci Flash RCC_HCLKConfig(RCC_SYSCLK_Div1); //ustaw HCLK=SYSCLK RCC_PCLK2Config(RCC_HCLK_Div1); //ustaw PCLK2=HCLK RCC_PCLK1Config(RCC_HCLK_Div2); //ustaw PCLK1=HCLK/2 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //ustaw PLLCLK = HSE(8MHz)*9 RCC_PLLCmd(ENABLE); //wlacz PLL while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //odczekaj uruchomienie PLL RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //PLL jako zrodlo sygnalu zegarowego while(RCC_GetSYSCLKSource()!=0x08);//odczekaj az PLL bedzie sygnalem zegarowym systemu } }