记录一个PWM驱动的编写过程
笔者从零入门编写一个PWM驱动的心路历程。
本科阶段的知识大多停留在知其然但不知其所以然的层次,大三做智能车时使用的K60芯片,通过PWM模块的输出模式控制电机输出和输入捕捉模式获取编码器输入,但是驱动层商家已经把函数封装好了,应用层只需要简单的调用就可以。
//pwm模块初始化
ftm_pwm_init(ftm0,ftm_ch0,15000,0);
ftm_pwm_init(ftm0,ftm_ch1,15000,0);
ftm_pwm_init(ftm0,ftm_ch2,15000,0);
ftm_pwm_init(ftm0,ftm_ch3,15000,0);
//pwm模块电机参数配置
ftm_pwm_duty(ftm0,ftm_ch0,0);
ftm_pwm_duty(ftm0,ftm_ch1,duty);
//pwm模块编码器速度获取
ftm_quad_get(ftm2);
这是我们当初唯一使用到的PWM的函数。走嵌入式方向有一个坑,大部分时间都在改别人的代码,真证自己写一个完整的代码的机会很少,很多时候,我们对嵌入式的了解就只局限在应用层,更深层次的驱动层和系统层很难有机会去真正的掌握。
或许是缘分,我实习工作的第一个任务就是编写一个PWM驱动出来。
废话少说,接下来开始步入正题。
我得到的资料有一个英文的芯片手册、一个SDK模板和一个在网上找不到的类似keil的编译器,再加上一台电脑,开始了我的驱动之旅。
了解正点原子的人知道,他给的官方例程有两个版本,对于入门来说,大部分人都是使用的库函数版本,我也不例外,虽然对函数调用和这种分文件存储的方式非常熟悉,但是寄存器版本的熟悉是我有意避开的,寄存器操作与配置于我来说就是从零开始。
公司给我的SDK里并没有PWM模块,一个空的PWM.c和一个PWM.h文件。
第一次使用英文手册,需要完成文档的翻译,要不然是真的看不懂。我逐行逐行的敲着去把文档翻译成中文,这里翻译软件建议使用谷歌翻译,还是很标准的。
起初,我打算从头开始,把芯片前面的概述都搞清楚之后,再去理解PWM驱动的模块。浪费了一段时间后,发现这样并不合算,按照以往的经验,芯片手册前面的部分只需要了解模块相应的引脚就行。查阅芯片手册后,我找到了该芯片的12个可以配置成pwm模块的引脚。没错,这个芯片有6个 pwm group,共12个channel,我将这些引脚放在了一个数组里,一开始的打算是写个循环将这些引脚全部初始化成PWM引脚(错误做法,在后面会提及)。
static const uint8_t pwm_pin_mux[12]=
{
GPIO0,
GPIO1,
GPIO2,
GPIO3,
GPIO4,
GPIO5,
GPIO6,
GPIO7,
GPIO8,
GPIO9,
GPIO17,
GPIO18,
};
花了大概两天时间,我翻译完了PWM模块的英文文档,但仍然感觉一筹莫展,无从下手。
以往的经验告诉我,应该找一下别的驱动底层的实现逻辑。我随便找了一个ADC驱动,代码编写非常规范。我本着应该从下到上的原则,又开始翻译ADC模块的手册。其间,我问了一个同事这些流程,他和我说IIC驱动是他写的,我就又去熟悉IIC驱动,后来总监看我进度太慢,过来问我,让我不要看IIC,比较难,说SPI比较简单,可以先熟悉SPI驱动,我又开始看SPI驱动。每次,我都是从下到上,先翻译英文手册,然后熟悉代码,整理流程,到最后除了每个模块的中断我依然不知道指向哪儿,大概流程有了一个掌握。
虽然大概流程清楚了,但其实每个模块的流程并不是完全相同的,我仍然感觉难以开始。于是,这个时候,我才发现原来PWM.h文件里原来是有内容的,定义了一些结构体变量并且声明了四个函数,给我指明了我大概的PWM驱动的应该有的一个框架。
于是,依据别的驱动的流程配置方法和头文件里面的内容,我大概的整理出了一些模式配置的函数。这个时候的代码长这个样子:
static void pwm_ch_counter_mode_config(pwm_reg_t *pwm_reg_addr,PWM_CH_COUNTER_MODE_E pwm_ch_counter_mode_conf)
{
if(pwm_ch_counter_mode_conf==PWM_COUNT_UP)
{
}
else if (pwm_ch_counter_mode_conf==PWM_COUNT_UP_DOWN)
{
}
return 0;
}
这是其中的一个模式配置的框架,可以看出这里并没有对寄存器进行配置,将头文件里定义的结构体里包含的变量都

最低0.47元/天 解锁文章
1250

被折叠的 条评论
为什么被折叠?



