pcDuino Linux驱动开发五 -- 最简单的PWM驱动

作者: tjcfeng
上传时间为: 2014-11-30 11:14 PM

其实比较来说,PWM比中断还要简单,只不过一般刚接触的板子首先实现的都是基本的IO,所以把PWM安排在了中断之后。为了不使帖子看起来内容太少,这个程序将两路PWM 放在了一起,不过也是多了几个寄存器的设置而已。

另外要吐槽一下A10,PWM少就不说什么了,居然计数寄存器只有8位。是的,只有8位,最大到255而已,这个也太弱了吧

还有预分频,也只有这么几个

看到0101...0111那几个了吗?经过尝试后,发现其实是起作用的,是/720、/840、/960,后面的1101...1111是84K、96K、108K,权当一点补偿吧。

下面上程序,跟GPIO的一样,还是精简得不能再精简了。接线方式没来得及拍照,后面补上。

  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/fs.h>
  4. #include <linux/cdev.h>
  5. #include <linux/device.h>
  6. #include <linux/wait.h>
  7. #include <linux/delay.h>
  8. #include <asm/io.h>
  9. #include <asm/uaccess.h>
  10. #include "../A10.h"
  11. /**********************************************************************/
  12. #define PWM_CH0 2
  13. volatile static unsigned long* REG_PB_CFG0;
  14. volatile static unsigned long* REG_PI_CFG0;
  15. volatile static unsigned long* REG_PWM_CTRL_REG;
  16. volatile static unsigned long* REG_PWM_CH0_PERIOD;
  17. volatile static unsigned long* REG_PWM_CH1_PERIOD;
  18. static int Inited = 0;
  19. static int PWM_open(struct inode* n, struct file* f)
  20. {
  21. int Result = 0;
  22. Inited++;
  23. if (Inited > 1)
  24. {
  25. return 0;
  26. }
  27. REG_PB_CFG0 = (volatile unsigned long*) ioremap(PB_CFG0, 4);
  28. REG_PI_CFG0 = (volatile unsigned long*) ioremap(PI_CFG0, 4);
  29. REG_PWM_CTRL_REG = (volatile unsigned long*) ioremap(PWM_CTRL_REG, 4);
  30. REG_PWM_CH0_PERIOD= (volatile unsigned long*) ioremap(PWM_CH0_PERIOD, 4);
  31. REG_PWM_CH1_PERIOD= (volatile unsigned long*) ioremap(PWM_CH1_PERIOD, 4);
  32. *REG_PB_CFG0 &= ~(0x7 << 8) ;
  33. *REG_PB_CFG0 |= (0x2 << 8) ; //PWM0
  34. *REG_PI_CFG0 &= ~(0x7 << 12) ;
  35. *REG_PI_CFG0 |= (0x2 << 12) ; //PWM1
  36. *REG_PWM_CH0_PERIOD = (249 << 16) + 5;
  37. *REG_PWM_CTRL_REG |= (0xF << 0);
  38. *REG_PWM_CTRL_REG |= (0x0 << 8) + (0x0 << 7) + (0x1 << 6) + (0x0 << 5);
  39. *REG_PWM_CTRL_REG |= (0x1 << 4);
  40. *REG_PWM_CH1_PERIOD = (249 << 16) + 5;
  41. *REG_PWM_CTRL_REG |= (0x8 << 15);
  42. *REG_PWM_CTRL_REG |= (0x0 << 23) + (0x0 << 22) + (0x1 << 21) + (0x1 << 20);
  43. *REG_PWM_CTRL_REG |= (0x1 << 19);
  44. printk("Open Finished!\n");
  45. return Result;
  46. }
  47. static ssize_t PWM_write(struct file* f, const char __user* buf, size_t len, loff_t* l)
  48. {
  49. //printk("Write Finished!\n");
  50. return 0;
  51. }
  52. static ssize_t PWM_read(struct file* f, char __user* buf, size_t len, loff_t* l)
  53. {
  54. //printk("Read Finished!\n");
  55. return 0;
  56. }
  57. static int PWM_close(struct inode* n, struct file* f)
  58. {
  59. Inited--;
  60. if (Inited > 0)
  61. {
  62. return 0;
  63. }
  64. *REG_PWM_CTRL_REG = 0;
  65. *REG_PWM_CH0_PERIOD = 0;
  66. *REG_PWM_CH1_PERIOD = 0;
  67. iounmap(REG_PB_CFG0);
  68. iounmap(REG_PI_CFG0);
  69. iounmap(REG_PWM_CTRL_REG);
  70. iounmap(REG_PWM_CH0_PERIOD);
  71. iounmap(REG_PWM_CH1_PERIOD);
  72. printk("Close Finished!\n");
  73. return 0;
  74. }
  75. /**********************************************************************/
  76. #define DEV_NAME "PWM"
  77. #define DEV_COUNT 1
  78. static struct class* pClass;
  79. int major;
  80. static struct file_operations fops =
  81. {
  82. .owner = THIS_MODULE,
  83. .open = PWM_open,
  84. .write = PWM_write,
  85. .read = PWM_read,
  86. .release = PWM_close,
  87. };
  88. static int __init PWM_init(void)
  89. {
  90. major = register_chrdev(0, DEV_NAME, &fops);
  91. pClass = class_create(THIS_MODULE, DEV_NAME);
  92. if (pClass == NULL)
  93. {
  94. unregister_chrdev(major, DEV_NAME);
  95. return -1;
  96. }
  97. device_create(pClass, NULL, MKDEV(major, 0), NULL, DEV_NAME);
  98. PWM_open(NULL, NULL);
  99. //printk("Init Finished!\n");
  100. return 0;
  101. }
  102. static void __exit PWM_exit(void)
  103. {
  104. PWM_close(NULL, NULL);
  105. unregister_chrdev(major, DEV_NAME);
  106. if (pClass)
  107. {
  108. device_destroy(pClass, MKDEV(major, 0));
  109. class_destroy(pClass);
  110. }
  111. //printk("Exit Finished!\n");
  112. }
  113. MODULE_LICENSE("GPL");
  114. MODULE_AUTHOR("LiuYang");
  115. module_init(PWM_init);
  116. module_exit(PWM_exit);
全部评论 ()

创建讨论帖子

登录 后参与评论
系统提示