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库,提供了 ...
随机推荐
- La 3942 字符串+dp
题目大意:一个字符串,可以分解成若干英语单词的连接(单词可以重复使用),求有多少种方法? #include<iostream> #include<cstdio> #includ ...
- 【CF1023C】Bracket Subsequence(模拟)
题意:给定一个正则括号序列 s ,让你在当中选择一个长度正好为 t 的子串,使得 t 恰好也是一个正则括号序列 思路:用栈模拟 #include<cstdio> #include<c ...
- 以iphone6plus 为标准单位是px的页面 在运行时转换为rem
在页面中引入以下代码,把样式中带px单位的样式放到本页面中的<style>标签中 /** * Created by Administrator on 2017-03-14. */ /*** ...
- hdu 4937 2014 Multi-University Training Contest 7 1003
Lucky Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) T ...
- python学习之-- 故障记录汇总
以下为我编程期间遇到的错误并进行记录,起始时间2017-6-21 时间:2018/11/21问题现象:ajax 执行异步提交后,在访问日志看出现了2次post执行分析:默认ajax提交是执行一次,然后 ...
- 迅雷在P2P网络中的另类上传速度
如上图,我们一般在下载BT时,一般P2P是边下载边上传. 但是迅雷在自己的软件中可以设置上传速度,反而在展示时却把P2P协议的速度不在上传那么显示,而是使用协议速度来进行展示:并且这个速度无法设置. ...
- Geoserver跨域请求设置
使用OpenLayers请求GeoServer发布的WFS服务时,如果不是相同的域可能会出现如下问题. 已拦截跨源请求:同源策略禁止读取位于 http://localhost:8080/geoserv ...
- 3.【nuxt起步】-下面以一个SPA单页程序为例子
spa:single page applcation 1.components目录新建header.vue,footer.vue Header.vue Footer.vue Pages/index.v ...
- 一天时间用OpenFire打造自己的IM聊天工具
Openfire采用Java开发,开源的实时协作(RTC)服务器基于XMPP(Jabber)协议.Openfire安装和使用都非常简单,并利用Web进行管理.单台服务器可支持上万并发用户. 好友界面 ...
- vue2.0 自定义 侧滑删除(LeftSlider)组件
1.自定义侧滑删除组件 LeftSlider.vue <!-- 侧滑删除 组件 --> <template> <div class="delete"& ...