使用ioremap调用pwm开启蜂鸣器

查看数据手册

使用的GPIO

原理图
在这里插入图片描述
核心板
在这里插入图片描述
可以看到使用了GPD0_0,需要用到GPD0CON(选择定时器),GPD0PUD(禁止上下拉)。

pwm定时器

4412(scp封装)有5个32位的定时器,其中0、1、2、3可以用来编程其中0、1共用第一个8位预分频器,2、3、4共用第二个8位预分频器,都可输出2,4,8,16的频率。
定时器

设置定时器(占空比)

(1)需要用到TCMPBn(用于比较),TCNTBn(初值) 寄存器,设置好TCMPBn,TCNTBn的值后,TCON开启定时器。(其实只要记住TCNTBn>TCMPBn即可)。
(2)TCMPBn值传入TCMPn ,TCNTBn值会传入TCNTn。
(3)TCNTn开始做减1的操作,当TCNTn等于TCMPn,输出电平翻转,当TCNTn减为0,输出电平再次翻转,并触发定时器中断。
(4)若TCON开启了自动重载,那会重复(2),(3)操作,再次开启下一次计时操作。
在这里插入图片描述

代码

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <mach/regs-gpio.h>
#include <asm/io.h>
#include <linux/regulator/consumer.h>
#include <linux/delay.h>

struct PWM_union
{
	unsigned int TCFG0;
	unsigned int TCFG1;
	unsigned int TCON;
	unsigned int TCNTB0;
	unsigned int TCMPB0;	//TCMPB0 < TCNTB0
};

struct PWM_union *Pwm;
//gpio和pwm定时器虚拟地址和物理地址
volatile unsigned long virt_pwm_addr,virt_gpio_addr,phy_pwm_addr,phy_gpio_addr;
//gpio的寄存器
volatile unsigned long *GPD0CON,*GPD0PUD;

void addr_init(void)
{
	printk(KERN_EMERG "addr init");
	phy_pwm_addr=0x139D0000;
	phy_gpio_addr=0x11400000;
	
	virt_pwm_addr = (unsigned long)ioremap(phy_pwm_addr,0x32);
	Pwm = (unsigned int*)(virt_pwm_addr+0x00);
	
	virt_gpio_addr = (unsigned long)ioremap(phy_gpio_addr,0x10);
	GPD0CON = (unsigned long*)(virt_gpio_addr+0x00A0);
	GPD0PUD = (unsigned long*)(virt_gpio_addr+0x00A8);
}

void pwm_init(void)
{
	addr_init();
	*GPD0CON &= ~(0xf);
	*GPD0CON |=	0x2;	//定时器0 TOUT_0
	
	*GPD0PUD &= ~(0xf);	//不要上下拉
	
	//预分频
	Pwm->TCFG0 &= ~(0xff);
	Pwm->TCFG0 |= 0xf9;	//这个值是1到255即(0x01-0xff);
	//分频
	Pwm->TCFG1 &= ~(0xf);
	Pwm->TCFG1 |= 0x2;	
	//占空比
	Pwm->TCMPB0 = 50;
	Pwm->TCNTB0 = 100;
	//手动加载 开启定时器
	Pwm->TCON &= ~(0xf);
	//定时器
	Pwm->TCON |= 0x1;
	//手动加载
	Pwm->TCON |= 0x2;
}

static void beep_on(void)
{
	//开启自动加载
	Pwm->TCON &= ~(0xf);
	Pwm->TCON |= 0x1;
	Pwm->TCON |= 0x8;
}
static void beep_off(void)
{
	//关闭定时器
	Pwm->TCON &= ~(0xf);
	Pwm->TCON |= 0x0;
	//gpio
	*GPD0CON &= ~(0xf);
	*GPD0CON |=	0x0;
}

static int BEEP_PWM_init(void)
{
    printk(KERN_EMERG "BEEP_PWM_init\n"); 
    
	pwm_init();
	beep_on();
    return 0;
}

static void BEEP_PWM_exit(void)
{
    printk(KERN_EMERG "BEEP_PWM_exit\n");
	beep_off();
}



module_init(BEEP_PWM_init);
module_exit(BEEP_PWM_exit);//初始化函数
MODULE_LICENSE("Dual_BSD/GPL"); //没有版本限制,什么版本都能运行
MODULE_AUTHOR("LIN"); //作者

本人也是新手有什么错误,请麻烦指出来。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值