2016年7月9日土曜日

タイマのレジスタ

STM32F1のタイマ周りのデバッグでレジスタを読みたくなった。複数のタイマの、複数のレジスタにまたがってのデバッグなので、いちいちデバッグ用のコマンドを実装するのも面倒なので、レジスタのポインタを返す関数を作った。

volatile uint16_t* GetTimRegPtr(int idx, const char* regname) {
    TIM_TypeDef* TIM;
    
    switch (idx) {
    case 1: TIM = TIM1; break;
    case 2: TIM = TIM2; break;
    case 3: TIM = TIM3; break;
    case 4: TIM = TIM4; break;
    case 5: TIM = TIM5; break;
    case 8: TIM = TIM8; break;
    default: return(0);
    }
    
    if (!strcmp(regname, "CR1")) { return(&TIM->CR1); }
    if (!strcmp(regname, "CR2")) { return(&TIM->CR2); }
    if (!strcmp(regname, "SMCR")) { return(&TIM->SMCR); }
    if (!strcmp(regname, "DIER")) { return(&TIM->DIER); }
    if (!strcmp(regname, "SR")) { return(&TIM->SR); }
    if (!strcmp(regname, "EGR")) { return(&TIM->EGR); }
    if (!strcmp(regname, "CCMR1")) { return(&TIM->CCMR1); }
    if (!strcmp(regname, "CCMR2")) { return(&TIM->CCMR2); }
    if (!strcmp(regname, "CCER")) { return(&TIM->CCER); }
    if (!strcmp(regname, "CNT")) { return(&TIM->CNT); }
    if (!strcmp(regname, "PSC")) { return(&TIM->PSC); }
    if (!strcmp(regname, "ARR")) { return(&TIM->ARR); }
    if (!strcmp(regname, "RCR")) { return(&TIM->RCR); }
    if (!strcmp(regname, "CCR1")) { return(&TIM->CCR1); }
    if (!strcmp(regname, "CCR2")) { return(&TIM->CCR2); }
    if (!strcmp(regname, "CCR3")) { return(&TIM->CCR3); }
    if (!strcmp(regname, "CCR4")) { return(&TIM->CCR4); }
    if (!strcmp(regname, "BDTR")) { return(&TIM->BDTR); }
    if (!strcmp(regname, "DCR")) { return(&TIM->DCR); }
    if (!strcmp(regname, "DMAR")) { return(&TIM->DMAR); }

    return(0);
}

とりあえずSTBeeで使ってるのでTIMは1,2,3,4,5,8を使えるようにしている。TIMxはdefineで宣言されているので、ifdefでcaseを囲ってもいい。
引数はタイマの番号と、レジスタの名前を文字列で渡す。不正な番号orレジスタ名を渡した場合は0(ぬるぽ)を返す。それぞれが正常だった場合はvolatile uint16_t*を返す。
USARTから文字列を受け取って、TIMの番号とレジスタ名を読み込んで、それを引数に渡して、ポインタ内の値を表示する、みたいな機能を作ればレジスタの値を読み取ることができる。
ポインタに値を設定すればレジスタを変更できる。



PWMとADCを高精度にタイミング合わせて走らせたいけど、結構面倒っぽい。あとSTM32F1を72MHzで走らせてるとADCは1Mspsではサンプリングできず、およそ0.85Mspsくらいが上限っぽい。コアを56MHzで動かせば1Mspsで取れるらしいが。
それとADC1とADC2を交互にサンプリングする方法も謎。おそらく高速インターリーブモードでできるんじゃないかと思うが。これはトリガ1個でどんどん変換していくので、止める方法が不明。
まぁいろいろな方法がありそう。期限があるわけでもないのでゆっくりと調べつつ。頭を休めつつ。

0 件のコメント:

コメントを投稿