一、PWM原理

1.有源蜂鸣器和无源蜂鸣器的概念

  • 有源蜂鸣器高电平就响,无源蜂鸣器需要PWM波才响。

2.PWM脉冲波

  • PWM = 定时器 + 定时器中断(重载) + IO输出(翻转)

3.分析原理图

  • GPIO-GPD0_0
  • XpwmTOUT0定时器0,同上面IO口

4.pwm定时器上的资源

  1. 5个32位定时器
  2. 定时器会产生内部中断
  3. 定时器0,1,2,3可以通过编程实现PWM,定时器4有内部计时而没有输出
  4. 定时器都有各自对应的分频区
  5. TCNTBn--,TCNTBn=TCMPBn

5.分频器 图形24-2

XpwmTOUT0 = PRESCALER0 + MUX + TCMPB0 + TCNTB0

6.例子分析

  1. 开启自动重载
  2. 设置TCNTBn和TCMPBn寄存器
  3. 手动设置
  4. 设置自动翻转,更新TCNTBn和TCMPBn寄存器
  5. 再次设置TCNTBn和TCMPBn寄存器(双缓冲再次更新)
  6. 定时器开启
  7. TCNTBn--,TCNTBn=TCMPBn,翻转
  8. TCNTn=0,产生中断
  9. 自动重载
  10. TCNTBn--,TCNTBn=TCMPBn,翻转
  11. TCNTn=0,产生中断
  12. 自动重载,产生中断。然后关闭自动重载
  13. TCNTBn--,TCNTBn=TCMPBn,翻转
  14. TCNTn=0,关闭自动重载,不再产生中断
  15. 自动重载关闭,停止。

7.简单用法

  1. GPIO-GPD0_0设置为PWM输出GPD0CON[0] = 0x02
  2. TCFG0 预分频(1-255)
  3. TCFG1分频(1,2,4,8,16)
  4. 设置占空比:TCMPB0 和 TCNTB0 (TCMPB0<TCNTB0)
  5. 设置自动重载,开启定时器,自动翻转等。TCON 寄存器

二、pwm的ioremap

1.配置步骤

  1. GPD0_0设置为pwm输出GPD0CON[0]=0x02
  2. TCFG0预分频(1-255)
  3. TCFG1分频(1.2.4.8.16)
  4. 设置占空比:TCMPB0和TCNTB0(TCMPB0<TCNTB0)
  5. 设置自动重载,开启定时器等
  6. TCON寄存器

2.写代码

beep驱动

#include <linux/init.h>
#include <linux/module.h> #include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include <linux/fs.h> #include <linux/gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio.h>
#include <mach/gpio-exynos4.h> #include <asm/io.h> #define DRIVER_NAME "PWM"
#define DEVICE_NAME "PWM" MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("TOPEET"); struct pwm_addr{
unsigned int TCFG0;
unsigned int TCFG1;
unsigned int TCON;
unsigned int TCNTB0;
unsigned int TCMPB0;
unsigned int TCNTO0;
unsigned int TCNTB1;
unsigned int TCMPB1;
unsigned int TCNTO1;
unsigned int TCNTB2;
unsigned int TCMPB2;
unsigned int TCNTO2;
unsigned int TCNTB3;
unsigned int TCMPB3;
unsigned int TCNTO3;
unsigned int TCNTB4;
unsigned int TCNTO4;
unsigned int TINT_CSTAT;
}*PWM; //sotre virtual address and physical address
volatile unsigned long virt_addr, virt_addr_gpio, phys_addr, phys_addr_gpio;
volatile unsigned long *GPD0CON, *GPD0PUD; static void addr_init(void)
{
phys_addr = 0x139D0000; //(PWM Base Address)
virt_addr = (unsigned long)ioremap(phys_addr, 0x48); //maybe 0x32 not enough
PWM = (struct pwm_addr*)(virt_addr + 0x00); phys_addr_gpio = 0x11400000+0xA0; //GPD0
virt_addr_gpio = (unsigned long)ioremap(phys_addr_gpio, 0x24);
GPD0CON = (unsigned long*)(virt_addr_gpio + 0x00);
GPD0PUD = (unsigned long*)(virt_addr_gpio + 0x00A8 - 0x00A0);
} static void PWM_Init(void)
{
addr_init();
/* config gpio */
*GPD0CON &= ~(0xf);
*GPD0CON |= 0x2; //TOUT_0
*GPD0PUD &= ~(0x03); //disable pull-up/pull-down //prescaler0 0-254 + 1
(*PWM).TCFG0 = (((*PWM).TCFG0&(~(0xff)))|(0xf9));
//prescaler1 1.2.4.8.16
(*PWM).TCFG1 = ((*PWM).TCFG1&(~(0xf)))|(0x2);
//set duty cycle
(*PWM).TCMPB0 = ;
(*PWM).TCNTB0 = ;
//set auto-reload,timer on
(*PWM).TCON = ((*PWM).TCON & (~(0xf))) | (0x1) | (0x2);
} static void beep_on(void)
{
(*PWM).TCON = ((*PWM).TCON & (~(0xf)))|(0x1)|(0x8);
} static void beep_off(void)
{
(*PWM).TCON = ((*PWM).TCON & (~(0xf)))|(0x0);
//After timer stop,GPIO = 0;
*GPD0CON = (*GPD0CON & (~(0xf)))|(0x0);
} static int iTop4412_PWM_init(void)
{
PWM_Init();
beep_on();
return ;
} static void iTop4412_PWM_exit(void)
{
beep_off();
} module_init(iTop4412_PWM_init);
module_exit(iTop4412_PWM_exit);

pwm

测试结果:

[root@iTOP-]# insmod pwm.ko
[root@iTOP-]# rmmod pwm

加载后蜂鸣器开启,不过频率不对

总结:根据逻辑框图中的寄存器名字,在PDF中搜索然后依次配置它。找到一个后,可以往下翻。类似的可能会在一起

4412 PWM的更多相关文章

  1. 4412 4路pwm输出

    一.4412 xpwmTOUT1 这是4412的GPD0_1路,itop中被使用为LCD的背光电路的pwm功能.因此如果使用教程中的代码,同样操作GPD0_1是行不通的. 会出现错误,所以需要解除在内 ...

  2. 4412 gpio读取pwm

    一.可以使用的GPIO管脚 去掉占用调用的GPIO驱动,包括leds,buzzer,camera ov5640,WIFI mt6620 ,Keyboards VIDEO_OV5640– Device ...

  3. exynos 4412 电源管理芯片PMIC 的配置及使用方法

    /** ****************************************************************************** * @author    Maox ...

  4. Cortex-A9 PWM Timer

    PWM定时器        4412时钟为我们提供了PWM定时器,在4412中共有5个32位的定时器,这些定时器可发送中断信号给ARM子系统.另外,定时器0.1.2.3包含了脉冲宽度调制(PWM),并 ...

  5. 基于ARM-contexA9-蜂鸣器pwm驱动开发

    上次,我们写过一个蜂鸣器叫的程序,但是那个程序仅仅只是驱动蜂鸣器,用电平1和0来驱动而已,跟驱动LED其实没什么两样.我们先来回顾一下蜂鸣器的硬件还有相关的寄存器吧: 还是和以前一样的步骤: 1.看电 ...

  6. STM32之PWM君

    PWM..英语好的人估计又知道这三个大写字母代表哪三个英语单词了.小弟不才,就说中文意思好了:脉冲宽度调制,玩过飞思卡尔的人估计对PWM非常的不陌生吧.电机驱动需要PWM,控制舵机的转向需要PWM,总 ...

  7. [nRF51822] 12、基础实验代码解析大全 · 实验19 - PWM

    一.PWM概述: PWM(Pulse Width Modulation):脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形. PWM 的几个基本概念: 1) 占空比:占空比是指 ...

  8. Windows on Device 项目实践 1 - PWM调光灯制作

    在前一篇文章<Wintel物联网平台-Windows IoT新手入门指南>中,我们讲解了Windows on Device硬件准备和软件开发环境的搭建,以及Hello Blinky项目的演 ...

  9. 【转帖】嵌入式4412开发板QT5.7编译安装到arm

    QT5.7.0+UBUNTU16.04+ARM-NONE-LINUX-GNUEABI4.8+busybox最小LINUX系统 Orandragon记录 本文转自迅为4412开发板群:http://to ...

随机推荐

  1. 用PHP实现一些常见的排序算法

    1.冒泡排序: 两两相比,每循环一轮就不用再比较最后一个元素了,因为最后一个元素已经是最大或者最小. function maopaoSort ($list) { $len = count($list) ...

  2. Visual Studio Code-使用Chrome Debugging for VS Code调试JS

    准备工作 安装 Debugger for Chrome 插件 按 F5(或选择菜单栏的 Debug->Start Debuging),然后选择 Chrome,就会自动创建默认的配置文件 &quo ...

  3. 124、TensorFlow替换函数

    # tf.device给你了很多可伸缩性在TensorFlow的计算图中选择放置你的单独的操作 # 在许多的情况下,有很多启发可以工作的很好 # 例如tf.train.replica_device_s ...

  4. day36—javascript对表格table的操作应用(一)

    转行学开发,代码100天——2018-04-21 今天记录一下,JavaScript对表格table的操作应用,包括表格元素的获取,创建,删除等. 一个普通的完整表格包括以下几个部分:table-&g ...

  5. Linux实用技巧--隧道

    平时开发过程中,可能会遇到一些网络问题,比如npm install 一些依赖包.本地电脑是可以,没有问题.但是测试环境服务器,由于公司内部网络安全限制,不可以随意访问外部网络.因此下载一个依赖包就变得 ...

  6. 设计模式 - 装饰器模式(Decorator)

    简介 场景 通过继承和关联都可以给对象增加行为,区别如下: 继承是静态的(无法在程序运行时动态扩展),且作用于所有子类.硬编码,高耦合. 通过装饰器可以在运行时添加行为和属性到指定对象.关联关系就是在 ...

  7. Vue访问子组件实例或子元素

    1 尽管存在 prop 和事件,有的时候你仍可能需要在 JavaScript 里直接访问一个子组件(例如,调用子组件的方法).为了达到这个目的,你可以通过 ref 特性为这个子组件赋予一个 ID 引用 ...

  8. 【ABAP系列】SAP ABAP与Java数据类型的对应关系

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP与Java数据类 ...

  9. Linux——通配符

    因为 shell 频繁地使用文件名,所以shell有一个使命令行强大的特性, shell 提供了特殊字符来帮助我们快速指定一组文件名.这些特殊字符叫做通配符.使用通配符(也以文件名代换著称)允许我们依 ...

  10. JS动态添加Easyui的HTML时样式丢失

    解决办法: $.parser.parse($("#creatLi").html(<li>xxxxxx</li>)); ------------------- ...