ch32v003メモ

[ch32v003]Lチカ(PWM)

ch32v003funを用いたLチカのサンプル。(PWMで点滅)(2023.7.23)
[参考資料]はCH32V003RM.PDF

ファイル一覧

ch32v003fun/examples/blink_pwm/
├── Makefile
├── blink.c
└── funconfig.h

配線図

blink.c

・GPIO可能な6個のピンのうち3ピンを約4Hzで点滅させる(PA1, PA2, PC4 = 1,3,7番ピン)
・コード解説
   l.13:  PA, PC, タイマー1に電源供給する
   l.15-25: PA1(Timer-1, CH2), PA2(Timer-1, CH2N), PC4(Timer-1, CH4)の各ポートをEnableにする
   l.35: タイマーの分周値を0x2000(=8192dec)にする
     内部クロックが5839[Hz]になる(=48MHz/8192)
   l.38: カウンタピリオドを1465decにする
     PWM周期が約4[Hz]になる(=5839/1465)
   l.81: PA1, PA2のコンペアレジスタを100decにする
     PA1(CH2)のPWMのディーティ比が約93%になる(=1.0-100/1465)
     PA2(CH2N)はPA1から反転した出力になるためディーティ比は約7%になる
   l.82: PC4のコンペアレジスタを732decにする
     PC4(CH2)のPWMのディーティ比が約50%になる(=1.0-732/1465)
   l.85-89: ダミーコード
     TIM1-1-SWEVGRを設定するとwhileループと無関係にPWM発振が継続される。
     プログラム中で「待ち(ループ中何もしない)」の記述がわからなかったのでこのように書いた
/* ------------------------------------------------------------
 * ch32v003J4M6(8pin)でPWMを用いたLチカを実行するコード
 * ------------------------------------------------------------*/
#include "ch32v003fun.h"
#include <stdio.h>

/*
 * initialize TIM1 for PWM
 */
void t1pwm_init( void )
{
  // Enable GPIOC, GPIOD and TIM1
  RCC->APB2PCENR |= 	RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_TIM1;

  // PA1 is T1CH2, 10MHz Output alt func, push-pull
  GPIOA->CFGLR &= ~(0xf<<(4*1));
  GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*1);

  // PA2 is T1CH2N, 10MHz Output alt func, push-pull
  GPIOA->CFGLR &= ~(0xf<<(4*2));
  GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*2);

  // PC4 is T1CH4, 10MHz Output alt func, push-pull
  GPIOC->CFGLR &= ~(0xf<<(4*4));
  GPIOC->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)<<(4*4);

  // Reset TIM1 to init all regs
  RCC->APB2PRSTR |= RCC_APB2Periph_TIM1;
  RCC->APB2PRSTR &= ~RCC_APB2Periph_TIM1;

  // CTLR1: default is up, events generated, edge align
  // SMCFGR: default clk input is CK_INT

  // Prescaler 
  TIM1->PSC = 0x2000;

  // Auto Reload - sets period
  TIM1->ATRLR  =1465;

  // Reload immediately
  TIM1->SWEVGR |= TIM_UG;

  // Enable CH1 output, positive pol
  TIM1->CCER |= TIM_CC2E | TIM_CC2P;

  // Enable CH1NE output, positive pol
  TIM1->CCER |= TIM_CC2NE | TIM_CC2NP;

  // Enable CH4 output, positive pol
  TIM1->CCER |= TIM_CC4E | TIM_CC4P;

  // CH1 Mode is output, PWM1 (CC1S = 00, OC1M = 110)
  TIM1->CHCTLR1 |= TIM_OC2M_2 | TIM_OC2M_1;

  // CH1 Mode is output, PWM1 (CC1S = 00, OC1M = 110)
  TIM1->CHCTLR1 |= TIM_OC2M_2 | TIM_OC2M_1;

  // CH2 Mode is output, PWM1 (CC1S = 00, OC1M = 110)
  TIM1->CHCTLR2 |= TIM_OC4M_2 | TIM_OC4M_1;

  // Set the Capture Compare Register value to 50% initially
  TIM1->CH2CVR = 732;
  TIM1->CH4CVR = 732;

  // Enable TIM1 outputs
  TIM1->BDTR |= TIM_MOE;

  // Enable TIM1
  TIM1->CTLR1 |= TIM_CEN;
}
int main()
{
  //int cnt=0;
  SystemInit();
  Delay_Ms( 100 );

  // init TIM1 for PWM(PC4, pin7 for J4m6)
  t1pwm_init();

  TIM1->ATRLR  =1465;
  TIM1->CH2CVR = 100;//PA1, PA2
  TIM1->CH4CVR = 732;//PC4
  TIM1->SWEVGR |= TIM_UG;//Update event generation bit(automaticallly cleared by hardware)

  while(1)
  {
    printf("delay 5s");
    Delay_Ms( 5000 );
  }
}

funconfig.h

#ifndef _FUNCONFIG_H
#define _FUNCONFIG_H

#define CH32V003           1

#endif

Makefile

all : flash

TARGET:=blink

include ../../ch32v003fun/ch32v003fun.mk

flash : cv_flash
clean : cv_clean