[STM32F439 EVM] I2C 테스트

[ST_MICRO]/STM32F43x | 2016.12.31 12:51
Posted by nexp

[STM32F439 EVM] I2C 테스트




[STM32F439 EVM] 에는 PB8(SCL), PB9(SDA)에 I2C가 할당되어 있다.




STM32F439 I2C 초기화 코드

I2C_HandleTypeDef I2cHandle;


#define I2Cx                             I2C1

#define I2Cx_CLK_ENABLE()                __I2C1_CLK_ENABLE()

#define I2Cx_SDA_GPIO_CLK_ENABLE()       __GPIOB_CLK_ENABLE()

#define I2Cx_SCL_GPIO_CLK_ENABLE()       __GPIOB_CLK_ENABLE() 


#define I2Cx_FORCE_RESET()               __I2C1_FORCE_RESET()

#define I2Cx_RELEASE_RESET()             __I2C1_RELEASE_RESET()


/* Definition for I2Cx Pins */

#define I2Cx_SCL_PIN                    GPIO_PIN_8

#define I2Cx_SCL_GPIO_PORT              GPIOB

#define I2Cx_SCL_AF                     GPIO_AF4_I2C1

#define I2Cx_SDA_PIN                    GPIO_PIN_7

#define I2Cx_SDA_GPIO_PORT              GPIOB

#define I2Cx_SDA_AF                     GPIO_AF4_I2C1


void I2CMaster_Init(void)

{

  GPIO_InitTypeDef  GPIO_InitStruct;

  

  /*##-1- Enable peripherals and GPIO Clocks #################################*/

  /* Enable GPIO TX/RX clock */

  I2Cx_SCL_GPIO_CLK_ENABLE();

  I2Cx_SDA_GPIO_CLK_ENABLE();

  /* Enable I2C1 clock */

  I2Cx_CLK_ENABLE(); 

  

  /*##-2- Configure peripheral GPIO ##########################################*/  

  /* I2C TX GPIO pin configuration  */

  GPIO_InitStruct.Pin       = I2Cx_SCL_PIN;

  GPIO_InitStruct.Mode      = GPIO_MODE_AF_OD;

  GPIO_InitStruct.Pull      = GPIO_PULLUP;

  GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;

  GPIO_InitStruct.Alternate = I2Cx_SCL_AF;

  

  HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct);

    

  /* I2C RX GPIO pin configuration  */

  GPIO_InitStruct.Pin = I2Cx_SDA_PIN;

  GPIO_InitStruct.Alternate = I2Cx_SDA_AF;

    

  HAL_GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct);

  

  

  I2cHandle.Instance             = I2Cx;

  

  I2cHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;

  I2cHandle.Init.ClockSpeed      = 100000;

  I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;

  I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;

  I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_ENABLED;

  I2cHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLED;

  I2cHandle.Init.OwnAddress1     = 0xFE;//I2C_ADDRESS<<1;

  I2cHandle.Init.OwnAddress2     = 0xFE;    

  

  

  HAL_I2C_Init(&I2cHandle);

}




STM32F439 I2C Read/Write 함수

HAL_I2C_Master_Transmit(),  HAL_I2C_Master_Receive() 함수를 사용하면 쉽게 I2C제어가 가능하다.

unsigned char read8(unsigned char addr, unsigned char data)

{

    unsigned char result;


    unsigned char tx_buf[2];

    unsigned char rx_buf[4];

    tx_buf[0] = data;

    

    

    //gTimerTick6 = 0;

    while(HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)addr, (uint8_t*)tx_buf, 1, 10000)!= HAL_OK)

    {

        //if(gTimerTick6>200)break;

    }

    

    //gTimerTick6 = 0;


    while(HAL_I2C_Master_Receive(&I2cHandle, (uint16_t)addr, (uint8_t *)rx_buf, 1, 10000) != HAL_OK)

    {

//if(gTimerTick6>200)break;

    }

  


    result = rx_buf[0];



    return result;


}


void write8(unsigned char addr, unsigned char reg, unsigned char data)

{

    unsigned char result;


    unsigned char tx_buf[2];

    unsigned char rx_buf[4];

    tx_buf[0] = reg;

tx_buf[1] = data;

    

    

    //gTimerTick6 = 0;

    while(HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)addr, (uint8_t*)tx_buf, 2, 10000)!= HAL_OK)

    {

        //if(gTimerTick6>200)break;

    }

}


[PIC32MZ EVM] 타이머 인터럽트 테스트


PIC32MZ 시리즈의 타이머/카운터는 9개가 있고 MPLAB 코드 생성 툴을 이용하면 쉽게 사용 할 수 있다.

한가지 아쉬운점은 기본 16비트 타이머 이고 32비트 타이머를 사용하려면 16비트 타이머2개를 조합해서 사용해야 되는것 같다.

STM32의 경우 별도의 32비트 타이머가 존재해서 편리 했는데...



MPLAB Harmony Configurator  를 이용하여 타이머드라이버 생성 할 수 있고 각종 파라미터를 설정하면 쉽게 초기화 할 수 있다.



자동으로 생성된 코드를 보면 아래와 같이 PIC32MZ의 타이머 설정부분의 코드가 생성된다.

void SYS_Initialize ( void* data )

{

    /* Core Processor Initialization */

    SYS_CLK_Initialize( NULL );

    sysObj.sysDevcon = SYS_DEVCON_Initialize(SYS_DEVCON_INDEX_0, (SYS_MODULE_INIT*)&sysDevconInit);

    SYS_DEVCON_PerformanceConfig(SYS_CLK_SystemFrequencyGet());

    SYS_PORTS_Initialize();


    /* Initialize Drivers */


    sysObj.drvTmr0 = DRV_TMR_Initialize(DRV_TMR_INDEX_0, (SYS_MODULE_INIT *)&drvTmr0InitData);


    SYS_INT_VectorPrioritySet(INT_VECTOR_T1, INT_PRIORITY_LEVEL1);

    SYS_INT_VectorSubprioritySet(INT_VECTOR_T1, INT_SUBPRIORITY_LEVEL0);

 

 

     sysObj.drvUsart0 = DRV_USART_Initialize(DRV_USART_INDEX_0, (SYS_MODULE_INIT *)&drvUsart0InitData);

    SYS_INT_VectorPrioritySet(INT_VECTOR_UART1_TX, INT_DISABLE_INTERRUPT);

    SYS_INT_VectorSubprioritySet(INT_VECTOR_UART1_TX, INT_SUBPRIORITY_LEVEL0);

    SYS_INT_VectorPrioritySet(INT_VECTOR_UART1_RX, INT_PRIORITY_LEVEL1);

    SYS_INT_VectorSubprioritySet(INT_VECTOR_UART1_RX, INT_SUBPRIORITY_LEVEL0);

    SYS_INT_VectorPrioritySet(INT_VECTOR_UART1_FAULT, INT_PRIORITY_LEVEL1);

    SYS_INT_VectorSubprioritySet(INT_VECTOR_UART1_FAULT, INT_SUBPRIORITY_LEVEL0);


    /* Initialize System Services */


    /*** Interrupt Service Initialization Code ***/

    SYS_INT_Initialize();

  

    /* Initialize Middleware */


    /* Enable Global Interrupts */

    SYS_INT_Enable();


    /* Initialize the Application */

    APP_Initialize();

}





PIC32MZ 타이머 기본 설정 이외 인터럽터 핸들러 생성 및  등록은 초기화 코드에서 해 주어야 한다.


SYS_MODULE_OBJ T0Handle ;


void APP_Initialize ( void )

{

    /* Place the App state machine in its initial state. */

    appData.state = APP_STATE_INIT;


    printf("PIC32MZ EVM Timer Test\r\n");


    

   T0Handle = DRV_TMR_Open( DRV_TMR_INDEX_0, DRV_IO_INTENT_EXCLUSIVE );

 

   // calculate the divider value and register the ISR

   uint32_t desiredFrequency = 1000 ; // 1 khertz

   uint32_t actualFrequency = DRV_TMR_CounterFrequencyGet(T0Handle) ;

   uint32_t divider = actualFrequency/desiredFrequency; // cacluate divider value

  

   DRV_TMR_AlarmRegister(T0Handle, divider, true, 0 , T0_ISRHandler);

 

   // Starting the Timer   

   DRV_TMR_Start(T0Handle);    

}





PIC32MZ  타이머 인터럽트 핸들러 함수


void T0_ISRHandler(uintptr_t context, uint32_t alarmCount)

{

   PLIB_PORTS_PinToggle(PORTS_ID_0, PORT_CHANNEL_H, 10 );

}






[PIC32MZ EVM] UART 테스트

[Microchip]/PIC32MZ | 2016.12.25 01:21
Posted by nexp

[PIC32MZ EVM] UART 테스트




PIC32MZ에서 UART를 사용하려면 MPLAB Harmony Configurator 를 실행해서 UART를 활성화 하고 설정해 주면 쉽게 사용가능하다.






[PIC32MZ EVM] 보드의 UART는 RD14->TXD, RD15-RXD에 할당되어 있다.

핀 다이어그램 에서 원하는 핀을 클릭해서 설정 할 수 있다.



그러면 아래와 같은 코드들을 자동으로 생성해 준다.

void SYS_Initialize ( void* data )

{

    /* Core Processor Initialization */

    SYS_CLK_Initialize( NULL );

    sysObj.sysDevcon = SYS_DEVCON_Initialize(SYS_DEVCON_INDEX_0, (SYS_MODULE_INIT*)&sysDevconInit);

    SYS_DEVCON_PerformanceConfig(SYS_CLK_SystemFrequencyGet());

    SYS_PORTS_Initialize();


    /* Initialize Drivers */

    sysObj.drvUsart0 = DRV_USART_Initialize(DRV_USART_INDEX_0, (SYS_MODULE_INIT *)&drvUsart0InitData);

    SYS_INT_VectorPrioritySet(INT_VECTOR_UART1_TX, INT_DISABLE_INTERRUPT);

    SYS_INT_VectorSubprioritySet(INT_VECTOR_UART1_TX, INT_SUBPRIORITY_LEVEL0);

    SYS_INT_VectorPrioritySet(INT_VECTOR_UART1_RX, INT_PRIORITY_LEVEL1);

    SYS_INT_VectorSubprioritySet(INT_VECTOR_UART1_RX, INT_SUBPRIORITY_LEVEL0);

    SYS_INT_VectorPrioritySet(INT_VECTOR_UART1_FAULT, INT_PRIORITY_LEVEL1);

    SYS_INT_VectorSubprioritySet(INT_VECTOR_UART1_FAULT, INT_SUBPRIORITY_LEVEL0);


    /* Initialize System Services */


    /*** Interrupt Service Initialization Code ***/

    SYS_INT_Initialize();

  

    /* Initialize Middleware */


    /* Enable Global Interrupts */

    SYS_INT_Enable();


    /* Initialize the Application */

    APP_Initialize();

}




void SYS_PORTS_Initialize(void)

{

    /* PORT D Initialization */

    PLIB_PORTS_OpenDrainEnable(PORTS_ID_0, PORT_CHANNEL_D, SYS_PORT_D_ODC);

    PLIB_PORTS_Write( PORTS_ID_0, PORT_CHANNEL_D,  SYS_PORT_D_LAT);

    PLIB_PORTS_DirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_D,  SYS_PORT_D_TRIS ^ 0xFFFF);

    PLIB_PORTS_ChangeNoticePerPortTurnOn(PORTS_ID_0, PORT_CHANNEL_D);

    PLIB_PORTS_ChannelModeSelect(PORTS_ID_0, PORT_CHANNEL_D, SYS_PORT_D_ANSEL ^ 0xFFFF, PORTS_PIN_MODE_DIGITAL);

    PLIB_PORTS_ChannelChangeNoticeEnable(PORTS_ID_0, PORT_CHANNEL_D, SYS_PORT_D_CNEN);

    PLIB_PORTS_ChannelChangeNoticePullUpEnable(PORTS_ID_0, PORT_CHANNEL_D, SYS_PORT_D_CNPU);

    PLIB_PORTS_ChannelChangeNoticePullDownEnable(PORTS_ID_0, PORT_CHANNEL_D, SYS_PORT_D_CNPD);

    

    /* PORT H Initialization */

    PLIB_PORTS_OpenDrainEnable(PORTS_ID_0, PORT_CHANNEL_H, SYS_PORT_H_ODC);

    PLIB_PORTS_Write( PORTS_ID_0, PORT_CHANNEL_H,  SYS_PORT_H_LAT);

    PLIB_PORTS_DirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_H,  SYS_PORT_H_TRIS ^ 0xFFFF);

    PLIB_PORTS_ChangeNoticePerPortTurnOn(PORTS_ID_0, PORT_CHANNEL_H);

    PLIB_PORTS_ChannelModeSelect(PORTS_ID_0, PORT_CHANNEL_H, SYS_PORT_H_ANSEL ^ 0xFFFF, PORTS_PIN_MODE_DIGITAL);

    PLIB_PORTS_ChannelChangeNoticeEnable(PORTS_ID_0, PORT_CHANNEL_H, SYS_PORT_H_CNEN);

    PLIB_PORTS_ChannelChangeNoticePullUpEnable(PORTS_ID_0, PORT_CHANNEL_H, SYS_PORT_H_CNPU);

    PLIB_PORTS_ChannelChangeNoticePullDownEnable(PORTS_ID_0, PORT_CHANNEL_H, SYS_PORT_H_CNPD);



    /* PPS Input Remapping */

    PLIB_PORTS_RemapInput(PORTS_ID_0, INPUT_FUNC_U1RX, INPUT_PIN_RPD14 );


    /* PPS Output Remapping */

    PLIB_PORTS_RemapOutput(PORTS_ID_0, OUTPUT_FUNC_U1TX, OUTPUT_PIN_RPD15 );

}






PIC32MZ UART 송수신 함수


void U0_PutByte (char chr)

{

   PLIB_USART_TransmitterByteSend (DRV_USART_INDEX_0, chr); 

   //U4TXREG = chr;


   while (! PLIB_USART_TransmitterIsEmpty (DRV_USART_INDEX_0));

  //while (! U4STAbits.TRMT); 

}



unsigned char U0_GetByte (char chr)

{

    while(!PLIB_USART_ReceiverDataIsAvailable(DRV_USART_INDEX_0));

    //while(U1STAbits.URXDA == 0);

    

    return PLIB_USART_ReceiverByteReceive(DRV_USART_INDEX_0);

}







XC32 컴파일러에서 printf 함수를 사용하고 싶다면 _mon_putc() 함수를 재정의 해 주면 사용할 수 있다.


void _mon_putc(char c)

{

     U0_PutByte(c);






TAG PIC32MZ, UART

PIC32MZ 개발 환경 설정

[Microchip]/PIC32MZ | 2016.12.25 01:20
Posted by nexp

PIC32MZ 개발 환경 설정




PIC32MZ 개발을 위해서는  MCU펌웨어 개발 프레임워크인 MPLAB® Harmony 라는 툴이 필요하다.

이거 언제 또 공부하나?


그런데 막상 사용해 보니 상당히 간단하고 편리한것 같다.


우선 프로그램을 다운로드 하고 설치 해보자

MPLAB

http://www.microchip.com/mplab/mplab-ide-home


하모니 페키지

http://www.microchip.com/mplab/mplab-harmony




MPLABX 프로그램 실행하고 새로운 프로젝트롤 생성한다.

하모니 프로젝트를 선택하고 위자드로 클릭 몇번하면 쉽게 새로운 프로젝트 생성이 가능하다.






디바이스 선택

[PIC32MZ EVM] 보드는 PIC32MZ 시리즈 PIC32MZ2048EFM144 이므로 이 장치를 선택한다.





생성이 되면 기본으로 MPLAB Harmony Configurator 가 실행되고 다양한 페리 설정을 간편하게 할수 있다.




PIC32MZ 구동에 기본이 되는 클럭 설정을 해 보면 아래 그림과 같이 클럭 소스나, 속도 및 다양한 설정을 쉽게 설정 할 수 있다.





이렇게 해서 코드를 생성하면 자동으로 아래와 같은 파일들을 생성해 준다.




생성된 파일중 app.c 파일을 수정하면 원하는 기능을 수행 할 수 있다.

초기화 함수

void APP_Initialize ( void )

{

    /* Place the App state machine in its initial state. */

    appData.state = APP_STATE_INIT;


    /* TODO: Initialize your application's state machine and other

     * parameters.

    */

}





그리고 APP_Tasks() 함수에서 사용자 코드를 작성해 주면 된다. RTOS 같은 구조 인데 실제는 RTOS는 아니고 추후 RTOS를 사용 하더라고 동일한 구조를 사용하기 위해 이런 형태의 코드가 생성되는것 같다.

코드의 호환성은 좋아지겠지만 성능 측면은 양보를 해야 할것 같다. 물론 PIC32MZ 속도가 200Mhz로 구동되기 때문에 큰 차이는 없어 보인다.


간단한 예제로 [PIC32MZ EVM] 보드의 LED를 깜박이는 예제를 작성해 보면 아래와 같다.

void APP_Tasks ( void )

{


    /* Check the application's current state. */

    switch ( appData.state )

    {

        /* Application's initial state. */

        case APP_STATE_INIT:

        {

            bool appInitialized = true;

       

            if (appInitialized)

            {

            

                appData.state = APP_STATE_SERVICE_TASKS;

            }

            break;

        }


        case APP_STATE_SERVICE_TASKS:

        {

            //사용자 코드 작성 부분

            PLIB_PORTS_PinToggle(PORTS_ID_0, PORT_CHANNEL_H, 10 );

            Delay(100);

            break;

        }


        /* TODO: implement your application state machine.*/

        


        /* The default state should never be executed. */

        default:

        {

            /* TODO: Handle error in application's state machine. */

            break;

        }

    }

}




참고로 MPLAB Harmony Configurator에서 GPIO설정을 해 주면 초기화 코드를 생성해 준다.





MPLAB Harmony Configurator 는 Tools 메뉴에서 실행 할 수 있다. (처음에 이창이 사라져서 찾기 힘들었다.)




sys_ports_static.c 파일을 보면 GPIO관련 초기화된 코드가 생성된것을 확인 할 수 있다.


void SYS_PORTS_Initialize(void)

{

    /* PORT H Initialization */

    PLIB_PORTS_OpenDrainEnable(PORTS_ID_0, PORT_CHANNEL_H, SYS_PORT_H_ODC);

    PLIB_PORTS_Write( PORTS_ID_0, PORT_CHANNEL_H,  SYS_PORT_H_LAT);

    PLIB_PORTS_DirectionOutputSet( PORTS_ID_0, PORT_CHANNEL_H,  SYS_PORT_H_TRIS ^ 0xFFFF);

    PLIB_PORTS_ChangeNoticePerPortTurnOn(PORTS_ID_0, PORT_CHANNEL_H);

    PLIB_PORTS_ChannelModeSelect(PORTS_ID_0, PORT_CHANNEL_H, SYS_PORT_H_ANSEL ^ 0xFFFF, PORTS_PIN_MODE_DIGITAL);

    PLIB_PORTS_ChannelChangeNoticeEnable(PORTS_ID_0, PORT_CHANNEL_H, SYS_PORT_H_CNEN);

    PLIB_PORTS_ChannelChangeNoticePullUpEnable(PORTS_ID_0, PORT_CHANNEL_H, SYS_PORT_H_CNPU);

    PLIB_PORTS_ChannelChangeNoticePullDownEnable(PORTS_ID_0, PORT_CHANNEL_H, SYS_PORT_H_CNPD);






마이크로 칩사의 새로운 IDE툴인 MPLABX와 하모니 툴을 이용하여 PIC32MZ 개발 환경을 테슽 해 보았는데...

결론적으로는 상당히 잘 만들어진 툴 같고 편리한것 같다.

특히 USB나 이더넷, TFT LCD같은 복잡한 페리를 사용하는데 있어서 자동 코드 생성툴이 상당히 편리 한것 같은데 마이크로 칩에서 제공하는 기본 구조를 지켜야 한다는 제약이 어떤 문제가 있을지 좀더 테스트 해 보아야 할것 같다.


쉽고 빠르게 기본 구조를 생성 할 수 있다는 점은 상당히 마음에 든다.





[PIC32MZ EVM] 보드 제작 - PIC32MZ2048EFM14



마이크로칩사의 PIC32MZ 시리즈 테스트 보드를 제작 했다. 200 MHz/330 DMIPS, microAptiv core 32bit MCU로 PIC시리즈 중 최고 사양의 MCU이다.


[L-Type EVM] 형태로 표준화 된 핀맵으로 제작 하여 여러 확장 보드에서 쉽게 테스트 가능하도록 했다.



L-Type 확장 테스트 보드










[PIC32MZ EVM] 핀맵 회로도











PIC32MZ 시리즈 검토

[Microchip]/PIC32MZ | 2016.12.22 23:02
Posted by nexp

마이크로 칩사에서 32 비트 MCU PIC32MZ 시리즈가 출시 되었다.

PIC32MZ 임베디드 연결 기능(EC) 제품군은 330DMIPS와 3.28 CoreMarks/MHz 속도를 지원하고, 최신 애플리케이션 대응을 위해 듀얼 패널, 최대 2MB의 라이브 업데이트 플래시, 512 KB의 대형 RAM을 지원한다.


차량용 인증등급인 AEC-Q100을 지원하는 PIC32MZ EF 시리즈도 동일하게 사용할수 있어서 차량용 제품 개발의  인증문제를 해결 할 수도 있다.

PIC32MZ EF 제품군은 최대 250MHz의 우수한 코어 성능, 부동소수점 유닛(FPU), 다양한 주변장치와 함께 CAN(Controller Area Network) 등의 뛰어난 연결 옵션을 제공한다. 이 확장 온도 지원 제품은 고온에서도 신뢰성 높은 성능과 강건성을 필요로 하는 다양한 주요 자동차 및 산업용 애플리케이션에 적합하다.



PIC32MZ 제품군은 마이크로칩의 MPLAB® Harmony 통합 소프트웨어 프레임워크, MPLAB X 통합 개발 환경(IDE), PIC32용 MPLAB XC32 컴파일러, MPLAB ICD 3 인-서킷 디버거, MPLAB Real ICE™ 인-서킷 에뮬레이션 시스템을 지원한다. 


주요 스펙을 보면 아래와 같다.


200 MHz/330 DMIPS, microAptiv core

Program Memory Size (KB) 2048

RAM (KB) 512

Auxiliary Flash (KB) 160

DSP-enhanced core:

Four 64-bit accumulators

Single-cycle MAC, saturating and fractional math

Dual Panel Flash for live update support

10-bit, 500 KSPS, 48-channel ADC module

CAN, UART, I2C, PMP, EBI, SQI & Analog Comparators

10/100 Mbps Ethernet MAC with MII and RMII interface

Temperature Range: - 40°C to 85°C; - 40°C to 125°C

50 MHz External Bus Interface (EBI)

50 MHz Serial Quad Interface (SQI)

Six UART modules (25 Mbps): Supports LIN 1.2 and IrDA protocols

Six 4-wire SPI modules (50 Mbps)

Five I2C modules (up to 1 Mbaud) with SMBus support

Nine 16-bit Timers/Counters (four 16-bit pairs combine to create four 32-bit timers)

Nine Capture inputs and Nine Compare/PWM outputs




ST사의 STM32F7 시리즈와 비교해 보면 좋을것 같다.

TAG PIC32MZ

[STM32F373 EVM] I2C 테스트 - 9축 IMU 센서 테스트




[STM32F373 EVM]에는 I2C가 PB8(SCL), PB9(SDA)에 할당되어 있다. I2C테스트를 위해 9축 IMU센서(BNO055 EVM)의 롤,피치 값을 TFT LCD에 표시하는 예제를 작성해 보았다.


PB8 -> SPI2_SCK/I2S2_CK,I2C1_SCL, USART3_TX,CAN_RX, CEC, TIM16_CH1,TIM4_CH3, TIM19_CH3,COMP1_OUT, TSC_SYNC

PB9 -> SPI2_NSS/I2S2_WS,I2C1_SDA, USART3_RX,CAN_TX, IR_OUT,TIM17_CH1, TIM4_CH4,TIM19_CH4, COMP2_OUT



STM32F373 EVM 회로도 핀맵



STM32F373의 I2C 블록도






STM32F373 I2C 초기화 함수

#define I2Cx                             I2C1

#define I2Cx_CLK_ENABLE()                __I2C1_CLK_ENABLE()

#define I2Cx_SDA_GPIO_CLK_ENABLE()       __GPIOB_CLK_ENABLE()

#define I2Cx_SCL_GPIO_CLK_ENABLE()       __GPIOB_CLK_ENABLE() 


#define I2Cx_FORCE_RESET()               __I2C1_FORCE_RESET()

#define I2Cx_RELEASE_RESET()             __I2C1_RELEASE_RESET()


//Definition for I2Cx Pins

#define I2Cx_SCL_PIN                    GPIO_PIN_8

#define I2Cx_SCL_GPIO_PORT              GPIOB

#define I2Cx_SCL_AF                     GPIO_AF4_I2C1

#define I2Cx_SDA_PIN                    GPIO_PIN_9

#define I2Cx_SDA_GPIO_PORT              GPIOB

#define I2Cx_SDA_AF                     GPIO_AF4_I2C1



void BNO055_Init(void)

{

  GPIO_InitTypeDef  GPIO_InitStruct;

  

  /*##-1- Enable peripherals and GPIO Clocks #################################*/

  /* Enable GPIO TX/RX clock */

  I2Cx_SCL_GPIO_CLK_ENABLE();

  I2Cx_SDA_GPIO_CLK_ENABLE();

  /* Enable I2C1 clock */

  I2Cx_CLK_ENABLE(); 

  

  /*##-2- Configure peripheral GPIO ##########################################*/  

  /* I2C TX GPIO pin configuration  */

  GPIO_InitStruct.Pin       = I2Cx_SCL_PIN;

  GPIO_InitStruct.Mode      = GPIO_MODE_AF_OD;

  GPIO_InitStruct.Pull      = GPIO_PULLUP;

  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;

  GPIO_InitStruct.Alternate = I2Cx_SCL_AF;

  

  HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct);

    

  /* I2C RX GPIO pin configuration  */

  GPIO_InitStruct.Pin = I2Cx_SDA_PIN;

  GPIO_InitStruct.Alternate = I2Cx_SDA_AF;

    

  HAL_GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct);

  

  

  I2cHandle.Instance             = I2Cx;

  

  I2cHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;

  I2cHandle.Init.Timing      = 400000;

  I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;

  //I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;

  I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_ENABLED;

  I2cHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLED;

  I2cHandle.Init.OwnAddress1     = 0xFE;

  I2cHandle.Init.OwnAddress2     = 0xFE;    

  

  

  HAL_I2C_Init(&I2cHandle);  

}




STM32F373 I2C 송수신 함수

unsigned char read8(unsigned char addr, unsigned char data)

{

    unsigned char tx_buf[2];

    unsigned char rx_buf[4];

    tx_buf[0] = data;

   

    while(HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)addr, (uint8_t*)tx_buf, 1, 10000)!= HAL_OK)

    {


    }

    

    while(HAL_I2C_Master_Receive(&I2cHandle, (uint16_t)addr, (uint8_t *)rx_buf, 1, 10000) != HAL_OK)

    {

    }

  

    result = rx_buf[0];

}


void write8(unsigned char addr, unsigned char reg, unsigned char data)

{

    unsigned char tx_buf[2];


    tx_buf[0] = reg;

    tx_buf[1] = data;


    while(HAL_I2C_Master_Transmit(&I2cHandle, (uint16_t)addr, (uint8_t*)tx_buf, 2, 10000)!= HAL_OK)

    {

    }

}




STM32F373 I2C 테스트 동영상

I2C인터페이스로 BNO055 센서의 롤,피치 값을 TFT LCD에 표시하는 테스트 


[STM32F373 EVM] SDADC 16bit ADC 성능 측정


16비트 ADC테스트 중 성능 확인을 위해서 데이터 분석을 해 보았다.



결론적으로는 +-)10정도 흔들린다. 정밀레퍼런스를 사용하지 않고 내부 레퍼런스만으로도 이정도면 상당히 좋은것 같다.

비슷한 등급의 FreeScale사의 K20 16bit ADC 성능 테스트와 비교해 보면 10배 정도는 노이즈가 줄어드는것 같다.



[STM32F373 EVM] SDADC 16bit ADC 테스트




STM32F3시리즈를 보면서 가장 눈길이 가는것은 16bit ADC (SDADC) 이다.  저가이면서 16bit ADC가 포함된 MCU로 사용하기에 좋을것 같다.



SDADC 특징

- Precise 16-bit sigma-delta ADCs (21 channels)

- 1.2/1.8V reference

- 16.6 ksps (multiple channels and up to 50 ksps)

- The data can be automatically stored in a system RAM buffer, reducing the software overhead. 

- Self-calibration (offset)

- 7 gain settings from 0.5x to 32x (analog gains: 0.5 - 8, digital gains: 16 - 32)




STM32F373 SDADC 블록도
STM32F372CBT6 은 48핀 패키지이고 SDADC1 만 사용가능하다.
따라서 PB0, PB1, PE8, PE9, PB2 만 사용 가능하다. 차동 입력은 2채널 가능하다.

PB0 -> ADC_IN8, SDADC1_AIN6P
PB1 -> ADC_IN9, SDADC1_AIN5P, SDADC1_AIN6M

PB2 -> SDADC1_AIN4P,SDADC2_AIN6P

PE8 -> SDADC1_AIN8P, SDADC2_AIN8P
PE9 -> SDADC1_AIN7P,SDADC1_AIN8M,SDADC2_AIN7P,SDADC2_AIN8M


PB14 -> SDADC3_AIN8P
PB15 -> SDADC3_AIN7P, SDADC3_AIN8M, RTC_REFCLKIN

PD8 SDADC3_AIN6P




그리고 16비트 ADC를 이용한 테스트 예제로 압력센서 MPX2102A와 온도센서 PT100 예제를 제공하니 테스트 해보면 좋을것 같다.



STM32F373의 ADC는 12bit, 16bit ADC가 모두 외부 레퍼런스 입력이 가능하다.
내부 레퍼런스는 1.2V, 1.8V 설정이 가능한데... 정밀도에대한 언급은 없는것 같다.
(1.2V애대한 언급만 있다. 1.16V< 1.21V< 1.26V, 100 ppm/°C)





STM32F372  SDADC ADC16 테스트 동영상


PB0 -> ADC_IN8, SDADC1_AIN6P 포트에 가변 저항을 연결하여 16bit ADC값을 TFT LCD 화면에 출력하고 그래프로 표시하는 테스트 예제를 진행했다

좀더 정밀한 분석이 필요하겠지만 대략적으로 봐도 값이 아주 안정적으로 들어온다.






STM32F372  SDADC 초기화 코드


void Adc16_Init(void)

{

  SDADC_ConfParamTypeDef confParam;

    

  hsdadc.Instance = SDADC1;

  hsdadc.Init.ReferenceVoltage = SDADC_VREF_VREFINT2;

  hsdadc.Init.IdleLowPowerMode = SDADC_LOWPOWER_NONE;

  hsdadc.Init.FastConversionMode = SDADC_FAST_CONV_DISABLE;

  hsdadc.Init.SlowClockMode = SDADC_SLOW_CLOCK_DISABLE; 

  

  if (HAL_SDADC_Init(&hsdadc) != HAL_OK)

  {

  

  }


  confParam.CommonMode = SDADC_COMMON_MODE_VSSA;

  confParam.Gain = SDADC_GAIN_1;

  confParam.InputMode = SDADC_INPUT_MODE_SE_ZERO_REFERENCE;

  confParam.Offset = 0x00000000;  

  

  if (HAL_SDADC_PrepareChannelConfig(&hsdadc, SDADC_CONF_INDEX_0, &confParam) != HAL_OK)

  {

    /* An error occurs during the preparation of the channel's configuration */

  }


  /* associate POT_SDADC_CHANNEL to the configuration 0 */

  if (HAL_SDADC_AssociateChannelConfig(&hsdadc, POT_SDADC_CHANNEL, SDADC_CONF_INDEX_0) != HAL_OK)

  {

    /* An error occurs during the association of the channel to the prepared configuration */

  }


  /* select POT_SDADC_CHANNEL for injected conversion and continuous mode */

  if (HAL_SDADC_InjectedConfigChannel(&hsdadc, POT_SDADC_CHANNEL, SDADC_CONTINUOUS_CONV_ON) != HAL_OK)

  {

    /* An error occurs during the selection of the channel for the injected conversion */

  }


  /* Select external trigger for injected conversion */

  if (HAL_SDADC_SelectInjectedTrigger(&hsdadc, SDADC_SOFTWARE_TRIGGER) != HAL_OK)

  {

    /* An error occurs during the selection of the trigger */

  }


  /* Start Calibration in polling mode */

  if (HAL_SDADC_CalibrationStart(&hsdadc, SDADC_CALIBRATION_SEQ_1) != HAL_OK)

  {

    /* An error occurs during the starting phase of the calibration */

  }


  /* Pool for the end of calibration */

  if (HAL_SDADC_PollForCalibEvent(&hsdadc, HAL_MAX_DELAY) != HAL_OK)

  {

    /* An error occurs while waiting for the end of the calibration */

  }


  /* Start injected conversion in interrupt mode */

  if (HAL_SDADC_InjectedStart_IT(&hsdadc) != HAL_OK)

  {

    /* An error occurs during the configuration of the injected conversion in interrupt mode */

  }  

}





STM32F372  SDADC 인터럽트 핸들러


void HAL_SDADC_InjectedConvCpltCallback(SDADC_HandleTypeDef *hsdadc)

{

  /* Get conversion value */

  gAdcData = HAL_SDADC_InjectedGetValue(hsdadc, (uint32_t *) &InjChannel);

}



void SDADC1_IRQHandler(void)

{

  HAL_SDADC_IRQHandler(&hsdadc);

}















[STM32F373 EVM] 12bit ADC 테스트

[ST_MICRO]/STM32F3 | 2016.12.11 22:19
Posted by nexp

[STM32F372 EVM] 12bit ADC 테스트




STM32F3 시리즈의 가장 강점은 저렴지만 강력한 ADC성능이다.


16비트 ADC도 추가되었고, ADC 속도도 향상되고 3채널 동시 획득이 가능하다고 한다. 


 - Ultra-fast 12-bit ADCs with 5 MSPS per channel (up to 18 MSPS in Interleaved mode)



16bit ADC테스트를 먼저 해 보고 싶지만 우선 기존 코드로 테스트 해 볼 수 있는 12bit ADC를 테스트 해보자


하지만 기존 코드와 많이 변경된것 같다.




STM32F373 ADC 초기화 코드


ADC_HandleTypeDef    AdcHandle;

  

void AdcInit(void)

{

__HAL_RCC_ADC1_CONFIG(RCC_ADC1PCLK2_DIV6);


AdcHandle.Instance          = ADCx;


AdcHandle.Init.ScanConvMode          = DISABLE;

AdcHandle.Init.ContinuousConvMode    = DISABLE;

AdcHandle.Init.DiscontinuousConvMode = DISABLE;

AdcHandle.Init.NbrOfDiscConversion   = 0;

AdcHandle.Init.ExternalTrigConv      = ADC_SOFTWARE_START;

AdcHandle.Init.DataAlign             = ADC_DATAALIGN_RIGHT;

AdcHandle.Init.NbrOfConversion       = 1;



GPIO_InitTypeDef          GPIO_InitStruct;


ADCx_CLK_ENABLE();

ADCx_CHANNEL_GPIO_CLK_ENABLE();


GPIO_InitStruct.Pin = ADCx_CHANNEL_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;

GPIO_InitStruct.Pull = GPIO_NOPULL;

HAL_GPIO_Init(ADCx_CHANNEL_GPIO_PORT, &GPIO_InitStruct);

}




STM32F373 ADC 획득 소스코드


unsigned int GetAdc(unsigned int Ch)

{

unsigned int val = 0;

ADC_ChannelConfTypeDef sConfig;


sConfig.Channel      = Ch;

sConfig.Rank         = 1;

sConfig.SamplingTime = ADC_SAMPLETIME_7CYCLES_5;


HAL_ADC_ConfigChannel(&AdcHandle, &sConfig)


//Start the conversion process

HAL_ADC_Start(&AdcHandle)


HAL_ADC_PollForConversion(&AdcHandle, 10);


//ADC conversion completed

val = HAL_ADC_GetValue(&AdcHandle);


return val;

}






블로그 이미지

nexp

카테고리

분류 전체보기 (1550)
[MyProject] (48)
[TI] (75)
[NXP] (51)
[ST_MICRO] (129)
[FreeScale] (31)
[MSP430] (139)
[Microchip] (131)
Cortex-M (36)
[ATMEL] (29)
[AnalogDevice] (22)
[Embedded] (2)
ARM9 (24)
[AVR] (80)
[DSP] (111)
[8051] (21)
[MCU] (50)
[INTERFACE] (210)
[AppBoard] (23)
[ROBOT] (25)
[MODULE] (127)
[SENSOR] (41)
[DATA] (21)
[FPGA] (29)
[EVB] (1)
[Proramming] (38)
[MyLog] (6)
[IDEA] (0)
[Utility] (19)
[Book] (24)
취미생활 (4)
[Link] (2)