[ST_MICRO]/STM32G2018. 12. 14. 05:11

#STM32G030 EVM - I2C 테스트 (TMP275 온도 센서의 온도 측정)

#STM32G030 EVM - I2C 테스트 (TMP275 온도 센서의 온도 측정)


STM32G-SSM EVM 보드는 표준 핀맵을 통일화 해서 다양한 확장보드에 공용으로 테스트 할 수 있도록 제작한 보드 이다. I2C도 핀 맵핑에 따라 동일한 위치에서 테스트 가능하다.



SSM EVM표준 핀맵




SSM EVM 확장 테스트 보드 연결

SSM EVM 표준 핀맵을 테스트 할수 있는 다양한 확장 테스트 보드를 이용해서 I2C 테스트를 진행 해 볼수 있다. 

우선 I2C로 온도 값을 읽을 수 있는 TMP275 온도 센서 모듈을이용하여 SSM EVM 확장 테스트 보드에 연결하여 I2C를 테스트 해 보자.





STM32CubeIDE를 이용하여 기본 핀맵 설정하고 I2C 셋팅을 한 후 코드 생성하면 자동으로 I2C 설정 코드가 생성된다.


SSM EVM 핀맵에 맞도록 STM32G031에서 I2C1을 PA12(SDA), PA11(SCL)에 할당 했다.






생성된 코드를 이용하여 TMP275에서 온도 값을 읽어 오는 코드를 추가 해주면 I2C로 TMP275의 온도 값을 읽어 올 수 있다.


#define _TMP275_ADDRESS                 (0x48<<1)
#define _TMP275_REG_CONFIG              1
#define _I2C_DELAY_TIME                 1000
#define I2C_HANLDLE                     hi2c2

unsigned int read16(unsigned char addr, unsigned char data)
{
    unsigned char buf[2];

    HAL_I2C_Master_Transmit(&I2C_HANLDLE, addr, &data, 1, _I2C_DELAY_TIME);
    HAL_I2C_Master_Receive(&I2C_HANLDLE, addr|0x01, buf, 2, _I2C_DELAY_TIME);
    return (buf[0]<<8|buf[1]);

}




  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C2_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
         x = (read16(_TMP275_ADDRESS, 0)>>4)%0xFFF;

         printf("%.2f\r\n", (float)x/16.0);
         HAL_Delay(500);
    /* USER CODE BEGIN 3 */

  }





STM32G 시리즈에서 TMP275 온도 센서 모듈을 이용하여 간단히 I2C 테스트를 진행해 보았다. STM32CubeIDE를 이용하니 코어가 바뀌어도 별다른 설정없이 I2C를 테스트 할 수 있어 편리한것 같다.




Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM32G2018. 12. 14. 05:10

#STM32G030 EVM - UART 테스트 (STM32CubeIDE 에서 printf 사용하기)

#STM32G030 EVM -  UART 테스트 (STM32CubeIDE  에서 printf 사용하기)





STM32g030F6에는 3채널의 UART포트가 있고 UART1(Tx-PB3, Rx-PB7) 포트가 보드상의 UART커넥터에 할당되어 있다.





STM32CubeIDE에서 새로운 프로젝트를 생성하고 UART탭의 핀맵과 보레이트 등을 설정한다.






STM32CubeIDE 로 코드 생성하면 자동 코드가 생성되고 기존 STM32 HAL코드와 동일하게 작성하면 UART 통신 테스트를 할 수 있다.



int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_UART_Transmit( &huart1, "STM32G-SSM EVM", 1, 100);
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

}




STM32CubeIDE  에서 printf 사용하기


STM32CubeIDE 에서 printf 를 사용하려면 _wrte 함수를 재 정의 해 주면 된다.


#define hUART           huart1
int _write( int32_t file , uint8_t *ptr , int32_t len )
{
    /* Implement your write code here, this is used by puts and printf for example */
    for ( int16_t i = 0 ; i < len ; ++i )
    {
        HAL_UART_Transmit( &hUART, ptr++, 1, 100);
    }
    return len;

}




printf 로 간단히 카운트 값을 증가 하는 코드 작성해서 테스트 해 보니 잘 동작한다.


  while (1)
  {
    /* USER CODE END WHILE */
    printf("%d\r\n", cnt++);
    HAL_Delay(100);
    /* USER CODE BEGIN 3 */

  }


Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM32G2018. 12. 10. 00:50

#STM32G0 STM32CubeIDE Timer Test - 1% HSI 이용

#STM32G0 STM32CubeIDE Timer Test  - 1% HSI 이용


STM32G0 스펙을 보면 HSI클럭 부분에서 1%를 강조 하고 있다. 기존 칩보다 강점 이라고 내새우니 한번 테스트 해 봐야 겠다.



Core: Arm® 32-bit Cortex®-M0+ CPU, frequency up to 64 MHz
-40°C to 85°C/125°C operating temperature
Up to 64 Kbytes of Flash memory
8 Kbytes of SRAM with HW parity check

Voltage range: 1.7 V to 3.6 V

4 to 48 MHz crystal oscillator
32 kHz crystal oscillator with calibration
Internal 16 MHz RC with PLL option (±1 %)
Internal 32 kHz RC oscillator (±5 %)

12-bit, 0.4 μs ADC (up to 16 ext. channels)
Up to 16-bit with hardware oversampling
Conversion range: 0 to 3.6V





STM32CubeIDE 를 이용하여 Timer14를 활성화 한다.






STM32 CubeIDE를 이용해서 코드 생성하면 생성되는 코드에 적절한 값을 설정해서 1ms 타이머를 하나 만든다.


static void MX_TIM14_Init(void)

{
  /* USER CODE BEGIN TIM14_Init 0 */
  /* USER CODE END TIM14_Init 0 */
  /* USER CODE BEGIN TIM14_Init 1 */
  /* USER CODE END TIM14_Init 1 */
  htim14.Instance = TIM14;
  htim14.Init.Prescaler = 64-1;
  htim14.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim14.Init.Period = 1000-1;
  htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim14) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM14_Init 2 */
  /* USER CODE END TIM14_Init 2 */
}



Timer14 타이머 인터럽트 핸들러를 생성하고 주기적으로 GPIO PA5를 토글하도록 했다.

#define TIM_HANDLE                       htim14
volatile uint32_t gTimeTick = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == TIM_HANDLE.Instance)
    {
       gTimeTick++;
       GPIOA->ODR ^= GPIO_PIN_5;
    }

}




타이머 Start 함수를 호출하면 PA5(LED)가 토글되는것을 확인 할 수 있다.

HAL_TIM_Base_Start_IT(&TIM_HANDLE);






1.995ms가 출력된다.

외부에 크리스털 발진기를 연결하는 것 보다는 정확하지는 않지만 스팩에 나와 있는 1% 범위 안에는 들어오는것 같다.





그러면 기존 STM32F 시리즈의 스펙을 한번 살펴보자

25도 범위에서는 비슷한 오차 인것 같고 -40~85도에서는 5% 오차를 보인다고 한다. 스펙상으로는 STM32G시리즈가 많이 좋아 보인다.




그럼 STM32F0 보드에서 동일한 코드를 실행해 보자.

1.991ms 가 출력된다. 

조금 좋아 진것 같긴하다. 이정도는 환경에 따라 달라질 수 있는 것으로 판단되긴 한데...

아무튼 기존 보다는 좋지 않을까...










Posted by nexp
TAG STM32G

댓글을 달아 주세요

[ST_MICRO]/STM32H72018. 12. 6. 05:33

STMH7 EVM - USB Mass Storage Host Mode 테스트


STMH7 EVM - USB Mass Storage Host Mode 테스트





STM32H7 EVM 보드에는 USB Host 및 Device를 테스트 할 수 있는 커넥터가 있다.


CubeMX로 USB HOST 모드 설정







USB_HOST 모드설정을 Mass Storage Host Class 로 설정한다.

VBUS 파워 공급을 GPIO로 설정 할 수도 있지만 이번에는 그냥 하드웨어 적으로 Host Mode 고정으로 전원을 강제로 공급하도록 했다.






CubeMX에서  FATFS 설정은 USB Disk로 설정한다.






이렇게 CubeMX 설정으로 마무리 하여 코드를 생성하면 대부분 자동으로 생성이 된다.

생성된 코드에서 수정 할 부분을 usb_host.c 파일의 USBH_UserProcess() 함수에 추가하면 된다.


main 함수에서 주기적으로 수행하면서 처리되는 함수 인데 테스트를 위해 HOST_USER_CLASS_ACTIVE 이벤트에서 디렉토리 내용을 출력하도록 했다.

static void USBH_UserProcess  (USBH_HandleTypeDef *phost, uint8_t id)
{
  /* USER CODE BEGIN CALL_BACK_1 */
  switch(id)
  {
         case HOST_USER_SELECT_CONFIGURATION:
                printf("CONFIGURATION\r\n");
                break;
         case HOST_USER_DISCONNECTION:
                Appli_state = APPLICATION_DISCONNECT;
 
                printf("DISCONNECTION\t\n");
                break;
         case HOST_USER_CLASS_ACTIVE:
                Appli_state = APPLICATION_READY;
                printf("APPLICATION_READY\r\n");

                f_opendir_scan_usb();
                break;
         case HOST_USER_CONNECTION:
                Appli_state = APPLICATION_START;
                printf("CONNECTION\r\n");
                break;
  default:
  break;
  }
  /* USER CODE END CALL_BACK_1 */

}




void f_opendir_scan_usb(void)
{
    DIR dir;
       FILINFO fno;
    TCHAR path[200] = "0:";

    res = f_mount(&fat32,path,0);
    printf("USB Mount : res f_mount : %d\r\n",res);
    if (res == FR_OK)
    {
    res = f_opendir(&dir,path);
        printf("res f_open : %02X\n\r",res);
        if (res == FR_OK)
        {
        while(1)
        {
            char *fn;
            res = f_readdir(&dir, &fno);
            if (res != FR_OK)
                printf("res = %d f_readdir\n\r", res);
            if ((res != FR_OK) || (fno.fname[0] == 0))
                break;
      */
      fn = fno.fname;
            printf("%c%c%c%c ",
                ((fno.fattrib & AM_DIR) ? 'D' : '-'),
                ((fno.fattrib & AM_RDO) ? 'R' : '-'),
                ((fno.fattrib & AM_SYS) ? 'S' : '-'),
                ((fno.fattrib & AM_HID) ? 'H' : '-') );
            printf("%10d ", fno.fsize);
            printf("%s/%s\n\r", path, fn);
        }
        }
        res = f_mount(0,path,0);
        printf("USB Unmount : res f_mount : %02X\n\r",res);
    }

}


테스트 해 보면 STM32H7 EVM 보드에 USB 메모리 스틱을 연결하면 인식해서 메모리 스틱의 파일 목록을 보여 주고 있다.




Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM32H72018. 12. 4. 02:02

STM32H7 CubeMx SD Card Test

STM32H7 CubeMx SD Card Test


[STM32H7 EVM] 보드에는 4bit SD 인터페이스가 있어 SD카드 FAT 연결 테스트를 Stm32CubeMx를 이용하여 해 보았다.


우선 SD카드는 하드웨어 적으로 STM32H7의 디폴트 SDMMC1에 연결되어 있다.


STM32H7 EVM보드는에 아래면에 SD소켓이 장착되어 있다.







STM32CubeMx 를 이용하여 SDMMC1을 SD 4bit 모드로 선택한다.






Middleware 탭의 FATFS에서 Mode를 SD Card로 선택 한다.




이렇게 해서 기본으로 코드 생성하면 아래와 같은 코드가 생성 되는데... 



주의 해야 할 사항은 bsp_driver_sd.c 파일에 있는 BSP_SD_Init() 함수를 호출 해 주어야 한다는 것이다.


int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
  /* USER CODE BEGIN Init */
  /* USER CODE END Init */
  /* Configure the system clock */
  SystemClock_Config();
  /* USER CODE BEGIN SysInit */
  /* USER CODE END SysInit */
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM3_Init();
  MX_USART1_UART_Init();
  MX_SDMMC1_SD_Init();
  MX_FATFS_Init();
  /* USER CODE BEGIN 2 */
  BSP_SD_Init();
  /* USER CODE END 2 */
  //disk_initialize((BYTE) 0);
  f_opendir_scan_sd();
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

}




SD를 4bit 모드로 변환 해 주는 부분이다.


uint8_t BSP_SD_Init(void)
{
  uint8_t sd_state = MSD_OK;
  /* Check if the SD card is plugged in the slot */
  if (BSP_SD_IsDetected() != SD_PRESENT)
  {
    return MSD_ERROR_SD_NOT_PRESENT;
  }
  /* HAL SD initialization */
  sd_state = HAL_SD_Init(&hsd1);
  /* Configure SD Bus width (4 bits mode selected) */
  if (sd_state == MSD_OK)
  {
    /* Enable wide operation */
    if (HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B) != HAL_OK)
    {
      sd_state = MSD_ERROR;
    }
  }
  return sd_state;

}






SD 카드 읽어 파일 내용을 출력 해주면 쉽게 SD카드 테스트 완료


void f_opendir_scan_sd(void)

{
    DIR dir;
       FILINFO fno;
    TCHAR path[200] = "0:";

    res = f_mount(&SDFatFS,path,0);
    printf("SD Mount : res f_mount : %02X\n\r",res);
    if (res == FR_OK)
    {
    res = f_opendir(&dir,path);
        printf("res f_open : %02X\n\r",res);
        if (res == FR_OK)
        {
        while(1)
        {
            char *fn;
            res = f_readdir(&dir, &fno);
            if (res != FR_OK)
                printf("res = %d f_readdir\n\r", res);
            if ((res != FR_OK) || (fno.fname[0] == 0))
                break;

      fn = fno.fname;
            printf("%c%c%c%c ",
                ((fno.fattrib & AM_DIR) ? 'D' : '-'),
                ((fno.fattrib & AM_RDO) ? 'R' : '-'),
                ((fno.fattrib & AM_SYS) ? 'S' : '-'),
                ((fno.fattrib & AM_HID) ? 'H' : '-') );
            printf("%10d ", fno.fsize);
            printf("%s/%s\n\r", path, fn);
        }
        }
        res = f_mount(0,path,0);
        printf("SD Unmount : res f_mount : %02X\n\r",res);
    }
}












Posted by nexp

댓글을 달아 주세요