[RISC-V MCU 应用开发] 【RISC-V MCU CH32V103测评】Part5:王小琪之PWM输出

[复制链接]
 楼主| 王小琪 发表于 2020-11-10 22:37 | 显示全部楼层 |阅读模式
本帖最后由 王小琪 于 2020-11-10 22:39 编辑

目的:如题,进行CH32V103开发板的PWM输出实验,PWM输出应用到led上就是灯逐渐变亮或者变暗,因为改变了占空比即改变了电压的大小,通过led的电流也随之改变了。PWM运动到电机驱动上就可以进行调速的应用,这个时候一般是用示波器来测量,但是我相信大多数人周围没有这个条件,所以这次就通过观察led的明暗来学习PWM输出。
1.硬件分析
首先还是led,用一个或者两个都可以,我们继续看原理图如下:
led.png
然后因为要用定时器输出PWM,所以要了解定时器的知识,如果是用定时器做定时中断的话,那么定时器就是单片机的内部资源,就不用在硬件上做处理了。但是PWM输出不一样,需要输出电平,所以我们要继续对定时器做更深入一点儿的了解。
资源分配表7.png
定时器.png
通过下图我们可以看到TIM1有4个通道(同理另外的TIM2 TIM3 TIM4也应该有4个通道),对应的IO口分别是PA8 PA9 PA10 PA11,所以我们应该将我们要用到的led一端连接到其中一个IO口,然后进行代码的编写。
我们为了配合软件,将LED1和PA8连接在一起。
TIM1.png
2.软件分析
代码层面的话,因为MounRiver Studio可以对CH32V103单片机生成对应的模板,所以只需要修改led.c,led.h,pwm.c,pwm.h,main.c文件即可。下面稍微看一下pwm.c文件和main.c文件
pwm.c文件主要是对定时器的pwm设置,这些如果是STM32的话可以用CUBEMX生成,但是现在并不可以,还是多看几遍吧,书读百遍,其义自见,源码也是,读多了自然就熟悉了。
其次是main.c文件,代码和官方的代码是完全一样的,但是这个板子的串口好像有点儿问题,所以其实里面有两句关于串口配置以及打印其实是没啥用的,但我也懒得去改了。主要看一下“TIM1_PWMOut_Init( 899, 0, 500 );”和“TIM_SetCompare1(TIM1,pwmval);”这两句一个是设置频率,一个是改变占空比,其实主函数里面的内容也很少。
  1. void TIM1_PWMOut_Init( u16 arr, u16 psc, u16 ccp )
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure;
  4.     TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
  5.     TIM_OCInitTypeDef TIM_OCInitStructure;

  6.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE );//使能GPIOA外设时钟和TIM1时钟

  7.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;        //配置PA8引脚
  8.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //设置为复用推挽输出
  9.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设置输出速度:50MHz
  10.     GPIO_Init( GPIOA, &GPIO_InitStructure );         //GPIO初始化

  11.     TIM_TimeBaseInitStructure.TIM_Period = arr;      //指定下次更新事件时要加载到活动自动重新加载寄存器中的周期值。
  12.     TIM_TimeBaseInitStructure.TIM_Prescaler = psc;   //指定用于划分TIM时钟的预分频器值。
  13.     TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;    //时钟分频因子
  14.     TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM计数模式,向上计数模式
  15.     TIM_TimeBaseInit( TIM1, &TIM_TimeBaseInitStructure); //根据指定的参数初始化TIMx的时间基数单位

  16.     TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;            //指定TIM模式
  17.     TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//指定TIM输出比较状态,即使能比较输出
  18.     TIM_OCInitStructure.TIM_Pulse = ccp;                         //指定要加载到捕获比较寄存器中的脉冲值。
  19.     TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;    //指定输出极性。
  20.     TIM_OC1Init( TIM1, &TIM_OCInitStructure ); //根据TIM_OCInitStruct中指定的参数初始化TIM1 Channel1。

  21.     TIM_CtrlPWMOutputs(TIM1, ENABLE );                  //启用定时器1PWM输出
  22.     TIM_OC1PreloadConfig( TIM1, TIM_OCPreload_Disable );//使能CCR1上的TIM1外设预加载寄存器
  23.     TIM_ARRPreloadConfig( TIM1, ENABLE );               //使能ARR上TIM1外设预加载寄存器
  24.     TIM_Cmd( TIM1, ENABLE );                            //使能TIM1
  25. }
  1. int main(void)
  2. {
  3.     u16 pwmval=0;
  4.     u8  a=1;

  5.     Delay_Init();
  6.     USART_Printf_Init(115200);
  7.     printf("SystemClk:%d\r\n",SystemCoreClock);

  8.     TIM1_PWMOut_Init( 899, 0, 500 );

  9.     while(1)
  10.     {
  11.         Delay_Ms(10);
  12.         if(a)  pwmval++;
  13.         else   pwmval--;

  14.         if(pwmval>300) a=0;
  15.         if(pwmval==0)  a=1;
  16.         TIM_SetCompare1(TIM1,pwmval); //设置TIM1捕获比较1寄存器值,,用于修改占空比
  17.     }
  18. }

3.环境搭建
硬件软件都配置好了,只需要用WCH-LINK和开发板连接起来将代码下载进去,观察现象即可。可以看到LED1在亮灭之间循环,即呼吸灯的效果。
微信截图_20201110205815.png 呼吸灯.png

7、PWM输出.rar

478.4 KB, 下载次数: 4

CH32V103SCH.pdf

166.86 KB, 下载次数: 1

CH32V103评估板说明书.pdf

790.52 KB, 下载次数: 2

CH32V103DS0.PDF

2 MB, 下载次数: 2

CH32xRM.PDF

2.92 MB, 下载次数: 3

您需要登录后才可以回帖 登录 | 注册

本版积分规则

232

主题

585

帖子

7

粉丝
快速回复 在线客服 返回列表 返回顶部