微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 第七篇?Rico board实现4路“DA”输出

第七篇?Rico board实现4路“DA”输出

时间:10-02 整理:3721RD 点击:

因为我要通过4路DA输出,控制两路电机,而Rico Board上又没有直接输出DA的部分,所以我考虑为了节省资金,准备通过4路PWM输出来实现4路DA的输出功能。

第一步:

先把4路DA正常输出吧,用的hrt高精度时钟,主要为了实现比较平滑的输出,pwm的频率越高,低通滤波后的输出越平滑,这也是我所希望的。

硬件上,用了4个GPIO实现4路输出,如下所示:


实现的效果如下:


我同时测试了两路输出,因为示波器只有两个通道啊。


测了三组:


测试的硬件连接图:



示波器的显示如下所示:




今天焊上了滤波电路,也测了三组,终端显示如下:


分别表示1650mv,330mv,3267mv


滤波后的输出波形,示波器测试如下:




但是把信号加入到电机驱动时,发现电压被拉低或是被太高,准备明天再加一级跟随试一试


下图是我的滤波电路和测试现场图:





驱动代码如下:

  1. /*************************
  2. *
  3. *[url=home.php?mod=space&uid=1455510]@file[/url] mada.c
  4. *@date 2016.11.12
  5. *author iysheng
  6. *
  7. *************************/


  8. #include
  9. #include
  10. #include
  11. #include
  12. #include
  13. #include
  14. #include
  15. #include
  16. #include
  17. #include


  18. MODULE_LICENSE("GPL");
  19. MODULE_AUTHOR("iysheng ");
  20. MODULE_VERSION("0.1");

  21. #define MADA_NUM 4
  22. #define MADA_NAME "MADA"
  23. #define NAME_SIZE 10
  24. #define MADA_TIME_SCALE 1000

  25. #define VALUE_SIZE 8

  26. #define MADA_MAJOR 0

  27. static dev_t mada_devnum;
  28. static int mada_major = MADA_MAJOR;

  29. #define  P_VOLTAGE  33
  30. #define MADA_VOLTAGE(devp) (P_VOLTAGE*(devp->mada_high)/10)

  31. int mada_gpio[MADA_NUM] = {164, 165, 166, 167};

  32. struct mada_dev{
  33.         struct cdev cdev;
  34.         struct device *device;
  35.         int mada_gpio;
  36.         unsigned int mada_high;
  37.         unsigned int mada_voltage;
  38.         dev_t devnum;
  39.         char mada_name[NAME_SIZE];
  40.         struct hrtimer mada_hrt;
  41.         bool mada_gpio_value;
  42.         bool mada_hrt_state;
  43. } *mada_devp;

  44. struct class *mada_class;

  45. /*
  46. int MADA_VOLTAGE(struct mada_dev * devp)
  47. {
  48.         int voltage;
  49.         voltage = P_VOLTAGE * devp->mada_high;
  50.         return voltage;
  51. }
  52. */

  53. enum hrtimer_restart mada_hrt_callback(struct hrtimer *hrt)
  54. {
  55.         struct mada_dev *devp;
  56.         devp = container_of(hrt, struct mada_dev, mada_hrt);
  57.         devp->mada_gpio_value = !devp->mada_gpio_value;
  58.         gpio_set_value(devp->mada_gpio, devp->mada_gpio_value);
  59.         if(devp->mada_gpio_value == true)
  60.                 hrtimer_forward_now(hrt, ns_to_ktime(devp->mada_high * MADA_TIME_SCALE));
  61.         else
  62.                 hrtimer_forward_now(hrt, ns_to_ktime((1000 - devp->mada_high) * MADA_TIME_SCALE));
  63.         return HRTIMER_RESTART;
  64. }

  65. int mada_open (struct inode *inode, struct file *filp)
  66. {
  67.         struct mada_dev *devp = container_of(inode->i_cdev, struct mada_dev, cdev);
  68.         filp->private_data = devp;
  69.         if(devp->mada_hrt_state == false)
  70.         {
  71.                 hrtimer_init(&devp->mada_hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
  72.                 devp->mada_hrt.function = mada_hrt_callback;
  73.                 hrtimer_start(&devp->mada_hrt,ns_to_ktime(devp->mada_high),HRTIMER_MODE_REL);
  74.                 devp->mada_hrt_state = true;
  75.         }
  76.         printk(KERN_INFO "mada_open func.\n");
  77.         return 0;
  78. }

  79. int mada_release (struct inode *inode, struct file *filp)
  80. {
  81.         printk(KERN_INFO "mada_release func.\n");
  82.         return 0;
  83. }

  84. ssize_t mada_write (struct file *filp, const char __user *buf, size_t count, loff_t *ppos)
  85. {
  86.         int ret;
  87.         char value[VALUE_SIZE];
  88.         struct mada_dev *devp = filp->private_data;
  89.         ret = copy_from_user(value, buf, sizeof(buf));
  90.         if(0 != ret)
  91.         {
  92.                 printk(KERN_INFO "error in writing and errnum is %d.\n", ret);
  93.                 return 0;
  94.         }       
  95.         else
  96.                 devp->mada_high = (unsigned int)simple_strtoul(value, NULL, 10);       
  97.         return sizeof(buf);
  98. }

  99. ssize_t mada_read (struct file *filp, char __user *buf, size_t count, loff_t *ppos)
  100. {
  101.         int ret;
  102.         struct mada_dev *devp = filp->private_data;
  103.         char value[VALUE_SIZE];
  104.         devp->mada_voltage = MADA_VOLTAGE(devp);
  105.         sprintf(value, "%d", devp->mada_voltage);
  106.         ret = copy_to_user(buf,value,sizeof(value));
  107.         if(0 != ret)
  108.         {
  109.                 printk(KERN_INFO "error in reading and errnum is %d.\n", ret);
  110.         }
  111.         else               
  112.                 printk(KERN_INFO "%s mada_voltage is %s.\n",devp->mada_name,value);
  113.         return ret;
  114. }


  115. struct file_operations mada_fops = {
  116.         .open = mada_open,
  117.         .release = mada_release,
  118.         .read = mada_read,
  119.         .write = mada_write,
  120. };

  121. int mada_setup(struct mada_dev *devp, int min, int gpio_num)
  122. {
  123.         int ret = 0;
  124.         printk(KERN_INFO "mada_setup function.\n");
  125.         if(!gpio_is_valid(gpio_num))
  126.         {
  127.                 printk(KERN_INFO "invalid gpio_num:%d.\n", gpio_num);
  128.                 return -1;
  129.         }
  130.         else
  131.         {
  132.                 gpio_request(gpio_num,"sysfs");
  133.                 gpio_direction_output(gpio_num,false);
  134.                 gpio_export(gpio_num,false);
  135.         }

  136.         devp->mada_gpio = gpio_num;
  137.         devp->mada_high = 500;
  138.         //devp->mada_voltage = MADA_VOLTAGE(devp);
  139.         devp->mada_hrt_state = false;
  140.         devp->mada_gpio_value = false;
  141.         devp->devnum = MKDEV(mada_major, min);
  142.         sprintf(devp->mada_name, "mada%d", min);
  143.         cdev_init(&devp->cdev,&mada_fops);
  144.         ret = cdev_add(&devp->cdev,MKDEV(mada_major, min),1);
  145.         if(ret)
  146.         {
  147.                 printk(KERN_INFO "add mada%d fail. error is %d", min, ret);
  148.                 memset(devp, 0, sizeof(struct mada_dev));
  149.                 gpio_free(gpio_num);
  150.                 gpio_unexport(gpio_num);
  151.                 return ret;
  152.         }
  153.         else
  154.                 devp->device = device_create(mada_class,NULL,MKDEV(mada_major, min),NULL,devp->mada_name);
  155.        
  156.         return 0;
  157. }

  158. void mada_del(struct mada_dev *devp)
  159. {
  160.         hrtimer_cancel(&devp->mada_hrt);
  161.         gpio_unexport(devp->mada_gpio);
  162.         gpio_free(devp->mada_gpio);
  163.         device_destroy(mada_class,devp->devnum);
  164.         unregister_chrdev_region(devp->devnum, 1);
  165.         memset(devp, 0, sizeof(struct mada_dev));
  166.         kfree(devp);
  167. }

  168. int __init mada_init(void)
  169. {
  170.         int ret = 0, i;
  171.         printk(KERN_INFO "mada_init begin.\n");
  172.         mada_devp = kzalloc(MADA_NUM * sizeof(struct mada_dev), GFP_KERNEL);
  173.         if(IS_ERR(mada_devp))
  174.         {
  175.                 ret = PTR_ERR(mada_devp);
  176.                 printk(KERN_INFO "vmalloc_fail and err is %d.\n", ret);
  177.                 goto fail;
  178.         }

  179.         if(mada_major == 0)
  180.         {
  181.                 ret = alloc_chrdev_region(&mada_devnum,0,MADA_NUM,MADA_NAME);
  182.                 mada_major = MAJOR(mada_devnum);
  183.         }
  184.         else
  185.         {
  186.                 mada_devnum = MKDEV(mada_major, 0);
  187.                 ret = register_chrdev_region(mada_devnum,MADA_NUM,MADA_NAME);
  188.         }
  189.         if(ret < 0)
  190.         {
  191.                 printk(KERN_INFO "register_fail and err is %d.\n", ret);
  192.                 goto fail;
  193.         }
  194.        
  195.         mada_class = class_create(THIS_MODULE, MADA_NAME);
  196.         for(i=0; i<MADA_NUM; i++)
  197.         {
  198.                 mada_setup(mada_devp+i, i, mada_gpio[i]);
  199.         }       
  200.        
  201.         printk(KERN_INFO "mada_init!\n");
  202.         return 0;

  203. fail:
  204.         return ret;
  205. }

  206. void __exit mada_exit(void)
  207. {
  208.         int i;
  209.         for(i=0; i<MADA_NUM; i++)
  210.                 mada_del(mada_devp+i);
  211.         class_destroy(mada_class);
  212.         printk("mada_exit!\n");
  213. }
  214. module_init(mada_init);
  215. module_exit(mada_exit);

复制代码

主要部分是4路高精度时钟


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top