標(biāo)題: 通過(guò)單片機(jī)pcf8591電位器控制直流電機(jī)正反轉(zhuǎn) 源程序Proteus仿真 [打印本頁(yè)]

作者: 電視機(jī)惹的禍    時(shí)間: 2020-11-23 09:22
標(biāo)題: 通過(guò)單片機(jī)pcf8591電位器控制直流電機(jī)正反轉(zhuǎn) 源程序Proteus仿真
proteus和程序一起打包,送給有需要的小伙伴

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)



單片機(jī)源程序如下:
  1. #include<reg51.h>
  2. #include<intrins.h>

  3. typedef unsigned char uint8;
  4. typedef unsigned int uint16;
  5. typedef unsigned long uint32;
  6. sbit PWM01=P1^4;                                       
  7. sbit PWM02=P1^5;                                                  //電機(jī)1
  8. sbit PWM11=P1^6;                                       
  9. sbit PWM12=P1^7;                                                   //電機(jī)2
  10. sbit PWM21=P2^2;                                       
  11. sbit PWM22=P2^3;                                                        //電機(jī)3
  12. sbit PWM31=P3^6;                                       
  13. sbit PWM32=P3^7;                                                   //電機(jī)4
  14. sbit ADDRC = P1^0;
  15. sbit ADDRB = P1^1;
  16. sbit ADDRA = P1^2;//控制138譯碼器的三個(gè)引腳
  17. uint8 AD_value0 = 0;//AD值
  18. uint8 AD_value1 = 0;//AD值
  19. uint8 AD_value2 = 0;//AD值
  20. uint8 AD_value3 = 0;//AD值
  21. uint8 Top = 255;
  22. uint8 Low = 0;
  23. uint8 between0 = 127;
  24. uint8 between1 = 128;
  25. sbit I2C_SDA = P2^1;
  26. sbit I2C_SCL = P2^0;//I2C通信的兩個(gè)引腳

  27. bit flag_300ms = 0;//300ms時(shí)間標(biāo)志位
  28. uint8 T0RH = 0;//定時(shí)器高8位初值
  29. uint8 T0RL = 0;//定時(shí)器低8位初值
  30. //uint8 AD_value = 0;//AD值
  31. uint8 code led_char[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  32.                                                  0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//LED段碼

  33. void config_timer0(uint8 ms);
  34. uint8 get_ADC_vaule(uint8 chn);
  35. void motor_deal0();
  36. void motor_deal1();
  37. void motor_deal2();
  38. void motor_deal3();
  39. void main()
  40. {
  41.         config_timer0(1);//初始化通用定時(shí)器0,定時(shí)1ms
  42.         while(1)
  43.         {
  44.                 if(flag_300ms == 1)        //判斷300ms時(shí)間是否到了
  45.                 {
  46.                         flag_300ms = 0;//清除標(biāo)志位
  47.                         AD_value0 = get_ADC_vaule(0);//讀取通道0的AD值
  48.                         AD_value1 = get_ADC_vaule(1);//讀取通道0的AD值
  49.                         AD_value2 = get_ADC_vaule(2);//讀取通道0的AD值
  50.                         AD_value3 = get_ADC_vaule(3);//讀取通道0的AD值
  51.                           
  52.                 }               
  53.                 motor_deal0();       
  54.                 motor_deal1();
  55.                 motor_deal2();
  56.                 motor_deal3();
  57.         }
  58. }
  59. void motor_deal0()
  60. {
  61.         if(AD_value0 == between0 || AD_value0 == between1)                   //stop
  62.                 {  
  63.                                 PWM01=1;
  64.                                 PWM02=1;   
  65.                 }
  66.                 else if(AD_value0>=Low && AD_value0<between0)                   //正
  67.                 {
  68.                                 PWM01=0;
  69.                                 PWM02=1;
  70.                 }
  71.                 else                                         //反
  72.                 {
  73.                         PWM01=1;
  74.                          PWM02=0;
  75.                 }       
  76. }
  77. void motor_deal1()
  78. {
  79.         if(AD_value1 == between0 || AD_value1 == between1)                   //stop
  80.         {  
  81.                         PWM11=1;
  82.                         PWM12=1;
  83.         }
  84.         else if(AD_value1>=Low && AD_value1<between0)                   //正
  85.         {
  86.                         PWM11=0;
  87.                         PWM12=1;
  88.         }
  89.         else                                         //反
  90.         {
  91.                 PWM11=1;
  92.                  PWM12=0;
  93.         }       
  94. }
  95. void motor_deal2()
  96. {
  97.         if(AD_value2 == between0 || AD_value2 == between1)                   //stop
  98.         {  
  99.                         PWM21=1;
  100.                         PWM22=1;
  101.         }
  102.         else if(AD_value2>=Low && AD_value2<between0)                   //正
  103.         {
  104.                         PWM21=0;
  105.                         PWM22=1;
  106.         }
  107.         else                                         //反
  108.         {
  109.                 PWM21=1;
  110.                  PWM22=0;
  111.         }       
  112. }
  113. void motor_deal3()
  114. {
  115.         if(AD_value3 == between0 || AD_value3 == between1)                   //stop
  116.         {  
  117.                         PWM31=1;
  118.                         PWM32=1;
  119.         }
  120.         else if(AD_value3>=Low && AD_value3<between0)                   //正
  121.         {
  122.                         PWM31=0;
  123.                         PWM32=1;
  124.         }
  125.         else                                         //反
  126.         {
  127.                 PWM31=1;
  128.                  PWM32=0;
  129.         }       
  130. }
  131. void I2C_delay()//I2C延時(shí)函數(shù)
  132. {
  133.         _nop_();
  134.         _nop_();
  135.         _nop_();
  136.         _nop_();
  137. }

  138. void I2C_start()//I2C起始信號(hào)
  139. {
  140.         I2C_SDA = 1;
  141.         I2C_SCL = 1;
  142.         I2C_delay();
  143.         I2C_SDA = 0;
  144.         I2C_delay();
  145.         I2C_SCL = 0;
  146.         I2C_delay();
  147. }

  148. void I2C_stop()//I2C停止信號(hào)
  149. {
  150.         I2C_SDA = 0;
  151.         I2C_SCL = 0;
  152.         I2C_delay();
  153.         I2C_SCL = 1;
  154.         I2C_delay();
  155.         I2C_SDA = 1;
  156.         I2C_delay();
  157. }

  158. bit I2C_write(uint8 dat)//I2C寫(xiě)一個(gè)字節(jié)
  159. {
  160.         bit ack = 0;
  161.         uint8 mask = 0;
  162.         for(mask=0x80;mask!=0;mask>>=1)
  163.         {
  164.                 if((mask&dat) == 0)
  165.                         I2C_SDA = 0;
  166.                 else
  167.                         I2C_SDA = 1;
  168.                 I2C_delay();
  169.                 I2C_SCL = 1;
  170.                 I2C_delay();
  171.                 I2C_SCL = 0;
  172.                 I2C_delay();
  173.         }
  174.         I2C_SDA = 1;
  175.         I2C_delay();
  176.         I2C_SCL = 1;
  177.         I2C_delay();
  178.         ack = I2C_SDA;
  179.         I2C_delay();
  180.         I2C_SCL = 0;
  181.         I2C_delay();
  182.        
  183.         return (~ack);       
  184. }

  185. uint8 I2C_read_ACK()//I2C讀一個(gè)字節(jié),并發(fā)送應(yīng)答位
  186. {
  187.         uint8 dat = 0;
  188.         uint8 mask = 0;
  189.         I2C_SDA = 1;
  190.         for(mask=0x80;mask!=0;mask>>=1)
  191.         {
  192.                 if(I2C_SDA == 0)
  193.                         dat = dat & (~mask);
  194.                 else
  195.                         dat = dat | mask;
  196.                 I2C_delay();
  197.                 I2C_SCL = 1;
  198.                 I2C_delay();
  199.                 I2C_SCL = 0;
  200.                 I2C_delay();
  201.         }
  202.         I2C_SDA = 0;
  203.         I2C_delay();
  204.         I2C_SCL = 1;
  205.         I2C_delay();
  206.         I2C_SCL = 0;
  207.         I2C_delay();

  208.         return dat;
  209. }

  210. uint8 I2C_read_NACK()//I2C讀一個(gè)字節(jié),并發(fā)送非應(yīng)答位
  211. {
  212.         uint8 dat = 0;
  213.         uint8 mask = 0;
  214.         I2C_SDA = 1;
  215.         for(mask=0x80;mask!=0;mask>>=1)
  216.         {
  217.                 if(I2C_SDA == 0)
  218.                         dat = dat & (~mask);
  219.                 else
  220.                         dat = dat | mask;
  221.                 I2C_delay();
  222.                 I2C_SCL = 1;
  223.                 I2C_delay();
  224.                 I2C_SCL = 0;
  225.                 I2C_delay();
  226.         }
  227.         I2C_SDA = 1;
  228.         I2C_delay();
  229.         I2C_SCL = 1;
  230.         I2C_delay();
  231.         I2C_SCL = 0;
  232.         I2C_delay();

  233.         return dat;
  234. }

  235. uint8 get_ADC_vaule(uint8 chn)//獲取AD值
  236. {
  237.         uint8 value = 0;
  238.         I2C_start();//I2C起始信號(hào)
  239.         if(!I2C_write(0X90))//寫(xiě)入PCF8591地址及讀寫(xiě)選擇位為寫(xiě)
  240.         {
  241.                 I2C_stop();
  242.                 return 0;
  243.         }
  244. //        I2C_write(0X40 | chn);//寫(xiě)入PCF8591通道0
  245.         I2C_write(0x00 | chn);//寫(xiě)入PCF8591通道0
  246.         I2C_start();//I2C起始信號(hào)
  247.         I2C_write(0x48<<1 | 0x01);
  248.         I2C_read_ACK();//提供轉(zhuǎn)換所需的時(shí)鐘信號(hào)
  249.         value = I2C_read_NACK();//讀取上一次轉(zhuǎn)換的結(jié)果
  250.         I2C_stop();//I2C結(jié)束信號(hào)

  251.         return value;
  252. }

  253. void config_timer0(uint8 ms)//配置定時(shí)器0的通用函數(shù)
  254. {
  255.         uint32 temp =0 ;
  256.         temp = 11059200/12;
  257.         temp = (temp * ms)/1000;
  258.         temp = 65536 - (temp + 12);
  259.         T0RH = (uint8)(temp >> 8);
  260.         T0RL = (uint8)temp;

  261.         TMOD = TMOD & 0XF0;
  262.         TMOD = TMOD | 0X01;
  263.         TH0 = T0RH;
  264.         TL0 = T0RL;
  265.         EA = 1;
  266.         ET0 = 1;
  267.         TR0 = 1;
  268. }
  269. ……………………

  270. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:
電位器控制電機(jī)正反轉(zhuǎn)四通道ok.zip (130.46 KB, 下載次數(shù): 35)


作者: dj3365191    時(shí)間: 2020-11-26 13:18
用proteus仿真了一下,當(dāng)電位器調(diào)節(jié)到50%的時(shí)候電機(jī)不能立即停止,要等個(gè)十幾秒鐘,請(qǐng)問(wèn)樓主這是什么原因,希望給解答一下,謝謝




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1