找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5371|回复: 4
打印 上一主题 下一主题
收起左侧

带PID控制的电机控制系统源程序 节气门(闭环)电机PWM调节

[复制链接]
跳转到指定楼层
楼主
节气门(闭环)电机PWM调节,可以采集电压来调节电机转速,PID控制

  1. #include <STC12C5A60S2.H>
  2. #include <intrins.H>

  3. #define AD_SPEEDHH 0x60 // 0110,0000  90个时钟周期转换一次
  4. #define AD_SPEEDH 0x50  // 0100,0000  180个时钟周期转换一次
  5. #define AD_SPEEDL 0x20  // 0010,0000  360个时钟周期转换一次
  6. #define AD_SPEEDLL 0x00 // 0000,0000  540个时钟周期转换一次
  7. #define AD_POWER 0x80 //1000,0000   AD电源
  8. #define AD_FLAG  0x10 //0001,0000   AD标志位
  9. #define AD_START 0x08 //0000,1000   启动AD转换
  10. #define AD_CHANNEl 0x07 //0000,0111 AD转换通道选择

  11. #define uint unsigned int
  12. #define uchar unsigned char

  13. sbit PWM=P2^0;
  14. bit f1,f2;
  15. char ZKB;
  16. uint tb_ad,jqm1_ad,jqm2_ad;

  17. /*******************************************************
  18.                   延时程序
  19. *******************************************************/
  20. delay(uint ms)
  21. {
  22.         while(ms--);
  23.         return 0;
  24. }
  25. /*******************************************************
  26.                   中断程序
  27. *******************************************************/
  28. void timer0_init()                    //中断初始化
  29. {
  30.         TH0=0xff;                                                //11.0592M晶振,定时1/60000s
  31.         TL0=0x46;                                                //波形频率1200Hz
  32.         TMOD=0x01;
  33.         EA=1;
  34.         ET0=1;
  35.         TR0=1;
  36. }
  37. timer0() interrupt 1           //定时0.02ms
  38. {
  39.         uchar a;
  40.         TH0=0xff;                                                //11.0592M晶振,定时1/60000s
  41.         TL0=0x80;
  42.         //TL0=0x46;                                                //波形频率1200Hz
  43.         a+=1;
  44.         if(a>=50) a=0;
  45.         if(a<ZKB) PWM=1;
  46.         else PWM=0;       
  47. }
  48. /*******************************************************
  49.                   AD转换程序
  50. *******************************************************/
  51. void ad_init()                                           //AD转换初始化函数
  52. {
  53.         ADC_RES = 0;                                   //转换结果寄存器清空
  54.     ADC_RESL = 0;
  55.         P1ASF=0xff;                                           //P1口作为模拟功能使用
  56. }

  57. uint get_AD_res(uchar ch)                   //AD转换函数
  58. {
  59.         ch &= AD_CHANNEl;                           //选择转换通道               
  60.         ADC_CONTR = AD_POWER|AD_SPEEDHH|ch|AD_START;        //1110,1***启动A/D电源、选择转换速度、选择通道、启动转换
  61.         _nop_();                                           //必要的延时,至少四个空指令
  62.         _nop_();
  63.         _nop_();
  64.         _nop_();
  65.         while(!(ADC_CONTR&AD_FLAG));    //0001,0000等待转换完成
  66.         ADC_CONTR &= 0xe7;              //1110,0111  AD标志位清0,关闭AD转换
  67.         return ADC_RES;               //返回 A/D 高 8 位转换结果
  68. }
  69. /*******************************************************
  70.                   PID程序
  71. *******************************************************/
  72. PID(uint jqm_ad)
  73. {
  74.         if(tb_ad<55)
  75.                 tb_ad=55;
  76.         if((tb_ad-10)<jqm_ad<(tb_ad+10))
  77.                 ZKB=tb_ad/4.2;
  78.         if(jqm_ad<(tb_ad-10))
  79.                 ZKB=(tb_ad+3*tb_ad-3*jqm_ad)/4.2;                               
  80.         if(jqm_ad>(tb_ad+10))
  81.                 ZKB=(tb_ad+3*tb_ad-3*jqm_ad)/4.2;
  82.                 if(ZKB<=0)
  83.                         ZKB=0;
  84.                 if(ZKB>=50)
  85.                         ZKB=50;
  86.         return 0;
  87. }
  88. /*******************************************************
  89.                主函数
  90. *******************************************************/
  91. main()
  92. {
  93.         P2M1=0X00;
  94.         P2M0=0X01;
  95.         ad_init();
  96.         timer0_init();
  97.         P1=0;
  98.         ZKB=0;
  99.         delay(1000);
  100.         while(1)
  101.         {                       
  102.                 jqm1_ad=get_AD_res(2);
  103.                 delay(30);
  104.                 jqm2_ad=get_AD_res(0);
  105.                 delay(30);
  106.                 if((10<jqm1_ad<240)||(10<jqm2_ad<240))
  107.                         f1=1;
  108.                 else f1=0;
  109.                 while(f1)
  110.                 {
  111.                         jqm1_ad=get_AD_res(2);
  112.                         delay(30);
  113.                         jqm2_ad=get_AD_res(0);
  114.                         delay(30);
  115.                         jqm2_ad=250-jqm2_ad;
  116.                         tb_ad=get_AD_res(6);
  117.                         delay(30);                       
  118.                         if((20<jqm1_ad)&&(jqm1_ad<240))                       
  119.                         {
  120.                                 f1=1;
  121.                                 PID(jqm1_ad);
  122.                         }                       


  123. …………余下代码请下载附件…………
复制代码



完整源码下载:
pid采集电压电机控制.zip (47.17 KB, 下载次数: 90)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1 发表于 2017-3-21 17:05 | 只看该作者
好资料,51黑有你更精彩
回复

使用道具 举报

板凳
ID:213928 发表于 2017-7-10 13:32 | 只看该作者
谢谢分享
回复

使用道具 举报

地板
ID:257741 发表于 2017-12-9 21:59 | 只看该作者
谢谢!正需要呢!
回复

使用道具 举报

5#
ID:739537 发表于 2020-4-27 18:37 | 只看该作者
大佬,真给力
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表