由于imx6并没有PWM计数功能,本次PWM计数主要通过中断进行PWM计数,
本文使用linux3.015的内核,没有设备树。
1、照葫芦画瓢,参考其他的中断,利用platform_get_irq函数获取中断号。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78/******Pwm.h中****************/ struct pwm_device { struct list_head node; struct platform_device *pdev; const char *label; struct clk *clk; int clk_enabled; void __iomem *mmio_base; unsigned int use_count; unsigned int pwm_id; int pwmo_invert; int irq; /*新添加*/ void (*enable_pwm_pad)(void); void (*disable_pwm_pad)(void); }; /*添加以下中断要用的函数*/ int pwm_irq_enable(struct pwm_device *pwm); /*使能*/ int pwm_irq_disable(struct pwm_device *pwm);/*失能*/ int pwm_irq_clearflags(struct pwm_device *pwm); /*清除标志位*/ int pwm_irq_stop(struct pwm_device *pwm);/*停止中断*/ /******Pwm.c中****************/ static int __devinit mxc_pwm_probe(struct platform_device *pdev) { /*此处省略n行代码*/ pwm->irq = platform_get_irq(pdev, 0); /*获取中断号*/ if (pwm->irq < 0) { ret = -EINVAL; } } ///PWM interrupt config// ///config fifo interrupt/ int pwm_irq_enable(struct pwm_device *pwm) { unsigned long reg; reg = readl(pwm->mmio_base + MX3_PWMMIR); reg |=MX3_PWM_ROV_IRQ_EN; writel(reg,pwm->mmio_base + MX3_PWMMIR); } EXPORT_SYMBOL(pwm_irq_enable); /*添加以下函数与宏定义*/ #define MX3_PWMMIR 0x08 /* PWM interrupt Register */ #define MX3_PWMFIFOIRQ_EN (1 << 0) #define MX3_PWM_ROV_IRQ_EN (1 << 1) #define MX3_PWMSR 0x04 /* PWM statues Register */ #define MX3_PWM_ROV_EN (1 << 4) int pwm_irq_disable(struct pwm_device *pwm) { /*unsigned long reg; reg = readl(pwm->mmio_base + MX3_PWMMIR); reg &=~ MX3_PWM_ROV_IRQ_EN;*/ writel(0,pwm->mmio_base + MX3_PWMMIR); } EXPORT_SYMBOL(pwm_irq_disable); int pwm_irq_clearflags(struct pwm_device *pwm) { unsigned long reg; reg = readl(pwm->mmio_base + MX3_PWMSR); reg |= MX3_PWM_ROV_EN; writel(reg,pwm->mmio_base + MX3_PWMSR); } EXPORT_SYMBOL(pwm_irq_clearflags); int pwm_irq_stop(struct pwm_device *pwm) { writel(0,pwm->mmio_base + MX3_PWMCR); } EXPORT_SYMBOL(pwm_irq_stop);
写好后,将内核编译,
另写一个驱动直接调用PWM定义的函数即可,如创建PWM1的中断
复制代码
1
2
3
4
5
6
7
8
9
10
11
12int pwm_irq(struct pwm_device *pwm) { int d1; d1=pwm->irq; printk("d1=%d!rn",d1); return d1; } /*在某函数调用*/ d1= pwm_irq(pwm_dev_2); pwm_irq_enable(pwm_dev_2); ret = request_irq(d1,pwm1_isr,0,"PWM1",pwm_dev_2);
其中pwm1_isr就是中断函数,定义一个count每次加1即可实现PWM计数。
通过示波器发现,有时候计数会出现误差,但误差在可接受范围内,待进一步测试后再确认该计数方式是否可行,除了pwm翻转中断计数外,可用FIFO空中断实现PWM粗略计数,也有人用EPIT精准定时器来进行计数,具体用那种方式比较好还有待研究。
最后
以上就是跳跃镜子最近收集整理的关于imx6的PWM计数的全部内容,更多相关imx6内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复