久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3862|回復: 10
收起左側

單片機+電機能加減速,但是LCD1062輸出轉速無法實時顯示

[復制鏈接]
ID:749922 發表于 2020-5-17 20:54 | 顯示全部樓層 |閱讀模式
300黑幣
C51單片機產生PWM輸入L298驅動電機,控制啟停,正反轉,加減速,這些都可以實現,可以以反饋到LCD1062上。但是通過T1定時器、外中斷INT1組合測速(脈沖頻率)無法實時顯示到屏幕,就是可以顯示,但是數值不變化。也不知道為啥。
個人認為問題應該出在測速模塊或者外中斷1函數里,但是找不出原因,請大佬看看!

單片機源程序如下:
  1. #include <reg52.h>
  2. #include<string.h>
  3. #include <intrins.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6.      
  7. sbit lcdrs=P2^0;       //寄存器選擇,0:數據寄存器。1:為狀態/命令寄存器
  8. sbit lcden=P2^1;         //--LCD控制引腳

  9. sbit speed=P3^2;                                        //測速端口
  10. sbit ENA=P2^2;                                        //電機使能控制端

  11. sbit key1=P1^0;         //啟動按鍵
  12. sbit key2=P1^1;                                        //正轉按鍵
  13. sbit key3=P1^2;                                        //反轉按鍵
  14. sbit key4=P1^3;                                        //加速按鍵
  15. sbit key5=P1^4;                                        //減速按鍵
  16. sbit key6=P1^5;                                        //停止按鍵
  17. sbit Zheng=P1^6;                                                //正轉輸出端口
  18. sbit Fan=P1^7;                                                //反轉輸出端口

  19. uchar Timer0_flag=4;
  20. uchar Timer0_BiaoZhi=0;//初始化占空比為1:3(高:低)

  21. uchar gewei;
  22. uchar shiwei;
  23. uchar baiwei;

  24. /******標志位設置*****/
  25. uchar KEY1=0;//優先級標志
  26. uchar KEY2=0;//加速標志

  27. uchar INT1_FLAG=0;
  28. uchar COUNTER_high=0;
  29. uchar COUNTER_low=0;
  30. uchar SUM=0;
  31. uint TIMER1_COUNTER=0;
  32. uint INT1_tingzhi=0;                //在要測速時置0

  33. /****面板顯示****/
  34. uchar code lcd_desktop10[]="WUU";//不顯示
  35. uchar code lcd_desktop11[]="RUN";//運行
  36. uchar code lcd_desktop12[]="FWD";//正轉
  37. uchar code lcd_desktop13[]="REV";//反轉
  38. uchar code lcd_desktop14[]="JIA";//加速
  39. uchar code lcd_desktop15[]="JAN";//減速
  40. uchar code lcd_desktop16[]="OFF";//停止
  41. uchar code num[]={'0','1','2','3','4','5','6','7','8','9'};//要顯示的轉速數字。

  42. //-----lcd液晶屏頭文件-----//
  43. /**延時函數**/
  44. void delayms(uchar xms)   
  45. {
  46.         uchar i,j;
  47.         for(i=xms;i>0;i--)
  48.         for(j=110;j>0;j--);
  49. }

  50. /****LCD寫命令******/
  51. void write_command(uchar com)//com寫入命令
  52. {
  53.         lcdrs=0;    //LED選擇輸入命令
  54.         P0=com;     //向P0口輸入命令39-32端口
  55.         delayms(2);  //延時
  56.         lcden=1;     //打開LCD使能
  57.         delayms(2);  //一個高脈沖
  58.         lcden=0;     //關閉LED使能
  59. }

  60. /**************LCD寫數據,來源網上*********/
  61. void write_data(uchar date)//數據為DATA
  62. {
  63.         lcdrs=1;  //設置為輸入數據
  64.         P0=date;  //將數據賦給P0口
  65.         delayms(2);  //延時
  66.         lcden=1;     //置高
  67.         delayms(2);
  68.         lcden=0;     //置低完成高脈沖
  69. }

  70. /********LCD初始化,來源網上****************/
  71. void lcd_init()//顯示模式設置
  72. {
  73.         lcden=0;
  74.         write_command(0x38);   //設置16×2 顯示5×7點陣,8位數據接口
  75.         write_command(0x0c);   //設置開始顯示不顯示光標(指令4)
  76.         write_command(0x06);   //寫一個字符后地址指針加一(指令3)
  77.         write_command(0x01);   //顯示清零數據指針清零(指令1)
  78. }

  79. /**電機初始化函數**/
  80. void motor_init(void)
  81. {
  82.         ENA=0;                                //        停止
  83. }

  84. void ZhongDuanKaiQi(void)
  85. {
  86.         EA=1;               
  87.         ET0=1;        //計時器0允許中斷。產生脈沖。
  88.         ET1=1;        //計時器1允許中斷。對低電平進行計時。
  89.         //EX1=1;        //INT0允許中斷。測速。由外部來啟動。
  90.         IT1=1;        //外部中斷1低電平觸發。
  91.         PX1=0;        //外中斷0為低級中斷。
  92.         PT0=1;  //定時器0為高優先級中斷
  93.         PT1=0;  //外中斷1為低優先級中斷
  94.         TMOD=0x12;//定時器工作方式控制
  95. }
  96. /***定時器T1初始化!!!等待外部脈沖的到來***/
  97. void Timer1_init(void)
  98. {
  99.         TH1=0;
  100.         TL1=0;                //等待外部脈的到來。INT1
  101. }
  102. /*****定時T0初始化*****/
  103. void Timer0_init(void)
  104. {
  105.         TH0=0;
  106.         TL0=0;
  107.         TR0=1;
  108. }
  109. /********測速模塊,顯示速度*******/
  110. void speed_test(void)
  111. {
  112. //        TIMER1_COUNTER;
  113.         COUNTER_high=TH1;
  114.         COUNTER_low=TL1;
  115.         SUM=COUNTER_high*256+COUNTER_low+TIMER1_COUNTER*65536;//得到的是多少us。
  116.         //count:每百16位進1,16位為65536;TH1:每8位進1,8位為256;TL1:每次進1;即TL1由0增加度到內255時,TH1加1,TL1回0,TH1由0增加到65535時,count加1,TH1回0,三者之和為總次數。
  117.         SUM=SUM/1000;                                //化為毫秒。
  118.         SUM=1000/SUM;                                //圈每秒。
  119.         SUM=SUM*60;                                        //圈每分鐘;三位數。
  120.         gewei=SUM%10+0x30;
  121.         shiwei=SUM/10%10+0x30;
  122.         baiwei=SUM/100+0x30;
  123.         write_command(0x80+0x4c);
  124.         write_data(baiwei);
  125.         write_command(0x80+0x4d);
  126.         write_data(shiwei);
  127.         write_command(0x80+0x4e);
  128.         write_data(gewei);
  129.         SUM=0;
  130.         TIMER1_COUNTER=0;               
  131. }

  132. /********外中斷1函數**********/
  133. void INT1_QIDONG() interrupt 2
  134. {
  135.         INT1_tingzhi++;
  136.         if(INT1_tingzhi==5)
  137.         {
  138.                 INT1_tingzhi=5;EX1=0;//關閉中斷。
  139.         }
  140.         if(INT1_tingzhi<=4)
  141.         {
  142.                 INT1_FLAG++;
  143.           if(INT1_FLAG==2)
  144.                         {
  145.                                 INT1_FLAG=0;TR1=0;speed_test();
  146.                         }
  147.                 else
  148.                         {
  149.                                 Timer1_init();
  150.                                 TR1=1;
  151.                         }
  152.         }
  153. }
  154. /******定時器T1計數*******/
  155. void Timer1_QIDONG() interrupt 3
  156. {
  157.         TIMER1_COUNTER++;
  158. }



  159. /****T0中斷發出信號并進行通道選擇****/
  160. void Timer0() interrupt 1
  161. {        
  162.         Timer0_flag--;
  163.         if((Timer0_BiaoZhi)>=(Timer0_flag))
  164.         {
  165.                 if(KEY2==0)
  166.                 {
  167.                         Zheng=1;Fan=0;
  168.                 }
  169.                 else
  170.                 {
  171.                         Zheng=0;Fan=1;
  172.                 }
  173.         }
  174.         else
  175.         {
  176.                 Zheng=0;Fan=0;                                
  177.         }        
  178.         if(Timer0_flag==0) Timer0_flag=5;
  179. }


  180. void Guan(void)
  181. {
  182.         ET0=0;
  183.         EX1=0;
  184.         ET1=0;        
  185. }


  186. void keyscan()                         //按鍵掃描函數
  187. {
  188.         uint i=0;
  189.         if(key1==0)   //按鍵K1啟動按鈕。只有該位啟動時,后面的幾位才有效。啟動T0計數開始發出脈沖。
  190.         {
  191.                 delayms(10);
  192.                 if(key1==0)
  193.                 {
  194.                         while(!key1);
  195.                         KEY1=5;
  196.                         Fan=0;
  197.                         Zheng=0;
  198.                         ENA=1;
  199.                         KEY2=0;//初始化為正轉。
  200.                   Timer0_BiaoZhi=0;
  201.                         Timer0_flag=4;
  202.                         
  203.                         ZhongDuanKaiQi();//開啟中斷        
  204.                         Timer0_init();//                初始化并開始發出脈沖外中斷已經開啟。
  205.                         EX1=1;                                        //外中斷開啟;測速,顯示速度。
  206.                         
  207.                         write_command(0x80);
  208.                         for(i=0;i<strlen(lcd_desktop10);i++)//顯示正轉。
  209.                         write_data(lcd_desktop11[i]);
  210.                 }
  211.         }
  212.         
  213.   if(key2==0&&KEY1==5) //按鍵K2按下,(正轉)只改變轉向(標志位改變輸出端口)
  214.         {
  215.                 delayms(10);
  216.                 if(key2==0)
  217.                 {
  218.                         while(!key2);
  219.                         KEY2=0;                //正轉標志,電機正向旋轉。
  220.                         //KEY2=(~1);
  221.                
  222.                         KEY1=5;
  223.                         write_command(0x80);
  224.                         for(i=0;i<strlen(lcd_desktop11);i++)//顯示正轉。
  225.                         write_data(lcd_desktop12[i]);
  226.                 }
  227.         }
  228.         
  229.         if(key3==0&&KEY1==5) //按鍵K3按下,(反轉)只改變轉向
  230.         {
  231.                 delayms(10);
  232.                 if(key3==0)
  233.                 {
  234.                         while(!key3);
  235.                         KEY2=~0;                        //反轉標志。
  236.                         //KEY2=(~0);
  237.                
  238.                         KEY1=5;
  239.                         write_command(0x80);
  240.                         for(i=0;i<strlen(lcd_desktop12);i++)//顯示反轉。
  241.                         write_data(lcd_desktop13[i]);
  242.                 }
  243.         }
  244.    if(key4==0&&KEY1==5)        //按鍵K4按下,(加速)改變裝入的數值?循環次數?執行if里面的語句,通過size++來改變幅值的頻率
  245.          {
  246.                  delayms(10);
  247.                  if(key4==0)
  248.                  {
  249.                          while(!key4);
  250.                          if(Timer0_BiaoZhi<4)
  251.                          {
  252.                                  Timer0_BiaoZhi++;
  253.                          }
  254.                          else
  255.                          {
  256.                                  Timer0_BiaoZhi=4;
  257.                          }
  258.                           EX1=1;
  259.                           KEY1=5;
  260.                          write_command(0x80);
  261.                         for(i=0;i<strlen(lcd_desktop13);i++)//顯示加速。
  262.                         write_data(lcd_desktop14[i]);
  263.                  }
  264.                
  265.          }
  266.          
  267.          if((key5==0)&&(KEY1==5))         //按鍵K5按下,(減速)對其它標志位沒有影響。
  268.          {
  269.                  delayms(5);
  270.                  if(key5==0)
  271.                  {
  272.                          while(!key5);
  273.                          if(Timer0_BiaoZhi==0)
  274.                          {
  275.                                  Timer0_BiaoZhi=0;
  276.                          }
  277.                          else
  278.                          {
  279.                                  Timer0_BiaoZhi--;
  280.                          }
  281.                           EX1=1;
  282.                           KEY1=5;
  283.                          write_command(0x80);
  284.                         for(i=0;i<strlen(lcd_desktop14);i++)//顯示減速。
  285.                         write_data(lcd_desktop15[i]);
  286.                  }
  287.          }
  288.          if((key6==0)&&(KEY1==5))//按鍵K6按下,電機停止轉動使能端和計數啟動關閉,計數器工作否?設立標志位。此按鍵按下后除K1外無法啟動
  289.          {
  290.                  delayms(5);
  291.                  if(key6==0)
  292.                  {
  293.                          while(!key6);
  294.                          //置位,保證后續操作正常。
  295.                         
  296.                         
  297.                         
  298.                          EA=0;                                //總中斷關
  299.                          motor_init();                //電機關
  300.                          Guan();
  301.                          write_command(0x80);
  302.                         for(i=0;i<strlen(lcd_desktop15);i++)//顯示停止。
  303.                         write_data(lcd_desktop16[i]);                                 
  304.                  }
  305.          }
  306. }

  307. /*主函數*/
  308. void main()
  309. {

  310.         ZhongDuanKaiQi();//初始化
  311.         motor_init();                        //電機停止
  312.         lcd_init();
  313.         while(1)
  314.         {
  315.                 keyscan();
  316.                
  317.         }
  318. }
復制代碼
11111.jpg





電路圖和程序,可以仿真。
電機控制及顯示.zip (68.96 KB, 下載次數: 8)

回復

使用道具 舉報

ID:749922 發表于 2020-5-18 11:13 | 顯示全部樓層
沒人回答嗎
回復

使用道具 舉報

ID:682488 發表于 2020-5-18 11:27 | 顯示全部樓層
用T2口試試,或許是片子質量有問題呢
回復

使用道具 舉報

ID:749922 發表于 2020-5-18 13:24 | 顯示全部樓層
大長蟲 發表于 2020-5-18 11:27
用T2口試試,或許是片子質量有問題呢

仿真的話,應該和片子沒關系吧。然后我覺得程序的問題在于那個函數sun算出來的是一個確定的值,但是我現在找不出問題在哪里
回復

使用道具 舉報

ID:754714 發表于 2020-5-18 13:44 | 顯示全部樓層
建議調整測速函數與顯示函數各種的參數,是否二者存在某項參數的不匹配。
回復

使用道具 舉報

ID:749922 發表于 2020-5-18 14:56 | 顯示全部樓層
1649293198 發表于 2020-5-18 13:44
建議調整測速函數與顯示函數各種的參數,是否二者存在某項參數的不匹配。

我剛才把sum的函數去掉,發現沒有給sum(也就是輸出的速度)賦值,他也能輸出096,給他賦值也還是輸出096,也就是輸出的數字完全就不是我想要的,這是為啥??
回復

使用道具 舉報

ID:749922 發表于 2020-5-18 15:02 | 顯示全部樓層
1649293198 發表于 2020-5-18 13:44
建議調整測速函數與顯示函數各種的參數,是否二者存在某項參數的不匹配。

我剛才把sum的函數去掉了,也就是沒有給sum(要輸出的速度)賦值,但是仿真的時候還是能出現096,給它賦值的時候也是輸出096,這是為什么?
回復

使用道具 舉報

ID:749922 發表于 2020-5-18 16:17 | 顯示全部樓層
現在的問題就是,sum的值就是0,函數沒有用,是因為外部中斷沒有起作用開始不能使T1開始計時嗎?
回復

使用道具 舉報

ID:752225 發表于 2020-5-18 17:04 來自手機 | 顯示全部樓層
你液晶程序在讀寫數據時不用判斷忙不忙嗎?可以百度一下判忙哪里是不是出現了問題
回復

使用道具 舉報

ID:752225 發表于 2020-5-18 17:07 來自手機 | 顯示全部樓層
還有在哪里添加延時非常重要,不過51的應該對延時要求不大,這個要參考數據手冊,我兩個1602液晶發現不能公用一個程序,當初困擾了很久,多半是延時和判忙哪里有問題,個人建議
回復

使用道具 舉報

ID:732506 發表于 2020-5-19 02:56 | 顯示全部樓層
圖太小,看不清測速端口信號從何而來?如果不是來自電機,應該人為注入一定頻率的信號來模擬電機轉動。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产日韩欧美中文 | 免费国产黄网站在线观看视频 | 国产精品区二区三区日本 | 欧美韩一区二区三区 | 成年人在线视频 | 精品美女久久久久久免费 | 国产999精品久久久 日本视频一区二区三区 | 一区二区精品 | 亚洲欧美国产精品久久 | 狠狠av| 羞羞的视频在线 | 一色一黄视频 | 国产一区二区三区网站 | 一区在线视频 | 欧美激情精品久久久久久变态 | 欧美一区二区三区在线观看 | 欧美黑人体内she精在线观看 | 国产成人精品一区二区三区四区 | 91久久综合亚洲鲁鲁五月天 | 91人人视频在线观看 | 欧美日韩国产一区二区三区 | 国产精品18久久久久久久 | 亚洲国产成人精品女人久久久 | 日本不卡视频 | 在线欧美亚洲 | 欧美精品在线播放 | 一区视频在线免费观看 | 中文av电影| 国产日韩一区二区三免费 | 99精品视频在线观看免费播放 | 麻豆hd| 99热精品在线观看 | 欧美性猛片aaaaaaa做受 | 日韩精品免费一区 | 欧美日本韩国一区二区 | 天天影视网天天综合色在线播放 | 亚洲精品久久久蜜桃 | 黄色片大全在线观看 | 亚洲午夜在线 | 日韩一级免费电影 | 国产四虎 |