• 4412 PWM


    一、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 = 50;
            (*PWM).TCNTB0 = 100;
            //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 0;
    }
    
    static void iTop4412_PWM_exit(void)
    {
            beep_off();
    }
    
    module_init(iTop4412_PWM_init);
    module_exit(iTop4412_PWM_exit);
    pwm

    测试结果:

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

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

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

  • 相关阅读:
    【WIN10】我的第一個WIN10-UWP應用——古文觀止
    【WIN10】文本圖標
    【WIN10】VisualStateManager使用說明
    【WIN10】Storyboard動畫板
    【WIN10】Bind、Binding與Converter的使用
    struts执行过程
    在jsp中的局部和全局变量
    jsp页面中的:<%@ page contentType="text/html; charset=utf-8" language="java"%>的作用及含义
    jsp中的this
    在Java接口中怎样访问定义的常量呢?
  • 原文地址:https://www.cnblogs.com/ch122633/p/9506835.html
Copyright © 2020-2023  润新知