找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机+L9190+LM393电机调速及测速源程序

[复制链接]
跳转到指定楼层
楼主
电机调速及测速程序电路图
P1排针

VCC接A或者接B,可以实现正传和反转。
OUT脉冲输出端,用于单片机测速。

电路原理图如下:


单片机源程序如下:
  1. /*--------------------------------------------------*/
  2. /*STC12C5A60S2 1T 系列单片机------------------------*/
  3. /*SYSCLK:22.1184M----------------------------------*/
  4. /*--------------------------------------------------*/
  5. #include <reg52.h>
  6. #include <stdio.h>
  7. #include <intrins.h>
  8. #include"pwm.h"
  9. #include"motor_ctr.h"
  10. #include"lcd1602.h"
  11. #include"timer.h"
  12. sbit IR=P3^3;  //红外接口标志

  13. /*------------------------------------------------
  14.                 全局变量声明
  15. ------------------------------------------------*/

  16. unsigned char  irtime;//红外用全局变量

  17. bit irpro_ok,irok;
  18. int cs = 0;
  19. unsigned char IRcord[4];
  20. unsigned char irdata[33];
  21. unsigned int FinalData = 0;
  22. unsigned int TempRecData[5]={0};
  23. unsigned char TempData[16];
  24. int i=0;
  25. int ddata=5000;
  26. int xdata e=0,e1=0,e2=0;
  27. float xdata uk=0,uk1=0,duk=0;
  28. float xdata kp=4,ki=1.2,kd=0.8;
  29. int xdata out;
  30. /*------------------------------------------------
  31.                   函数声明
  32. ------------------------------------------------*/
  33. void Ircordpro(void);

  34. /*------------------------------------------------
  35.                   定时器0中断处理
  36. ------------------------------------------------*/

  37. void tim1_isr () interrupt 3
  38. {
  39.   irtime++;  //用于计数2个下降沿之间的时间
  40. }

  41. /*------------------------------------------------
  42.                   外部中断0中断处理
  43. ------------------------------------------------*/
  44. void EX1_ISR (void) interrupt 2 //外部中断1服务函数
  45. {
  46.   static unsigned char  i;             //接收红外信号处理
  47.   static bit startflag;                //是否开始处理标志位

  48. if(startflag)                        
  49.    {
  50.     if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
  51.                         i=0;
  52.             irdata[i]=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
  53.             irtime=0;
  54.             i++;
  55.              if(i==33)
  56.                 {
  57.                  irok=1;
  58.                  i=0;
  59.                 }
  60.           }
  61.      else
  62.         {
  63.         irtime=0;
  64.         startflag=1;
  65.         }

  66. }

  67. /*------------------------------------------------
  68.                 定时器0初始化
  69. ------------------------------------------------*/
  70. void TIM1init(void)//定时器0初始化
  71. {

  72.   TMOD=0x22;//定时器0工作方式2,TH0是重装值,TL0是初值
  73.   TH1=0x00; //重载值
  74.   TL1=0x00; //初始化值
  75.   ET1=1;    //开中断
  76.   TR1=1;   
  77. }
  78. /*------------------------------------------------
  79.                   外部中断0初始化
  80. ------------------------------------------------*/
  81. void EX1init(void)
  82. {
  83. IT1 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
  84. EX1 = 1;   //使能外部中断
  85. EA = 1;    //开总中断
  86. }
  87. /*------------------------------------------------
  88.                   键值处理
  89. ------------------------------------------------*/

  90. void Ir_work(void)
  91. {     
  92.   int Findata=0;
  93.         int flag=0;
  94.         if(IRcord[2]==0x16)
  95.         {
  96.                 Findata=0;
  97.         }
  98.         if(IRcord[2]==0x0c)
  99.         {
  100.                 Findata=1;
  101.         }
  102.         if(IRcord[2]==0x18)
  103.         {
  104.                 Findata=2;
  105.         }
  106.         if(IRcord[2]==0x5e)
  107.         {
  108.                 Findata=3;
  109.         }
  110.                 if(IRcord[2]==0x08)
  111.         {
  112.                 Findata=4;
  113.         }
  114.                 if(IRcord[2]==0x1c)
  115.         {
  116.                 Findata=5;
  117.         }
  118.                 if(IRcord[2]==0x5a)
  119.         {
  120.                 Findata=6;
  121.         }
  122.                 if(IRcord[2]==0x42)
  123.         {
  124.                 Findata=7;
  125.         }
  126.                 if(IRcord[2]==0x52)
  127.         {
  128.                 Findata=8;
  129.         }
  130.                 if(IRcord[2]==0x4a)
  131.         {
  132.                 Findata=9;
  133.         }
  134.                 if(IRcord[2]==0x09)//确认信号
  135.         {
  136.                 Findata=66;
  137.                 flag=1;
  138.         }
  139.                 if(IRcord[2]==0x43)//暂停信号
  140.         {
  141.                 Findata=55;
  142.                 flag=3;
  143.         }       
  144.         if(flag==0)
  145.         {
  146.           TempRecData[i] = Findata;
  147.                 i++;
  148.         }       
  149.         if(flag==3)
  150.         {
  151.                 flag=0;
  152.                 cs++;
  153.                 if(cs==1)
  154.           {       
  155.                         START_F = 0;
  156.                         MOTOR_STOP;                 //快速制动
  157.                 }
  158.                 if(cs==2)
  159.                 {
  160.                         cs=0;
  161.                         PWM_EN;                  // 启动
  162.                         START_F = 1;
  163.                 }
  164.         }       
  165.         irpro_ok=0;//处理完成标志       
  166.         if(flag==1)
  167.         {       
  168.                 flag=0;
  169.                 if(i==5&&TempRecData[0]>2)
  170.                 {
  171.                         TempRecData[0]=1;
  172.                         TempRecData[1]=0;
  173.                         TempRecData[2]=0;
  174.                         TempRecData[3]=0;
  175.                         TempRecData[4]=0;
  176.                 }
  177.                 switch(i)
  178.                 {
  179.                         case 0:FinalData = 6000;break;
  180.                         case 1:FinalData = TempRecData[0];break;
  181.                         case 2:FinalData =TempRecData[0]*10+TempRecData[1];break;
  182.                         case 3:FinalData =TempRecData[0]*100+TempRecData[1]*10+TempRecData[2];break;
  183.                         case 4:FinalData =TempRecData[0]*1000+TempRecData[1]*100+TempRecData[2]*10+TempRecData[3];break;
  184.                         case 5:FinalData =TempRecData[0]*10000+TempRecData[1]*1000+TempRecData[2]*100+TempRecData[3]*10+TempRecData[4];break;
  185.                         default:break;
  186.                 }
  187.                 ddata= FinalData;
  188.                 i=0;
  189.                 TempRecData[0]=0;
  190.                 TempRecData[1]=0;
  191.                 TempRecData[2]=0;
  192.                 TempRecData[3]=0;
  193.                 TempRecData[4]=0;
  194.         }
  195.         if(i==6)
  196.         {
  197.                 i=0;
  198.         }

  199. }
  200. /*------------------------------------------------
  201.                 红外码值处理
  202. ------------------------------------------------*/
  203. void Ircordpro(void)//红外码值处理函数
  204. {
  205.   unsigned char i, j, k;
  206.   unsigned char cord,value;

  207.   k=1;
  208.   for(i=0;i<4;i++)      //处理4个字节
  209.   {
  210.     for(j=1;j<=8;j++) //处理1个字节8位
  211.       {
  212.         cord=irdata[k];
  213.         if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
  214.           value|=0x80;
  215.          if(j<8)
  216.           {
  217.              value>>=1;
  218.           }
  219.            k++;
  220.       }
  221.      IRcord[i]=value;
  222.      value=0;     
  223.   }
  224.      irpro_ok=1;//处理完毕标志位置1
  225. }


  226. /************************************************************************/
  227. //10ms处理程序
  228. /************************************************************************/
  229. void DS10MS_CNT(void)
  230. {
  231.    if( JS10MS_F )        //10ms到
  232.    {
  233.                 JS10MS_F = 0;//标志位清零
  234.                 Key();                 //按键扫描
  235.    }
  236. }

  237. /************************************************************************/
  238. //10ms处理程序
  239. /************************************************************************/
  240. void DS50MS_CNT(void)
  241. {
  242.    if( JS50MS_F )        //10ms到
  243.    {
  244.                 JS50MS_F = 0;   //标志位清零
  245.                         pca_pro();            //转速处理
  246.                 PID_Adjust();              //PID调节
  247.    }
  248. }
  249. /************************************************************************/
  250. //100ms处理程序
  251. /************************************************************************/
  252. void DS100MS_CNT(void)
  253. {
  254.         if(JS100MS_F)//200ms到
  255.         {
  256.          JS100MS_F = 0;
  257.          Key_symbol_process();         //按键处理
  258.         }
  259. }


  260. /****************************************************/
  261. //1000ms处理程序
  262. /***************************************************/
  263. void DS1MIN_CNT(void)
  264. {
  265.         if(JS1MIN_F) //1000ms到
  266.         {
  267.          JS1MIN_F = 0;  //标志位清零
  268.          //Data_Display(); //更新数据显示
  269.         }
  270. }

  271. ////////////////////////主函数///////////////////////
  272. void main()
  273. {   
  274.        
  275.         PWM_Init();      //PWM初始化
  276.   Motor_Ctr_Int(); //控制初始化
  277.         lcd_init();             //160液晶初始化
  278.         Timer0_Init();
  279.         EX1init();            //初始化外部中断
  280.   TIM1init();           //初始化定时器
  281.         EA = 1;//开总中断
  282.   DIR=!DIR;
  283.         PWM_EN;                  // 启动
  284.         START_F = 1;         
  285.         while (1)
  286.         {       
  287.    
  288.                 DS10MS_CNT();
  289.                 DS50MS_CNT();
  290.                 DS100MS_CNT();
  291.                 DS1MIN_CNT();
  292.          if(irok)                        //如果接收好了进行红外处理
  293.      {   
  294.        Ircordpro();
  295.        irok=0;
  296.       }
  297.     if(irpro_ok)                   //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
  298.       {
  299.                                  Ir_work();
  300.                         }
  301.           e = ddata - rpm;
  302.           duk = (kp*(e-e1)+ki*e+kd*(e-2*e1+e2))/100;
  303.           uk = uk1+duk;
  304.           out = (int)uk;
  305.           if(out>250)
  306.           {
  307.            out = 250;
  308.           }
  309.           if(out<1)
  310.           {
  311.                    out = 0;
  312.           }
  313.                
  314.           uk1 = uk;
  315.                 e2=e1;
  316.           e1=e;
  317.           PWM0_TEMP = out;
  318.         }
  319. }
复制代码


所有资料51hei提供下载:
电机.rar (7.1 MB, 下载次数: 32)



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:419294 发表于 2018-11-7 15:51 | 只看该作者
没看懂
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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