龙芯1c库是把龙芯1c的常用外设的常用功能封装为一个库,类似于STM32库。Git地址:https://gitee.com/caogos/OpenLoongsonLib1c
本文通过“龙芯1c库”中提供的PWM接口,实现了在4路pwm的输出连续的pwm脉冲和单个脉冲。
在讲解了pwm接口之后,才开始详细介绍寄存器,以及怎样使用这些寄存器来封装接口,最后给出了封装的pwm接口代码清单。
龙芯1c库中pwm接口使用示例
PWM接口简介
提供三个接口函数,分别是
void pwm_init(pwm_info_t *pwm_info);
void pwm_disable(pwm_info_t *pwm_info);
void pwm_enable(pwm_info_t *pwm_info);
其中函数pwm_init()是最核心的接口,调用后会立刻在指定引脚上产生需要的波形。初始化之后,可以在需要的时候调用pwm_disable()停止输出pwm波形,在disable后还可以调用pwm_enable()重新使能,指定引脚上又继续输出pwm波形。
这三个接口都是一了相同的入参,这个入参到底长啥样,马上揭晓。
// 硬件pwm信息
typedef struct
{
unsigned int gpio; // PWMn所在的gpio
unsigned int mode; // 工作模式(单脉冲、连续脉冲)
float duty; // pwm的占空比
unsigned long period_ns; // pwm周期(单位ns)
}pwm_info_t;
我想这个应该一看就知道说的是啥。
这里重点解释一下为什么这里是gpio,而不是PWMn。因为每路pwm都可以复用到至少另外的一个引脚上,却不存在一个引脚可能发生支持多个PWM复用的情况,这里直接传入gpio,代码中会自动根据gpio判断是使用那个PWM,是否需要使用复用,如果需要复用,自动复用。
除了gpio之外,还有工作模式为啥还有个单脉冲模式。当工作在单脉冲模式时,调用一次pwm_init()产生一个脉冲。这对于常用于步进电机的控制,比如我之前做的3D打印机(龙印)就用到了,通过控制脉冲个数,达到控制步进电机行走距离的目的。
龙芯1C300B支持FPU(硬件浮点运算单元),并且龙芯1c库中已经默认开启了FPU,所以这里直接采用浮点数形式的占空比。
据此,构造了三个测试用例:
用例一,测试PWM正常模式(连续输出PWM)。
通过调用pwm_init()产生连续单脉冲,然后调用pwm_disable()停止输出脉冲,最后调用pwm_enable()又继续输出连续脉冲。为了便于使用示波器观察,禁止输出一会后,又使能,再禁止,再使能,反复不停的循环。
用例二,测试PWM单脉冲模式(每次只输出一个脉冲)
通过调用pwm_init()产生一个脉冲,再延时一会之后(延时时间必须大于等于pwm周期),再调用pwm_init(),再延时一会,再调用pwm_init(),再延时,再输出一定数量的脉冲之后停止输出。通用为了便于用示波器观察,可以将上述过程反复重复。
用例三。将pwm默认的引脚作用普通GPIO,同时复用其它引脚来用作pwm。
PWM0的默认引脚GPIO06用作普通gpio,而GPIO04上输出pwm波形,
硬件资源
龙芯1c有4路pwm,每路都可以复用。但只有pwm0和pwm1才有默认引脚(当然也可以复用其它引脚),pwm2和pwm3都需要复用。这里每路选取了两个引脚,如下
// pwm引脚定义
#define LS1C_PWM0_GPIO06 (6) // gpio06用作pwm0
#define LS1C_PWM0_GPIO04 (4) // gpio04复用为pwm0
#define LS1C_PWM1_GPIO92 (92) // gpio92用作pwm1
#define LS1C_PWM1_GPIO05 (5) // gpio05复用为pwm1
#define LS1C_PWM2_GPIO52 (52) // gpio52复用为pwm2
#define LS1C_PWM2_GPIO46 (46) // gpio46复用为pwm2
#define LS1C_PWM3_GPIO47 (47) // gpio47复用为pwm3
#define LS1C_PWM3_GPIO53 (53) // gpio53复用为pwm3
每个引脚都可以输出连续pwm脉冲和单个脉冲。
测试用例1——产生连续脉冲
代码清单
// 测试硬件pwm产生连续的pwm波形
void test_pwm_normal(void)
{
pwm_info_t pwm_info;
int i;
pwm_info.gpio = LS1C_PWM0_GPIO06; // pwm引脚位gpio06
// pwm_info.gpio = LS1C_PWM0_GPIO04;
pwm_info.mode = PWM_MODE_NORMAL; // 正常模式--连续输出pwm波形
pwm_info.duty = 0.25; // pwm占空比
pwm_info.period_ns = 5*1000*1000; // pwm周期5ms
// pwm初始化,初始化后立即产生pwm波形
pwm_init(&pwm_info);
while (1)
{
// 延时100ms
for (i=0; i<100; i++)
{
delay_1ms();
}
// 禁止pwm
pwm_disable(&pwm_info);
// 延时100ms
for (i=0; i<100; i++)
{
delay_1ms();
}
// 使能pwm
pwm_enable(&pwm_info);
}
return ;
}
测试效果
从图上可以看出,有脉冲和没脉冲的时间都是100ms,与代码相符。下面放大了再来看看连续脉冲的详细信息,如下
占空比为0.25,pwm周期为5ms,与代码相符。
测试用例2——产生单脉冲
代码清单
// 测试硬件pwm产生pwm脉冲
void test_pwm_pulse(void)
{