2012年4月20日金曜日

STBeeMiniでタイマ割り込み+Lチカ

とりあえず
汚いですが ソースコードです
全体で100行超えちゃうのでもっと読むからどうぞ



ソースコード2
ヘッダ1
main.c/stm32f10x_it.c/stm32f10x_it/h

↓↓↓

/* main.c */

#include "stm32f10x_conf.h"

#define GPAON(PIN) { GPIOA -> BSRR = _BV(PIN); }
#define GPAOF(PIN) { GPIOA -> BRR  = _BV(PIN); }
#define GPASET(PIN, bit) { if(bit){ GPAON(PIN); }else{ GPAOF(PIN); } }

extern volatile int CntmiliSec;
extern volatile long long CntSecond;

void Delay(volatile unsigned long delay)
{ while(delay--) ; }

void TIM2init(void) {
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Enable the TIM2 Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = 7200 - 1;
    TIM_TimeBaseStructure.TIM_Prescaler = 10 - 1;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);

    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);

    TIM_Cmd(TIM2, ENABLE);
}

void IOinit(void) {
GPIO_InitTypeDef GPIO_InitStructure;
// ポートの初期化(PA13, PA15を出力に)
GPIO_InitStructure.GPIO_Pin = _BV(13) | _BV(15);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
    // ポートの初期化(PC13を入力に)
    GPIO_InitStructure.GPIO_Pin = _BV(13);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void ALLinit(void) {
// STM32の初期化 クロック設定
SystemInit();
NVIC_SetVectorTable(0x3000, 0);

// JTAGを無効にします。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);
AFIO->MAPR = _BV(26);

// GPIO A, B, Cポートを有効にします
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    // TIM2を有効に
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    IOinit();
    TIM2init();
}

int main(void) {
    long long sec = 0;
    int flag1 = 0, flag2 = 0;
    int mSec = 0;

    ALLinit();

while(1){
        // 1秒ごと(0.5Hz)でLED(RESET側)を点滅
        if (sec != CntSecond) {
            sec = CntSecond;
            GPASET(13, flag1);
            flag1 = !flag1;
        }
     
        // 0.5秒ごと(1Hz)でLED(USER側)を点滅
        if (CntmiliSec % 200 == 0) {
            GPASET(15, 1);
        } else if (CntmiliSec % 100 == 0) {
            GPASET(15, 0);
        }
}
}

/* stm32f10x_it.h */

#ifndef __STM32F10x_IT_H
#define __STM32F10x_IT_H

#include "stm32f10x.h"

void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void TIM2_IRQHandler(void);
void int1ms(void);

#endif /* __STM32F10x_IT_H */

/* stm32f10x_it.c */

#include "stm32f10x_it.h"

int CntmiliSec = 0;
long long CntSecond = 0;
void NMI_Handler(void) { }

void HardFault_Handler(void) { while (1) { } }

void MemManage_Handler(void) { while (1) { } }

void BusFault_Handler(void) { while (1) { } }

void UsageFault_Handler(void) { while (1) { } }

void SVC_Handler(void) { }

void DebugMon_Handler(void) { }

void PendSV_Handler(void) { }

void SysTick_Handler(void) { }

void TIM2_IRQHandler(void) {
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    CntmiliSec++;
    if (CntmiliSec >= 1000) {
        CntmiliSec = 0;
        CntSecond++;
    }
}

こんな感じです
まずタイマ割り込みを1mSに設定
ミリ秒のカウンタをインクリメントし
1000になったらミリ秒を初期化し秒をインクリメント
外部からわかるように100mSと1S単位でLEDを点滅させます
開発環境はストリナで配布しているSTBeeMiniのサンプルです
STBeeではまだ未確認
汚いですが 一応動いてるように見えるので 公開
例の微妙にずれるという不具合は
おそらく割り込みとフラグクリアのタイミングの問題
と言うことで放置

こんなかんじです


0 件のコメント:

コメントを投稿