risc-v Sifive learn inventor基础之串口 在入门手册中可以知道,在金手指上,gpio2接到小车上的右边电机且控制电机正转。在芯片手册的gpio章节,可以找到gpio2的复用功能1中对应的是pwm0_cmp2,所以要操作的就是pwmcmp2输出pwm波。 e310有三个pwm控制器,我们需要操作的是pwm0。 pwmcfg:配置pwm 2,pwms与pwmcmpx 了解了寄存器的功能后,就可以通过代码来操作寄存器实现所需的功能了。可见,通过scale可以设置pwms的时钟频率(pwm时钟频率是16MHZ),设置pwmcmp0可以设置pwm的周期,再通过设置pwmcmpX调节pwm的占空比。 寄存器相关宏定义 示例应用 以pwm0为例,其他的pwm也大致可以依样画葫芦。这次用逻辑分析仪,能明显清晰的看到pwm的周期和占空比,通过不断调试pwmcfg,最后找到规律。同时实践了操作寄存器的方法。编写了reg.h,方便操作寄存器。
risc-v Sifive learn inventor基础之硬件pwm
继串口之后,继续来通过寄存器操作硬件pwm,熟悉操作寄存器的流程。
因为sifive官方没有提供pwm的库函数,所以必须根据芯片手册配置寄存器来开发pwm。这是练习操作寄存器的好机会!一,硬件连接
二,pwm
一个pwm控制器的寄存器如下:
pwmcount:pwm计数寄存器
pwms:保存pwmcount经过放大后的值,这个寄存器用来与pwmcmpX寄存器比较,从而产生pwm波。
1,pwmcfg
pwms的值就是pwmcount的值扩大2^n,n=scale,n∈【0,15】。从频率来看,就是把频率缩小了2 ^n倍,缩放后的值与pwmcmpX寄存器里的值比较,产生pwm波。当pwms>pwmcmpX 时,gpioX输出高电平。
pwmcpmX的最大值与cmpwdith有关,如图不同pwm控制器有不一样的cmpwdith,如pwm0的cmpwdith=8,pwmcmpX寄存器就只能设置8位,也就是0->255,pwm1的cmpwdith=16,pwmcmpX范围0->2^16-1。这一点在编程时需要注意传递的参数不能超出范围。
二,代码编写
首先设置gpio2,输出使能,复用功能1,配置pwmcfg寄存器,保险起见,先清零,再设置scale
注意,pwmenalways必须在pwmzerocmp之前置位,若pwmzerocmp先置位,则pwmenalways设置为1时,pwmzerocmp会被清零!
最后清零所有cmp寄存器,然后设置cmp0的值,这样初始化了周期,cmp1-cmp3的输出全是高电平。#include "pwm.h" /* * 设置pwm0占空比 * cmp_num :0->3 * 通过设置pwmcmp0可以设置周期,cmpx>pwms 低电平 * cmp 【0,155】这是由于pwmdwith=8 */ int pwm0_setcmp(int cmp_num,char cmp){ if(cmp_num==0){ PWM0_CMP0 &=0; PWM0_CMP0|=cmp; } else if(cmp_num==1){ PWM0_CMP1 &=0; PWM0_CMP1|=cmp; } else if(cmp_num==2){ PWM0_CMP2 &=0; PWM0_CMP2|=cmp; } else if(cmp_num==3){ PWM0_CMP3 &=0; PWM0_CMP3|=cmp; } } /* * pwm初始化 * 假设时钟周期设为64M * 周期 = (250*2^scale)/64 us=2^scale*3.90625 *int scale (0-15)时钟分频系数 scale=7时,T=500us */ void pwm_init(int scale){ //GPIO2->PWM0CMP2 GPIO0_IOF_EN |=(1<<2);//enable gpio2 iof GPIO0_IOF_SEL |=(1<<2); //select iof 1 //配置cfg寄存器 PWM0_CFG &=0;//clear cfg PWM0_CFG |=scale;//set scale=0 PWM0_CFG |=(1<<12);//set pwmenalways 1 ;note:this must be done before pwmzeorcmp PWM0_CFG |=(1<<9);//set pwmzero 1 //init the cmpx value pwm0_setcmp(0,250); pwm0_setcmp(1,250); pwm0_setcmp(2,250); pwm0_setcmp(3,250); }
#define PWM0_CFG (__METAL_ACCESS_ONCE((__metal_io_u32 *)(METAL_SIFIVE_PWM0_0_BASE_ADDRESS + METAL_SIFIVE_PWM0_PWMCFG))) #define PWM0_CMP0 (__METAL_ACCESS_ONCE((__metal_io_u32 *)(METAL_SIFIVE_PWM0_0_BASE_ADDRESS + METAL_SIFIVE_PWM0_PWMCMP0))) #define PWM0_CMP1 (__METAL_ACCESS_ONCE((__metal_io_u32 *)(METAL_SIFIVE_PWM0_0_BASE_ADDRESS + METAL_SIFIVE_PWM0_PWMCMP1))) #define PWM0_CMP2 (__METAL_ACCESS_ONCE((__metal_io_u32 *)(METAL_SIFIVE_PWM0_0_BASE_ADDRESS + METAL_SIFIVE_PWM0_PWMCMP2))) #define PWM0_CMP3 (__METAL_ACCESS_ONCE((__metal_io_u32 *)(METAL_SIFIVE_PWM0_0_BASE_ADDRESS + METAL_SIFIVE_PWM0_PWMCMP3)))
设置pwm周期500us 占空比4/5__metal_driver_sifive_fe310_g000_pll_init(&__metal_dt_clock_4);//clock 64mhz metal_clock_set_rate_hz(&__metal_dt_clock_4.clock,64000000); //当scale=7 PWM周期500us pwm_init(7); pwm0_setcmp(2,200);
三,小结
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算