打印
[RISC-V MCU 应用开发]

【RISC-V MCU CH32V103测评】Part5:王小琪之PWM输出

[复制链接]
634|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
王小琪|  楼主 | 2020-11-10 22:37 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 王小琪 于 2020-11-10 22:39 编辑

目的:如题,进行CH32V103开发板的PWM输出实验,PWM输出应用到led上就是灯逐渐变亮或者变暗,因为改变了占空比即改变了电压的大小,通过led的电流也随之改变了。PWM运动到电机驱动上就可以进行调速的应用,这个时候一般是用示波器来测量,但是我相信大多数人周围没有这个条件,所以这次就通过观察led的明暗来学习PWM输出。
1.硬件分析
首先还是led,用一个或者两个都可以,我们继续看原理图如下:

然后因为要用定时器输出PWM,所以要了解定时器的知识,如果是用定时器做定时中断的话,那么定时器就是单片机的内部资源,就不用在硬件上做处理了。但是PWM输出不一样,需要输出电平,所以我们要继续对定时器做更深入一点儿的了解。


通过下图我们可以看到TIM1有4个通道(同理另外的TIM2 TIM3 TIM4也应该有4个通道),对应的IO口分别是PA8 PA9 PA10 PA11,所以我们应该将我们要用到的led一端连接到其中一个IO口,然后进行代码的编写。
我们为了配合软件,将LED1和PA8连接在一起。

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);”这两句一个是设置频率,一个是改变占空比,其实主函数里面的内容也很少。
void TIM1_PWMOut_Init( u16 arr, u16 psc, u16 ccp )
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

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

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

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

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

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

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

    TIM1_PWMOut_Init( 899, 0, 500 );

    while(1)
    {
        Delay_Ms(10);
        if(a)  pwmval++;
        else   pwmval--;

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

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

7、PWM输出.rar

478.4 KB

CH32V103SCH.pdf

166.86 KB

CH32V103评估板说明书.pdf

790.52 KB

CH32V103DS0.PDF

2 MB

CH32xRM.PDF

2.92 MB

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

227

主题

578

帖子

6

粉丝