LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

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
  }
}
Autor: Jan Szemiet