TA的每日心情 | 奋斗 2022-9-16 05:52 |
---|
签到天数: 1368 天 连续签到: 1 天 [LV.10]以坛为家III
|
其实比较来说,PWM比中断还要简单,只不过一般刚接触的板子首先实现的都是基本的IO,所以把PWM安排在了中断之后。为了不使帖子看起来内容太少,这个程序将两路PWM 放在了一起,不过也是多了几个寄存器的设置而已。
另外要吐槽一下A10,PWM少就不说什么了,居然计数寄存器只有8位。是的,只有8位,最大到255而已,这个也太弱了吧
还有预分频,也只有这么几个
看到0101...0111那几个了吗?经过尝试后,发现其实是起作用的,是/720、/840、/960,后面的1101...1111是84K、96K、108K,权当一点补偿吧。
下面上程序,跟GPIO的一样,还是精简得不能再精简了。接线方式没来得及拍照,后面补上。
- #include <linux/init.h>
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/cdev.h>
- #include <linux/device.h>
- #include <linux/wait.h>
- #include <linux/delay.h>
- #include <asm/io.h>
- #include <asm/uaccess.h>
- #include "../A10.h"
- /**********************************************************************/
- #define PWM_CH0 2
- volatile static unsigned long* REG_PB_CFG0;
- volatile static unsigned long* REG_PI_CFG0;
- volatile static unsigned long* REG_PWM_CTRL_REG;
- volatile static unsigned long* REG_PWM_CH0_PERIOD;
- volatile static unsigned long* REG_PWM_CH1_PERIOD;
- static int Inited = 0;
- static int PWM_open(struct inode* n, struct file* f)
- {
- int Result = 0;
- Inited++;
- if (Inited > 1)
- {
- return 0;
- }
- REG_PB_CFG0 = (volatile unsigned long*) ioremap(PB_CFG0, 4);
- REG_PI_CFG0 = (volatile unsigned long*) ioremap(PI_CFG0, 4);
- REG_PWM_CTRL_REG = (volatile unsigned long*) ioremap(PWM_CTRL_REG, 4);
- REG_PWM_CH0_PERIOD= (volatile unsigned long*) ioremap(PWM_CH0_PERIOD, 4);
- REG_PWM_CH1_PERIOD= (volatile unsigned long*) ioremap(PWM_CH1_PERIOD, 4);
- *REG_PB_CFG0 &= ~(0x7 << 8) ;
- *REG_PB_CFG0 |= (0x2 << 8) ; //PWM0
- *REG_PI_CFG0 &= ~(0x7 << 12) ;
- *REG_PI_CFG0 |= (0x2 << 12) ; //PWM1
- *REG_PWM_CH0_PERIOD = (249 << 16) + 5;
- *REG_PWM_CTRL_REG |= (0xF << 0);
- *REG_PWM_CTRL_REG |= (0x0 << 8) + (0x0 << 7) + (0x1 << 6) + (0x0 << 5);
- *REG_PWM_CTRL_REG |= (0x1 << 4);
- *REG_PWM_CH1_PERIOD = (249 << 16) + 5;
- *REG_PWM_CTRL_REG |= (0x8 << 15);
- *REG_PWM_CTRL_REG |= (0x0 << 23) + (0x0 << 22) + (0x1 << 21) + (0x1 << 20);
- *REG_PWM_CTRL_REG |= (0x1 << 19);
- printk("Open Finished!\n");
- return Result;
- }
- static ssize_t PWM_write(struct file* f, const char __user* buf, size_t len, loff_t* l)
- {
- //printk("Write Finished!\n");
- return 0;
- }
- static ssize_t PWM_read(struct file* f, char __user* buf, size_t len, loff_t* l)
- {
- //printk("Read Finished!\n");
- return 0;
- }
- static int PWM_close(struct inode* n, struct file* f)
- {
- Inited--;
- if (Inited > 0)
- {
- return 0;
- }
- *REG_PWM_CTRL_REG = 0;
- *REG_PWM_CH0_PERIOD = 0;
- *REG_PWM_CH1_PERIOD = 0;
- iounmap(REG_PB_CFG0);
- iounmap(REG_PI_CFG0);
- iounmap(REG_PWM_CTRL_REG);
- iounmap(REG_PWM_CH0_PERIOD);
- iounmap(REG_PWM_CH1_PERIOD);
- printk("Close Finished!\n");
- return 0;
- }
- /**********************************************************************/
- #define DEV_NAME "WM"
- #define DEV_COUNT 1
- static struct class* pClass;
- int major;
- static struct file_operations fops =
- {
- .owner = THIS_MODULE,
- .open = PWM_open,
- .write = PWM_write,
- .read = PWM_read,
- .release = PWM_close,
- };
- static int __init PWM_init(void)
- {
- major = register_chrdev(0, DEV_NAME, &fops);
- pClass = class_create(THIS_MODULE, DEV_NAME);
- if (pClass == NULL)
- {
- unregister_chrdev(major, DEV_NAME);
- return -1;
- }
- device_create(pClass, NULL, MKDEV(major, 0), NULL, DEV_NAME);
- PWM_open(NULL, NULL);
- //printk("Init Finished!\n");
- return 0;
- }
- static void __exit PWM_exit(void)
- {
- PWM_close(NULL, NULL);
- unregister_chrdev(major, DEV_NAME);
- if (pClass)
- {
- device_destroy(pClass, MKDEV(major, 0));
- class_destroy(pClass);
- }
- //printk("Exit Finished!\n");
- }
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("LiuYang");
- module_init(PWM_init);
- module_exit(PWM_exit);
|
|