이 포스팅에서는 리뷰하고 있는 STEVEL-FCU001V1에서 I2C기능을 추가하는 방법에 대해 기술한다. 먼저 코드 링크와 파일 경로는 다음과 같다.
Code Link :
https://github.com/STMicroelectronics-CentralLabs/ST_Drone_FCU_F401
살펴볼 코드는 Official release with BLE Remocon이며 위치는 다음과 같다.
File Path :
ST_Drone_FCU_F401-master\ST_Drone_FCU_F401-master\STM32 FW Project\Official release with BLE Remocon - 170318\Src
중점적으로 다뤄질 코드는 Src의 main.c, stm32f4xx_hal_msp.c이다. 해당 코드에서 간단히 코드를 추가하면 I2C를 사용할 수 있다.
그리고 중요한 부분이 있는데 다음 경로에 있는 .project 파일에 추가해 줄 것이 있다.
.project의 path는 다음과 같다.
File Path :
ST_Drone_FCU_F401-master\ST_Drone_FCU_F401-master\STM32 FW Project\Official release with BLE Remocon - 170318\SW4STM32\ToyDrone Configuration
이제 I2C를 살려보도록 하자,
I2C를 활성하기 위해서는 stm32f401의 핀의 역할을 잘 확인해보아야 하고 FCC 보드에 어떻게 porting 되어 있는지 확인이 필수적이다.
아래의 그림 ST에서 제공하는 Document에서 찾을 수 있다. 링크는 다음과 같다.
Link :
https://www.st.com/en/evaluation-tools/steval-fcu001v1.html#documentation
File Name :
Getting started with the STEVAL-FCU001V1 flight controller unit evaluation board for mini drones - User manual
그럼 그림을 확인해보자,
Fig 1. STEVAL-FCU001V1 – circuit schematic (2 of 4)
User Manual에서는 위 그림과 같이 PB3와 PB10을 I2C로 사용하고 있다고 명시되어 있다.
하지만 코드상에는 활성화하지 않은 상태이다. 즉 회로적으로 연결을 되어있으므로 소프트웨어적으로 설정하는 코드를 작성하면어 문제 없을것이다.
결과적으로 PB3와 PB10을 각 I2C로 설정하되 PB3를 I2C의 SDA 그리고 PB10을 SCL로 설정하면 된다.
이제 이를 위한 코드를 추가해 보자, stm32f4xx_hal_msp.c로 가보자, 해당 파일의 코드를 보면 센서와의 통신, 모터 제어 신호를 위한 Timer 설정, 제어 주기를 위한 Timer 등등에 대한 핀 설정 함수들이 작성되어 있다(한번 Line-by-Line으로 확인해봐도 좋아요). 이 자체에서 "수정할 내용은 없고" I2C를 설정하는 코드를 "추가" 할 것이다. 아래 코드를 삽입하면 되는데 아무곳에 삽입해도 문제가 없지만 함수 HAL_UART_MspInit 아래 코드를 붙여넣기 하면 된다. 즉 함수 하나 넣는다 생각하면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c) { GPIO_InitTypeDef GPIO_InitStruct; if(hi2c->Instance==I2C2) { /* USER CODE BEGIN I2C2_MspInit 0 */ /* USER CODE END I2C2_MspInit 0 */ /**I2C2 GPIO Configuration PB10 ------> I2C2_SCL PB3 ------> I2C2_SDA */ GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C2; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF9_I2C2; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* Peripheral clock enable */ __I2C2_CLK_ENABLE(); /* USER CODE BEGIN I2C2_MspInit 1 */ /* USER CODE END I2C2_MspInit 1 */ } } | cs |
그럼 stm32f4xx_hal_msp.c에서 볼일은 끝난 것이다.
다음으로 main.c에서 추가해야할 부분을 살펴보자, I2C 설정을 위해 I2C Handler를 생성해야만 한다(Line 24).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | #include "bluenrg_l2cap_aci.h" #include "vl53l5cx_api.h" /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ volatile uint32_t HCI_ProcessEvent=0; uint8_t joydata[8] = {0,0,0,0,0,0,0,0}; uint32_t uhCCR4_Val = 500; uint32_t uhCCR1_Val = 5000; ADC_HandleTypeDef hadc1; SPI_HandleTypeDef hspi1; SPI_HandleTypeDef hspi2; TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim4; TIM_HandleTypeDef htim9; UART_HandleTypeDef huart1; I2C_HandleTypeDef hi2c2;//**추가된 부분 I2C Handler ... ... ... | cs |
그리고 I2C를 상세하게 설정하기 위해 초기화 함수를 생성해주어야한다(Line 5).
| /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_ADC1_Init(void); static void MX_I2C2_Init(void);//I2C 상세 설정을 위한 Initialization Function //static void MX_SPI1_Init(void); //static void MX_SPI2_Init(void); static void MX_TIM2_Init(void); static void MX_TIM4_Init(void); static void MX_TIM9_Init(void); static void MX_USART1_UART_Init(void); | cs |
초기화 함수는 다음과 같은데, 이 함수는 main문 밑에 어딘가에 적절히 복사 붙여넣기 하면 된다. 필자는 MX_ADC1_Init 밑에 추가하였는데 이 함수 또한 main.c 코드의 밑 부분에 찾아보면 나온다(Line 31).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | /* ADC1 init function */ void MX_ADC1_Init(void) { ADC_ChannelConfTypeDef sConfig; /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */ hadc1.Instance = ADC1; hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4; hadc1.Init.Resolution = ADC_RESOLUTION12b; hadc1.Init.ScanConvMode = DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; hadc1.Init.DMAContinuousRequests = DISABLE; hadc1.Init.EOCSelection = EOC_SINGLE_CONV; HAL_ADC_Init(&hadc1); /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_9; sConfig.Rank = 1; sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES; HAL_ADC_ConfigChannel(&hadc1, &sConfig); } /* I2C2 init function */ //MX_ADC1_Init밑에 이 코드를 추가하세요! void MX_I2C2_Init(void) { hi2c2.Instance = I2C2; hi2c2.Init.ClockSpeed = 400000;//SCL Clock Speed 400k[Hz] //Clock speed는 센서마다 요구조건이 다르므로 확인하고 이를 바꾸면된다. hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c2.Init.OwnAddress1 = 0; hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED; hi2c2.Mode = HAL_I2C_MODE_MASTER; hi2c2.Init.OwnAddress2 = 0; hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED; hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED; HAL_I2C_Init(&hi2c2); } | cs |
이로서 코드는 설정이 끝났으며, ".project" 수정만 남았다. 수정을 위해 다음 path로 이동하자
path :
ST_Drone_FCU_F401-master\ST_Drone_FCU_F401-master\STM32 FW Project\Official release with BLE Remocon - 170318\SW4STM32\ToyDrone Configuration
.project를 워드패드(추천)나 메모장으로 열어보자! 다음처럼
Fig 2. .project file open using WordPad
.project에서는 상위폴더에 있는 Src과 Inc에 포함되어있는 코드들을 Linking하는 코드들이 작성되어있다.
파일을 쭉 보다보면 stm32f4xx_hal_spi.c 도 있고 stm32f4xx_hal_tim.c도 있고
stm32f4xx_hal_uart.c도 있을 것이다.
그렇다, 아니? 왜 i2c는 없는거야? 내가 여기 근처에 i2c를 추가하면 되겠지? 라는 생각이 들면된다. 이런 생각이 들었어도 어찌 추가해야하는 거지? 라는 생각이 들 수 있다.
uart도 있으니 i2c도 stm32f4xx_hal에 어딘가에 존재할 것이다. 그러면 stm32f4xx_hal_i2c.c를 추가하면 되는데... 어떻게 넣지?
uart나 spi도 다음과 같은 형식으로 써져있음을 알 수 있다.
| </locationURI> </link> <link> <name>Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_uart.c</name> <type>1</type> <locationURI> PARENT-2-PROJECT_LOC/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c | cs |
그러면 i2c도 이런식으로 작성해서 넣어주면 되겠구나! 필자는 다음과 같이 uart 설정 윗부분에 추가하였다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ..... </locationURI> </link> <link> <name>Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_tim_ex.c</name> <type>1</type> <locationURI> PARENT-2-PROJECT_LOC/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c </locationURI> </link> <link> <name>Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_i2c.c</name> <type>1</type> <locationURI> PARENT-2-PROJECT_LOC/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c</locationURI> </link> <link> <name>Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_uart.c</name> <type>1</type> <locationURI> PARENT-2-PROJECT_LOC/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_uart.c ...... ...... | cs |
이러면 I2C를 FCC에서 쓸 수 있게된것이다. 막혀있던 I2C 길이 열린것
추가 참고자료로 다음에 링크를 남긴다.
1. https://deepbluembedded.com/stm32-i2c-tutorial-hal-examples-slave-dma/
2. https://rs29.tistory.com/2
3.
https://dkeemin.com/stm32f103-i2c-%EA%B8%B0%EC%B4%88%EC%84%A4%EC%A0%95-%EB%B0%8F-%EC%BD%94%EB%93%9C-%EC%A7%9C%EA%B8%B0/
4. https://mokhwasomssi.tistory.com/46
5.
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=eziya76&logNo=221486711330
Comments
Post a Comment