[ST_MICRO]/STM82014. 6. 16. 01:14

STM8S - 타이머 테스트 (1초 만들기)

STM8S - 타이머 테스트 (1초 만들기)



마이컴 다루면서 가장 기본으로 필요한 타이머 인터럽트인데, STM8S에서 타이머 인터럽트를 어떻게 제어 하는지 테스트 해 보았다.


STM8S 타이머 구조

STM8S는 3개의 타이머가 있다. TIM4 는 8bit 베이직타이머로 일반 시간 계산하는데 사용하면 편리하다. 




Auto-reload 기능이 있어 한번만 설정하면 계속해서 자동으로 타이머 설정이 가능하다. 동급의 AVR에서는 이 기능이 없어서 인터럽트가 걸릴때 마다 매번 갱신해 주었어야 했었다.



메인클럭이 16Mhz 이므로 프리스케일로 1/128 하면 125khz가 되고 이는 8us 마다 한번씩 카운트 된다.

1초를 만드려면 1000ms/8ms -> 125번 만다 한번씩 인터럽트 걸리도록 하면 된다. 

ST제공 예제를 이용하면 타이머를 쉽게 설정 가능하다.

void Timer4Init(void)

{

        //Timer4 8bit Basic Timer Init

// 16MHz/128 = 125kHz -> 8us

TIM4_DeInit();

TIM4_TimeBaseInit(TIM4_PRESCALER_128, 125);

TIM4_ClearFlag(TIM4_FLAG_UPDATE);

TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);

TIM4_Cmd(ENABLE);

}




Timer4 인터럽트 핸들러

1ms마다 한번씩 증가 하도록 한다.

INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)

{

    //Led1Toggle();

    gTimeTick1++;

    

    TIM4_ClearITPendingBit(TIM4_IT_UPDATE);

}




STM8S Timer 테스트 예제코드

int main( void )

{

    SystemInit();

    

    DebugInit(BAUD_115200);

    DebugPrint("STM8S Timer Test\r\n"); 

    

    Led1Init();

    Led1Off();    


Timer4Init();

enable();



    while(1)

    {

        if(gTimeTick1>1000-1)

        {

            gTimeTick1 = 0;

            Led1Toggle();

        }

    }

    

    return 0;

}


Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM82014. 5. 5. 22:00

STM8S - PWM테스트 (DC모터 속도 제어)

STM8S - PWM테스트 (DC모터 속도 제어)



16비트 타이머 TIM1, TIM2를 이용하여 PWM출력을 각각 4, 3채널씩 출력 가능하다. 

그리고 특이사항으로 PD4는 BEEP 핀이고 1, 2 , 4 kHz 로 사운드 출력을 할수 있다. (이 기능을 사용하려면 옵션비트 AFR7 을 리맵해야 한다고 한다.)

PC6(HS)/SPI_MOSI [TIM1_CH1]

PC7(HS)/SPI_MISO[TIM1_CH2]

PC3(HS)/TIM1_CH3/[TIM1_CH1N]

PC4(HS)/TIM1_CH4/CLK_CCO/AIN2/[TIM1_CH2N]


PD4(HS)/TIM2_CH1/UART1_CK/BEEP

PD3(HS)/TIM2_CH2/AIN4/ADC_ETR

PA3(HS)/TIM2_CH3/[SPI_NSS]

PC5(HS)/SPI_SCK [TIM2_CH1]



STM8S PWM출력 블록도





STM8S PWM을 테스트 하기 위해 PWM출력을 간단한 모터 드라이버 모듈 BA608 을 이용하였다. ADC로 입력되는 가변저항의 전압값에 따른 모터 속도 제어를 테스트 해보았다. 


STM8-SS EVM보드에는 PD4/TIM2_CH1 에 PWM출력이 된다.



모터 드라이버 BA608 모듈 연결은 GND와 PWM신호만 연결하면 된다.




STM8S PWM초기화 함수

STM8 PWM 출력은 15Khz로 설정하고 10bit로 제어 하도록 설정했다.

//STM8 PWM출력 함수

#define SetPwm21(Value)              TIM2->CCR1H = (Value >> 8);\

                                    TIM2->CCR1L = (Value);


//STM8 PWM초기화 함수

void InitPwm2(void)

{

    TIM2_TimeBaseInit(TIM2_PRESCALER_1, 1024); //16000000/1024->15625


    // PWM1 Mode configuration

    TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 0, TIM2_OCPOLARITY_HIGH);

    TIM2_OC1PreloadConfig(ENABLE);

    TIM2_ARRPreloadConfig(ENABLE);


    TIM2_Cmd(ENABLE);

}




STM8S PWM 출력 테스트 예제코드

int main( void )

{

    unsigned int cnt = 0;

    unsigned int adc = 0;

    SystemInit();

    

    DebugInit(BAUD_115200);

    DebugPrint("STM8S PWM Test\r\n"); 

    

    Led1Init();

    Led1On();    

    

//ADC초기화

    AdcInit(0);

//PWM초기화

    InitPwm2();


enable();



    while(1)

    {

        adc = AdcRead(ADC1_CHANNEL_3);

        SetPwm21(adc);

    }

    

    return 0;

}



STM8S PWM테스트 동영상


Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM82014. 5. 5. 21:30

STM8S - ADC 테스트

STM8S - ADC 테스트




STM8S 는 10bit SAR ADC가 내장되어 있고 fADC = 1 to 4 or 6 MHz 로 동작한다.


STM8S003F3 의 경우 VREF는 VDD이다. 저렴한 만큼 ADC의 성능은 기대할 수준은 아닌것 같다.

LPC812와 같이 ADC없는것 보다는 나은것 같다.



STM8S ADC 블록도

STM8S003F3에서 ADC관련 핀맵은 아래와 같고 UART를 제외 하면 실제 2채널을 할당 할 수 있다.

STM8-SS EVM에서는 ADC가 PD2/AIN3에 연결되어 있다. ADC테스트는 가변저항에 따라 변화되는 ADC값을 LCD에 표시하는 예제를 작성해 보았다.


PD2(HS)/AIN3

PD3 (HS)/AIN4/TIM2_CH2/ADC_ETR


PD5(HS)/AIN5/UART1_TX

PD6(HS)/AIN6/UART1_RX

PB4/[ADC_ETR] I2C_SCL




ADC결과는 10bit ADC이지만 Alignment Mode로 좀더 유연하게 제어할 수 있다.





STM8S ADC 초기화 함수

void AdcInit(unsigned int AD_Chan)

{

ADC1_DeInit();

ADC1_Init(ADC1_CONVERSIONMODE_CONTINUOUS, ADC1_CHANNEL_3, ADC1_PRESSEL_FCPU_D2, \

ADC1_EXTTRIG_TIM, DISABLE, ADC1_ALIGN_RIGHT, ADC1_SCHMITTTRIG_CHANNEL3,\

DISABLE);

ADC1_Cmd(ENABLE);

}



STM8S ADC Read 함수

unsigned int AdcRead(unsigned char port)

ADC1->CSR &= (uint8_t)(~ADC1_CSR_CH);

ADC1->CSR |= port;

ADC1_StartConversion();

while(RESET == ADC1_GetFlagStatus(ADC1_FLAG_EOC));

ADC1_ClearFlag(ADC1_FLAG_EOC);

    return ADC1_GetConversionValue();

}



Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM82014. 5. 4. 19:30

STM8S - SPI 테스트

STM8S - SPI 테스트



STM8S의 SPI는 최대 클럭 스피드 10Mhz로 동작한다. 동급의 8bit MCU인 AVR과 비교하면 조금더 성능이 좋아 보인다.

S-Type EVM 보드를 이용하여 SPI인터페이스의 가속도센서를 테스트 해 보았다.



STM8S SPI블록도

8bit MCU의 전형적이 SPI구조 이고 AVR과 비교 했을때 큰 차이가 없어 보인다.





STM8S SPI초기화 함수

void SPI0_Init(void)

{

SPI_DeInit();

SPI_Init(SPI_FIRSTBIT_MSB, 

            SPI_BAUDRATEPRESCALER_32, 

            SPI_MODE_MASTER, 

            SPI_CLOCKPOLARITY_LOW, 

            SPI_CLOCKPHASE_2EDGE, 

            SPI_DATADIRECTION_2LINES_FULLDUPLEX, 

            SPI_NSS_HARD, 0x00);

SPI_Cmd(ENABLE);

}



STM8S SPI송수신 함수

레지스터의 SPI_FLAG_TXE 비트를 검사해서 1이면 SPI버퍼가 비어 있으므로 데이터를 쓰고, SPI_FLAG_RXNE비트가 1이되면 읽을 준비가 되었으므로 수신한 값을 리턴하면 된다.

unsigned char SPI0_WriteReadByte(unsigned char Data)

{

while (SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET);

SPI->DR = Data;


while(SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET);


return SPI->DR;

}




Posted by nexp

댓글을 달아 주세요

[ST_MICRO]/STM82014. 5. 4. 19:00

STM8S - UART 테스트

STM8S - UART 테스트




SS-Type EVM 보드와 USB2UART를 이용하여 STM8S UART 테스트를 진행했다.



STM8S UART 블록도

뭐 그리 특별한것은 없고 다른 8bit MCU와 같이 간단한 레지스터 구조로 구성되어 있다. 몇가지 레지스터만 확인하면 될것 같다.



STM8S UART 송수신 함수

unsigned char U0_GetByte(void)

{

while ((UART1->SR & UART1_FLAG_RXNE) == RESET);

return UART1->DR;

}



void U0_PutByte(unsigned char Data)

{

    UART1->DR = Data;


    while ((UART1->SR & (u8) UART1_FLAG_TXE) == RESET);

}



STM8S UART 테스트 예제

int main( void )

{

    unsigned int cnt = 0;


    SystemInit();

    

    DebugInit(BAUD_115200);

    U0_PutStr("test\r\n");


    Led1Init();

    Led1On();

    

    while(1)

    {

        Led1Toggle();

        DebugPrint("%d\r\n", cnt++);

        Delay(500);

    }

    

    return 0;

}







STM8S UART 인터럽트 테스트

UART 인터럽트 초기화함수로 UART1_ITConfig() 를 이요하면되고 STM32와 유사해서 코드 수정하는데 편한것 같다.

    UART1_ITConfig(UART1_IT_RXNE, ENABLE);

    enable();



STM8S  UART 인터럽트 핸들러 함수

INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)

{

    unsigned char data;


    U0_PutByte(U0_GetByte());

}



Posted by nexp

댓글을 달아 주세요