找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 1269|回復(fù): 1
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)自行車碼表+PWM調(diào)速程序問題

[復(fù)制鏈接]
回帖獎(jiǎng)勵(lì) 50 黑幣 回復(fù)本帖可獲得 1 黑幣獎(jiǎng)勵(lì)! 每人限 1 次
跳轉(zhuǎn)到指定樓層
樓主
ID:271875 發(fā)表于 2019-5-19 13:10 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
自行車速度里程測(cè)量,使用的是外部中斷0計(jì)數(shù)里程脈沖,定時(shí)器0計(jì)算時(shí)間
PWM調(diào)速,使用定時(shí)器1產(chǎn)生PWM波形
兩個(gè)程序單獨(dú)使用都沒問題,
但是合在一起,兩個(gè)定時(shí)器一起用就出現(xiàn)問題,錯(cuò)誤首先在數(shù)碼管位選端出現(xiàn)流水燈效果,第一次切割后恢復(fù)正常,沒有了流水燈效果,速度測(cè)量失效。里程測(cè)量還能用


附程序代碼:
  1. //速度:?jiǎn)挝粸?m/h         里程單位cm
  2. #include<reg51.h>
  3. #define duan P0                         //段選
  4. #define wei P2                   //位選P2^4-P2^7
  5. #define zhouchang 200            //車輪周長(zhǎng)200cm
  6. typedef unsigned char uchar;
  7. typedef unsigned int uint;
  8. typedef unsigned long ulong;
  9. uchar code display1[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數(shù)碼管驅(qū)動(dòng)信號(hào)0---9,共陽(yáng)
  10. uchar code bitcode[]={0x7f,0xbf,0xdf,0xef};                                  //數(shù)碼管位選掃描信號(hào)  0111 1111
  11. sbit change = P3^4;                    //切換按鍵
  12. bit flag = 1;                       //切換標(biāo)記
  13. bit flag1=0;                    //第一次切割
  14. uchar point1 = 0;               //小數(shù)點(diǎn)標(biāo)記,速度
  15. uchar buf1[]={0,0,0,0};                                        //數(shù)碼管該顯示的數(shù)字,高-----低,速度
  16. uchar point2 = 0;               //小數(shù)點(diǎn)標(biāo)記,里程
  17. uchar buf2[]={0,0,0,0};                                        //數(shù)碼管該顯示的數(shù)字,高------低,里程
  18. uchar num = 4;                  //數(shù)碼管第num位
  19. uint time_counter = 0;                                        //每10次切割時(shí)差,定時(shí)計(jì)數(shù)
  20. uint time_counter8 = 0;                                        //8s定時(shí)計(jì)數(shù)
  21. uint external_counter = 0;                        //外部中斷計(jì)數(shù)
  22. ulong s = 0;//里程
  23. ulong speed = 0;//速度

  24. sbit PWM=P1^0;              //PWM所使用的一些量
  25. sbit key1=P1^1;
  26. sbit key2=P1^2;
  27. uchar zkb,w;// zkb指占空比

  28. void delay1m(uchar x)//MS級(jí)延時(shí)函數(shù)
  29. {
  30.         uchar i,j;
  31.         for(i = 0;i < x;i++)        //連續(xù)x次,約 x ms
  32.                 for(j=0;j<120;j++);   //數(shù)120 次,約1 ms
  33. }
  34. void keyscan()         //鍵盤掃描
  35.   {
  36.            P1=0XFF;
  37.       while(1)
  38.           {
  39.         if(key1==0)
  40.          {
  41.           delay1m(5);
  42.            if(key1==0)
  43.            {

  44.                 if(zkb<10)
  45.                  {
  46.                    zkb++;
  47.                  zkb++;
  48.                  }
  49.               while(!key1);

  50.            }
  51.          }
  52.         if(key2==0)
  53.          {
  54.           delay1m(5);
  55.            if(key2==0)
  56.            {

  57.             if(zkb>0)  
  58.                  {
  59.                    zkb--;

  60.                  }
  61.            while(!key2);
  62.            }
  63.          }   

  64.   }
  65. }

  66. void init_display()              //初始顯示0.0.0.0
  67. {
  68.         uchar i;
  69.         for(i = 0;i < 4;i++)         
  70.         {
  71.                 wei = bitcode[num - 1];
  72.                 duan = display1[buf1[num--]];
  73.                 delay1m(1);
  74.                 if(num == 0)num = 4;
  75.         }
  76. }
  77. void time0_int0_init()         //定時(shí)器0和外部中斷0的初始化函數(shù)
  78. {
  79.         TMOD |= 0x11;
  80.         TH1=(65536-10)/256;
  81.         TL1=(65536-10)%256;
  82.         TL0 = (65536 - 5000) % 256;//12M晶振,5ms定時(shí)
  83.         TH0 = (65536 - 5000) / 256;
  84.         IT0 = 1;//外部中斷0,負(fù)跳變觸發(fā)方式
  85.         TR0 = 0;
  86.         ET0 = 1;
  87.         EX0 = 1;
  88.         EA = 1;
  89.         ET1=1;
  90.         TR1=1;

  91. }

  92. void display_function()                //顯示函數(shù)
  93. {
  94.         if(flag == 0)//顯示速度
  95.         {
  96.                 switch(point1)
  97.                 {
  98.                         case 0:wei = bitcode[num-1];
  99.                                  duan = display1[buf1[num-1]];
  100.                                  num--;
  101.                         break;//速度顯示 0

  102.                         case 1:if(num == 1)
  103.                                         { wei = bitcode[num-1];
  104.                                           duan = 0x7f&display1[buf1[num-1]];
  105.                                           num--;
  106.                                         }
  107.                                  else
  108.                                         {
  109.                                                 wei = bitcode[num-1];
  110.                                                 duan = display1[buf1[num-1]];
  111.                                                 num--;
  112.                                         }
  113.                         break;//最高位小數(shù)點(diǎn)亮

  114.                         case 2:if(num == 2)
  115.                                         {
  116.                                                 wei = bitcode[num-1];
  117.                                                 duan = 0x7f&display1[buf1[num-1]];
  118.                                                 num--;
  119.                                         }
  120.                                  else
  121.                                         {
  122.                                                 wei = bitcode[num-1];
  123.                                                 duan = display1[buf1[num-1]];
  124.                                                 num--;
  125.                                         }
  126.                         break;//第二高位小數(shù)點(diǎn)亮

  127.                         case 3:if(num == 3)
  128.                                         {
  129.                                                 wei = bitcode[num-1];
  130.                                                 duan = 0x7f&display1[buf1[num-1]];
  131.                                                 num--;
  132.                                         }
  133.                                    else
  134.                                         {
  135.                                                 wei = bitcode[num-1];
  136.                                                 duan = display1[buf1[num-1]];
  137.                                                 num--;
  138.                                         }
  139.                         break;//第三高位小數(shù)點(diǎn)亮

  140.                         default:break;        

  141.                 }
  142.                 if(num == 0)num = 4;
  143.          }
  144.         else if(flag == 1)//顯示里程
  145.    {
  146.                 switch(point2)
  147.                 {
  148.                         case 0:wei = bitcode[num-1];
  149.                                  duan = display1[buf2[num-1]];
  150.                                  num--;
  151.                         break;//里程顯示 0

  152.                         case 1:if(num == 1)
  153.                                         {
  154.                                                 wei = bitcode[num-1];
  155.                                                 duan = 0x7f&display1[buf2[num-1]];
  156.                                                 num--;
  157.                                         }
  158.                                  else
  159.                                         {
  160.                                                 wei = bitcode[num-1];
  161.                                                 duan = display1[buf2[num-1]];
  162.                                                 num--;
  163.                                         }
  164.                         break;//最高位小數(shù)點(diǎn)亮

  165.                         case 2:if(num == 2)
  166.                                         {
  167.                                                 wei = bitcode[num-1];
  168.                                                 duan = 0x7f&display1[buf2[num-1]];
  169.                                                 num--;
  170.                                         }
  171.                                    else
  172.                                         {        
  173.                                                 wei = bitcode[num-1];
  174.                                                 duan = display1[buf2[num-1]];
  175.                                                 num--;
  176.                                         }
  177.                         break;//第二高位小數(shù)點(diǎn)亮

  178.                         case 3:if(num == 3)
  179.                                         {
  180.                                                 wei = bitcode[num-1];
  181.                                                 duan = 0x7f&display1[buf2[num-1]];
  182.                                                 num--;
  183.                                         }
  184.                                    else
  185.                                         {
  186.                                                 wei = bitcode[num-1];
  187.                                                 duan = display1[buf2[num-1]];
  188.                                                 num--;
  189.                                         }
  190.                         break;//第三高位小數(shù)點(diǎn)亮

  191.                         default:break;        

  192.                 }
  193.                 if(num == 0)num = 4;
  194.    }
  195. }
  196. //====================================主函數(shù)=========================================================
  197. void main()
  198. {

  199.         time0_int0_init();//定時(shí)器0和外部中斷0的初始化
  200.         while(!TR0)        //上電一直未切割時(shí)就顯示  0.0.0.0
  201.         {
  202.                 init_display();
  203.         }
  204.         zkb=4;

  205.         while(1)
  206.         {

  207.                 keyscan();
  208.                 if(!change)//按下切換按鍵顯示里程
  209.                 {
  210.                         delay1m(5);
  211.                         if(!change)
  212.                         {
  213.                                 flag = ~flag;
  214.                         }
  215.                         while(!change);               
  216.                 }

  217.         }
  218. }

  219. //==================================定時(shí)器0中斷函數(shù)================================
  220. void time0_interrupt() interrupt 1
  221. {
  222.         TL0 = (65536 - 5000) % 256;// 12M晶振,5ms定時(shí)
  223.         TH0 = (65536 - 5000) / 256;
  224.         display_function();
  225.         time_counter++;
  226.         time_counter8++;
  227.         if(time_counter8 >= 1600)//大于8s沒切割,車子視為停下了,速度為:0,但里程還記著
  228.         {
  229.                 time_counter8 = 0;
  230.                 speed = 0;//速度為 0
  231.                 point1 = 0;
  232.                 buf1[3] = speed%10;                //顯示數(shù)組賦值
  233.                 buf1[2] = speed/10%10;
  234.                 buf1[1] = speed/100%10;
  235.                 buf1[0] = speed/1000%10;
  236.         }
  237. }

  238. void time1() interrupt 3         //定時(shí)器1中斷函數(shù)
  239.   {

  240.       TH1=(65536-10)/256;
  241.         TL1=(65536-10)%256;
  242.         ++w;
  243.         if(w>10)
  244.           {
  245.           w=0;
  246.           };

  247.         if(w<=zkb)
  248.         {
  249.          PWM=1;
  250.         }
  251.         else PWM=0;


  252.   }

  253. //==================================外部中斷0中斷函數(shù)=========================
  254. void int0_interrupt()interrupt 0
  255. {        

  256.         external_counter++;
  257.         if(external_counter ==1 )TR0 = ~TR0; //第一次切割打開定時(shí)器0
  258.         if(external_counter == 65535)external_counter = 0;
  259.         time_counter8 = 0;                //只要8秒內(nèi)有切割,車子就一直在運(yùn)行

  260.         if(external_counter % 10 == 0)//切割10次 更新下速度
  261.         {                                                                                     //*5是因?yàn)橹袛嘁淮问?MS
  262.                  if(flag1==0)                 //第一次切割更新速度
  263.                                 {
  264.                                         speed =((ulong)(36000)*zhouchang)/(time_counter * 5);
  265.                                         flag1=1;
  266.                                 }
  267.                 else if(flag1==1){speed =((ulong)(36000)*10*zhouchang)/(time_counter * 5);} //不是第一次切割

  268.                 if((speed >= 100)&&(speed < 1000))         //100 ---- 1000       3位整數(shù)
  269.                 {
  270.                         point1 = 1;
  271.                         buf1[3] = speed%10;
  272.                         buf1[2] = speed/10%10;
  273.                         buf1[1] = speed/100%10;
  274.                         buf1[0] = 0;
  275.                 }
  276.                 else if((speed >= 1000)&&(speed < 10000))   //1000 ---- 10000        4位整數(shù)
  277.                 {
  278.                         point1 = 1;
  279.                         speed = (uint)speed;
  280.                         buf1[3] = speed%10;
  281.                         buf1[2] = speed/10%10;
  282.                         buf1[1] = speed/100%10;
  283.                         buf1[0] = speed/1000%10;
  284.                 }
  285.                 else if((speed >= 10000)&&(speed < 100000))          //10000 ----- 100000      5位整數(shù)
  286.                 {
  287.                         point1 = 2;
  288.                         buf1[3] = speed/10%10;
  289.                         buf1[2] = speed/100%10;
  290.                         buf1[1] = speed/1000%10;
  291.                         buf1[0] = speed/10000%10;
  292.                 }
  293.                 else if((speed >= 100000)&&(speed < 1000000))  //100000 ------ 1000000    6位整數(shù)
  294.                 {
  295.                         point1 = 3;
  296.                         buf1[3] = speed/100%10;
  297.                         buf1[2] = speed/1000%10;
  298.                         buf1[1] = speed/10000%10;
  299.                         buf1[0] = speed/100000%10;
  300.                 }
  301.                 time_counter = 0;
  302.         }

  303.         if(external_counter % 10 == 0)//每切割10次 更新下里程
  304.         {
  305.                  s = (ulong)external_counter * zhouchang;  //里程:?jiǎn)挝粸?nbsp;  cm
  306.                 if((s >= 1000)&&(s < 10000))
  307.                 {
  308.                         point2 = 1;                                                                                                   //  0.012    001212
  309.                         buf2[3] = s/100%10;
  310.                         buf2[2] = s/1000%10;
  311.                         buf2[1] = 0;
  312.                         buf2[0] = 0;
  313.                 }//   4位整數(shù)
  314.                 else if((s >= 10000)&&(s < 100000))
  315.                 {
  316.                         point2 = 1;
  317.                         buf2[3] = s/100%10;
  318.                         buf2[2] = s/1000%10;
  319.                         buf2[1] = s/10000%10;
  320.                         buf2[0] = 0;
  321.                 }//     5位整數(shù)           0.123         012345
  322.                 else if((s >= 100000)&&(s < 1000000))
  323.                 {
  324.                         point2 = 1;
  325.                         buf2[3] = s/100%10;
  326.                         buf2[2] = s/1000%10;
  327.                         buf2[1] = s/10000%10;
  328.                         buf2[0] = s/100000%10;
  329.                 } //    6位整數(shù)         1.234    1234 56
  330.             else if((s >= 1000000)&&(s < 10000000))
  331.                 {
  332.                         point2 = 2;
  333.                         buf2[3] = s/1000%10;
  334.                         buf2[2] = s/10000%10;
  335.                         buf2[1] = s/100000%10;
  336.                         buf2[0] = s/1000000%10;
  337.                 }//     7位整數(shù)          1234 567
  338.                 else if((s >= 10000000)&&(s < 100000000))
  339.                 {
  340.                         point2 = 3;
  341.                         buf2[3] = s/10000%10;
  342.                         buf2[2] = s/100000%10;
  343.                         buf2[1] = s/1000000%10;
  344.                         buf2[0] = s/10000000%10;
  345.                 } //     8位整數(shù)                 1234 5678
  346.         }
  347. }
復(fù)制代碼


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:123289 發(fā)表于 2019-5-20 08:48 | 只看該作者
1、延時(shí)不要用DELAY硬件延時(shí)程序做!
2、中斷服務(wù)程序中:不要做顯示、復(fù)雜的計(jì)算!
你能做到以上兩點(diǎn)就可以了。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表