SAM4E单片机之旅——4、LED闪烁之PWM
两个LED灯虽然可以闪了,但是总是需要CPU的参与。现在尝试使用一种更为自动化的方法:让脉宽调制(PWM)控制器输出具有一定周期和占空比的方波,以此控制LED灯的亮灭。
一、实现思路
依然使用蓝色和琥珀色的LED灯。开发板上能启用四个PWM通道,每个通道能输出两个互补的方波。我们会启用其中的一个通道,然后让这个通道的两个输出分别控制一个LED灯。但是由于这两个引脚上不存在同一通道的输出,所以需要第三个引脚辅助。
我们将使用PWM的通道0。
1. PWMH0输出至引脚PA0(外设A)。
2. PWML0输出至引脚PC0(外设B)。
3. 引脚PD20配置为纯输入引脚。
4. 将PC0和PD20两个引脚短接起来。
这样就可以使这两个LED灯交替闪烁了。
二、PWM设置
在PMC中启用PWM时钟。
/* PMC 启用
* PWM的ID大于31,需要在PMC_PCER1中启用
*/
PMC->PMC_PCER1 = 1 << (ID_PWM - 32);禁用PWM通道。
通道在启用时不能进行完整的控制,先禁用通道。/* 禁用通道0,以进行配置 */
PWM->PWM_DIS = PWM_DIS_CHID0;设置时钟。
通道选择的时钟直接或间接由主时钟分频得到。由于主时钟频率较高,所以为保证能产生肉眼可见的闪烁,这里会选择尽可能大的分频数。为对PWM的特性有更多的了解,我们将开启它的Clock A。通过向PWM时钟控制器的(PWM_CLK)中的PERA字段写入 9,以配置Clock A的输入时钟为MCK / 512;通过向DIVA字段写入125,再将输入时钟进行125分频。配置完成后,CLKA输出的时钟的频率即为MCK / (512 * 125)。初始化时,MCK的频率为4MHz(4000000Hz),所以CLKA输出频率即为62.5 Hz。
/* clockA */;
PWM->PWM_CLK = PWM_CLK_DIVA(125)
| PWM_CLK_PREA(9);选择通道的模式。
为简单起见,将使用默认的属性:周期为左对齐,极性为先输出低电平,不使用中断以及死区发生器。同时,在这里为通道选择时钟CLKA。/* 配置通道0 */
PWM->PWM_CH_NUM[0].PWM_CMR = PWM_CMR_CPRE_CLKA;配置周期和占空比。
为观察方便,将输出脉冲方波的周期设置为2秒,占空比50%。因为使用的时钟频率为62.5Hz,所以需要将计数器的周期设置为62.5 * 2 = 125。将比较器阀值设置为63,使占空比大约为50%。PWM->PWM_CH_NUM[0].PWM_CPRD = PWM_CPRD_CPRD(125); /* 周期 */
PWM->PWM_CH_NUM[0].PWM_CDTY = PWM_CDTY_CDTY(63); /* 占空比,准确来说是阀值 */使能PWM通道。
/* 使能 PWM */
PWM->PWM_ENA = PWM_ENA_CHID0;
三、PIO设置
在实现思路中已经说明了PIO引脚的配置,而且不是太为复杂,且后面将会给出完整代码,这里就不单独解释了。
附 完整代码
#include <sam.h> void ConfigPWM(void)
{
/* PMC 启用
* PWM的ID大于31,需要在PMC_PCER1中启用
*/
PMC->PMC_PCER1 = 1 << (ID_PWM - 32); /* 禁用通道0,以进行配置 */
PWM->PWM_DIS = PWM_DIS_CHID0; /* clockA */;
PWM->PWM_CLK = PWM_CLK_DIVA(125)
| PWM_CLK_PREA(9);
/* 配置通道0 */
PWM->PWM_CH_NUM[0].PWM_CMR = PWM_CMR_CPRE_CLKA /* 计数器时钟选择为CLKA */
; /* 周期左对齐,先输出低电平,不使用中断及死区发生器 */ PWM->PWM_CH_NUM[0].PWM_CPRD = PWM_CPRD_CPRD(125); /* 周期 */
PWM->PWM_CH_NUM[0].PWM_CDTY = PWM_CDTY_CDTY(63); /* 占空比,准确来说是阀值 */ /* 使能 PWM */
PWM->PWM_ENA = PWM_ENA_CHID0;
} void ConfigPIO(void)
{
/* 引脚由外设控制 */
PIOA->PIO_PDR = PIO_PA0;
PIOC->PIO_PDR = PIO_PC0;
/* 选择外设 */
/* PIOA选择外设A(将影响PA所有引脚) */
PIOA->PIO_ABCDSR[0] = 0;
PIOA->PIO_ABCDSR[1] = 0;
/* PC0选择外设B */
PIOC->PIO_ABCDSR[0] = PIO_ABCDSR_P0;
PIOC->PIO_ABCDSR[1] = 0; /* 配置PD20为输入 */
PIOD->PIO_PER = PIO_PD20;
PIOD->PIO_ODR = PIO_PD20;
} int main(void)
{
/* Disable WDT */
WDT->WDT_MR = WDT_MR_WDDIS; ConfigPWM();
ConfigPIO(); while (1) {
}
return 0;
}
SAM4E单片机之旅——4、LED闪烁之PWM的更多相关文章
- SAM4E单片机之旅——3、LED闪烁之定时器中断
让一个LED灯闪烁不过瘾,我们应该让这块开发板完成一点更高难度的任务:比如让两个LED灯闪烁. …… 当然了,以我们的现在使用的空循环技术,还是可以实现这点的.但是这样显得略为低端.所以我们使用一个高 ...
- SAM4E单片机之旅——23、在AS6(GCC)中使用FPU
浮点单元(Floating Point Unit,FPU),是用于处理浮点数运算的单元. 为使用FPU,除了需要启用FPU外,还需要对编译器进行设置,以使其针对浮点运算生成特殊的指令.虽然在Atmel ...
- SAM4E单片机之旅——2、LED闪烁之轮询定时器
之前我们使用空循环,达到了延迟的目的,但是这样子的延迟比较不精确.现在就使用实时定时器(RTT)来进行更为精确的计时.RTT虽然不是特别通用,在某些单片机上可能没有,但它较为简单. RTT内部有一个计 ...
- SAM4E单片机之旅——1、LED闪烁之空循环
最近因为导师要写一本关于SAME4单片机的书籍,而我也作为一个嵌入式的初学者看了这本书.现在也让我写写几个小的程序,做做示例.既然写了文档之类的,就发到博客上来吧. 目前关于这芯片能参考的书籍大概就只 ...
- SAM4E单片机之旅——7、LED闪烁之TC中断
RTT主要用做一个全局的定时器,而且不太通用.现在尝试使用一个更为通用的定时器进行定时:定时计数器(Timer Counter, TC). TC提供了广泛的功能,主要可以分为对输入的测量,以及波形的输 ...
- SAM4E单片机之旅——6、LED闪烁之按钮控制
现在试试用按钮控制LED灯……让LED在一个按钮按下时亮起:弹起时灭掉. 主要目的是学习GPIO的输入及中断. 一. 电路 图中的J39-n是几个跳线插座,位置在开发板LCD附近,往下进行前要先确保跳 ...
- SAM4E单片机之旅——5、LED呼吸和PWM
PWM在高频情况下,一个很好的用处就是通过控制占空比来控制输出的功率,比如控制风扇转速.LED灯的亮度等.这次就利用PWM的中断功能,动态改变脉冲的占空比,来实现呼吸灯的效果. 一.实现思路 PWM可 ...
- SAM4E单片机之旅——8、UART初步
通信还是比让LED灯闪烁实用得多的. 这次试试使用UART,实现开发版和PC间的通信.功能比较简单,就是把PC发向开发版的内容发送回去.这次主要介绍一下UART的配置,至于通信,则使用较为简单的不断查 ...
- SAM4E单片机之旅——24、使用DSP库求向量数量积
DSP(Digital Signal Processing,数字信号处理)中会使用大量的数学运算.Cortex-M4中,配置了一些强大的部件,以提高DSP能力.同时CMSIS提供了一个DSP库,提供了 ...
随机推荐
- 百万级日活 App 的屏幕录制功能是如何实现的
Android 从 4.0 开始就提供了手机录屏方法,但是需要 root 权限,比较麻烦不容易实现.但是从 5.0 开始,系统提供给了 App 录制屏幕的一系列方法,不需要 root 权限,只需要用户 ...
- 58同城职位分类数据 json
{ "level0": {"0": "销售", "1": "客服", "2": ...
- js拖拽效果的实现
1.最基础的写法 <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> < ...
- MX
A mail exchanger record (MX record) is a type of resource record in the Domain Name System that spec ...
- luogu P1140 相似基因
题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了4种核苷酸,简记作A,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. 在一个人类基因工作组的任务中,生物学家研究 ...
- js中call、apply、bind那些事2
前言 回想起之前的一些面试,几乎每次都会问到一个js中关于call.apply.bind的问题,比如… 怎么利用call.apply来求一个数组中最大或者最小值 如何利用call.apply来做继承 ...
- 【spring cloud】Feign使用填坑
引用地址:https://blog.csdn.net/liuchuanhong1/article/details/54728681 问题一: 在前面的示例中,我们讲过 @RequestMapping( ...
- android清除缓存为什么总是存在12k?
转载请注明出处:http://blog.csdn.net/droyon/article/details/41116529 android手机在4.2之后.清除缓存总是会残留12k的大小.预计强迫症患者 ...
- sql的一些知识_通配符
like操作符 通配符只能用于字符串查询 % 指任意字符出现任意次数,包括0次,不包括NULL SELECT username,weight,age FROM userinfo WHERE usern ...
- angular 资源路径问题
1.templateUrl .component("noData",{ templateUrl:"components/noData.html" // 注意相对 ...