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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3108|回復: 12
打印 上一主題 下一主題
收起左側

誠心求解答!關于利用stc15單片機制作俯臥撐計數裝置的問題

[復制鏈接]
跳轉到指定樓層
樓主
400黑幣
樓主單片機小白一名。正在學習stc15w4k32s4這一款單片機。目前想利用超聲波傳感器做一個俯臥撐計數的裝置。但是遇到了種種問題,經過長時間的調試仍未好轉,誠心求大佬解答!
項目具體描述如下:stc15單片機與兩個HC-SR04超聲波連接,通電后超聲波測距并在12864液晶上實時顯示,通過監測超聲波返回的距離變化來統計做了俯臥撐的個數。當距離超出一定范圍時蜂鳴器就會報警,提示別人姿勢錯誤。測量的距離同時通過串口返回給電腦。
遇到的問題:目前給單片機上電后在絕大多數情況下單片機無法正常工作,液晶只亮不顯示,串口助手無數據返回,蜂鳴器不響。像是沒有進入到主函數中,單片機像是“僵死”了。樓主不知道是代碼的問題還是硬件焊接的問題實物圖如下:


單片機代碼如下:
  1. #include<stc15w.h>
  2. #include<intrins.h>
  3. #include<stdio.h>
  4. #include<math.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int
  7. #define Part P1 //P0接8位數據線
  8. sbit LCD_RS=P2^6;  //定義12864液晶RS端,寄存器選擇信號 H:數據寄存器 L:指令寄存器   
  9. sbit LCD_RW=P2^5;  //定義12864液晶RW端,讀/寫信號  H:讀   L:寫   
  10. sbit LCD_EN=P2^4;  //定義12864液晶LCDEN端, 片選信號  下降沿觸發,鎖存數據   
  11. sbit LCD_PSB=P2^3;  //定義12864液晶PSB端, H:并行 L:串行  
  12. sbit Echo1=P0^0;//超聲波測距模塊Echo1連接的IO
  13. sbit Trig1=P0^1;//超聲波測距模塊Trig1連接的IO
  14. sbit Echo2=P0^2;//超聲波測距模塊Echo2連接的IO
  15. sbit Trig2=P0^3;//超聲波測距模塊Trig2連接的IO
  16. sbit Beep=P2^7;//蜂鳴器連接的IO口
  17. uchar show1[]="chest:0000mm";
  18. uchar show2[]="waist:0000mm";
  19. uchar show3[]="gap:000mm";
  20. uchar show4[]="times:000";
  21. uint xdata distance1=600,distance2=600,time,num=0;
  22. uchar xdata urdat,k=1;
  23. float xdata ratio;
  24. char xdata m=1;
  25. int xdata gap;
  26. void SendData(unsigned char dat);
  27. void delayms(uint xms)
  28. {        
  29.         uint i,j;
  30.         for(i=xms;i>0;i--)
  31.                 for(j=110;j>0;j--);
  32. }
  33. void Delay20us()                //@11.0592MHz
  34. {
  35.         unsigned char i;

  36.         _nop_();
  37.         _nop_();
  38.         _nop_();
  39.         i = 52;
  40.         while (--i);
  41. }
  42. //====================================  
  43. //LCD忙檢測函數  
  44. bit lcd_busy()  
  45. {  
  46. bit result;  
  47.     LCD_RS=0;   
  48.   LCD_RW=1;  
  49.   LCD_EN= 1;  
  50.    result=(bit)(Part & 0x80);  
  51.    LCD_EN=0;  
  52. return result;  
  53. }  
  54. //=====================================  
  55. //液晶寫命令函數  
  56. void lcd_write_cmd(uchar com)  
  57. {  
  58. while(lcd_busy());  
  59. LCD_RS=0;  //選擇指令寄存器  
  60. LCD_RW=0;  //寫  
  61. LCD_EN=0;   
  62. Part=com;    //指令值賦給P1口  
  63. delayms(5);  
  64. LCD_EN=1;  
  65. delayms(5);  
  66. LCD_EN=0;   
  67. }  
  68. //=====================================  
  69. //液晶寫一個字符數據函數  
  70. void lcd_write_dat(uchar date)  
  71. {  
  72. while(lcd_busy());  
  73. LCD_RS=1;  //選擇數據寄存器  
  74. LCD_RW=0;  //寫  
  75. LCD_EN=0;  
  76. P1=date;    //數據值賦給P1口  
  77. delayms(5);  
  78. LCD_EN=1;  
  79. delayms(5);  
  80. LCD_EN=0;  
  81. }  
  82. //=====================================  
  83. //液晶寫一個字符串函數  
  84. //void lcd_write_string(uchar *str)  
  85. //{  
  86. //while(*str!='\0')  //未結束  
  87. // {  
  88. //  lcd_write_dat(*str++);  
  89. //  delayms(5);  
  90. // }  
  91. //}  
  92. //=====================================  
  93. //液晶顯示位置函數  
  94. void lcd_pos(uchar x,uchar y)  //從第X行的第Y位置開始顯示  
  95. {  
  96. uchar pos;  
  97. if(x==1)        //第一行  
  98. { x=0x80;}  
  99. else if(x==2)  //第二行  
  100. { x=0x90;}  
  101. else if(x==3)  //第三行  
  102. { x=0x88;}  
  103. else if(x==4)  //第四行  
  104. { x=0x98;}  
  105. pos=x+y-1;     //首地址為0X80  
  106. lcd_write_cmd(pos);  
  107. }  
  108. //=====================================  
  109. //液晶初始化函數  
  110. void lcd_init()  
  111. {  
  112. LCD_PSB=1;  //并行方式  
  113. lcd_write_cmd(0x30);  
  114. delayms(5);  
  115. lcd_write_cmd(0x0c);  //開顯示,不顯示光標  
  116. delayms(5);  
  117. lcd_write_cmd(0x06);  //寫一個字符后地址指針自動加1  
  118. delayms(5);  
  119. lcd_write_cmd(0x01);   //清屏  
  120. delayms(5);  
  121. }  
  122. //=====================================
  123. void Display1()
  124. {
  125.         uint xdata i;
  126.         lcd_pos(1,1);  
  127.         for(i=0;i<13;i++)
  128.   {lcd_write_dat(show1[i]); }  
  129. }
  130. void Display2()
  131. {
  132.         uint xdata i;
  133.   lcd_pos(2,1);  
  134.         for(i=0;i<13;i++)  
  135.   {lcd_write_dat(show2[i]); }      
  136. }
  137. void Display3()
  138. {
  139.         uint xdata i;
  140.   lcd_pos(3,1);  
  141.         for(i=0;i<10;i++)   
  142.   {lcd_write_dat(show3[i]); }  
  143. }
  144. void Display4()
  145. {
  146.         uint xdata i;
  147.   lcd_pos(4,1);  
  148.         for(i=0;i<9;i++)   
  149.   {lcd_write_dat(show4[i]); }  
  150. }
  151. void UartInit(void)
  152. {
  153.         SCON=0x50;//工作方式選擇:8位UART波特率可變
  154.         AUXR&=0x80;
  155.         TMOD=0x00;
  156.         TL1=0xe8;
  157.         TH1=0xff;
  158.         TR1=1;
  159.         ES=1;
  160.         EA=1;
  161. }//配置波特率,對數據采樣
  162. void Uart() interrupt 4 using 1//定時器1,16位自動重裝模式
  163. {
  164.         if(RI)
  165.         {
  166.                 urdat=SBUF;//從緩沖區讀取數據
  167.                 RI=0;//響應中斷請求后清零
  168.                 SendData(urdat);
  169.         }
  170. }
  171. void SendData(unsigned char dat)
  172. {
  173.         SBUF=dat;//將數據傳入PC機
  174.         while(TI==0);//等待發送中斷請求
  175.         TI=0;//響應中斷后TI清零
  176. }
  177. char putchar(char c)
  178. {
  179.         SendData(c);
  180.         return c;
  181. }//輸出成對象
  182. void INT_init1 (void)
  183. {
  184.         TMOD&=0x01;//定時器0,16位不可重裝載工作方式
  185.         TH0=0;//定時器0清零
  186.         TL0=0;//定時器0清零
  187.         EA = 1;//總中斷開
  188.         Trig1=0;//拉低為下次觸發做準備
  189.         Trig2=0;
  190. }
  191. void dist (void)//測量距離程序
  192. {
  193.         if(m==1)
  194.         {
  195.         Trig1=1;        
  196.         Delay20us();   //延時20us
  197.         Trig1=0;         //Trig輸出20us高電平觸發測距
  198.         while(Echo1==0); //等待Echo回波引腳變高電平
  199.         TR0=1;//程序運行到此處時說明Echo腳變成了高電平,此時啟動T0開始計時
  200.         while(Echo1==1); //等待Echo回波引腳高電平結束               
  201.         TR0=0;//程序運行到此處時說明Echo腳變成了低電平,此時T0停止計時
  202.         time=TH0*256+TL0;
  203.         distance1=time*0.272;  //測量距離
  204.         TH0 = 0;  //重置計時器
  205.         TL0 = 0;
  206.         }
  207.         if(m==-1)
  208.         {
  209.         Trig2=1;        
  210.         Delay20us();   //延時20us
  211.         Trig2=0;         //Trig輸出20us高電平觸發測距
  212.         while(Echo2==0); //等待Echo回波引腳變高電平
  213.         TR0=1;//程序運行到此處時說明Echo腳變成了高電平,此時啟動T0開始計時
  214.         while(Echo2==1); //等待Echo回波引腳高電平結束               
  215.         TR0=0;//程序運行到此處時說明Echo腳變成了低電平,此時T0停止計時
  216.         time=TH0*256+TL0;
  217.         distance2=time*0.24;  //測量距離
  218.         TH0 = 0;  //重置計時器
  219.         TL0 = 0;
  220.         }
  221.         m=-m;//輪流測量距離12
  222. }

  223. void main()//主函數  
  224. {
  225.         P0M0=0x00;P0M1=0x00;
  226.         P1M0=0x00;P1M1=0x00;
  227.         P2M0=0x00;P2M1=0x00;
  228.         P3M0=0x00;P3M1=0x00;//單片機IO口工作方式初始化
  229.         INT_init1();//T0初始化
  230.         UartInit();//串口初始化
  231.         lcd_init();//液晶初始化
  232.         while(1)        
  233.         {        
  234.                 dist();//定時器測量距離
  235.                 printf("dis1=%d\n",distance1);
  236.                 printf("dis2=%d\n",distance2);
  237.                 gap=distance1-distance2;
  238.                 gap=abs(gap);
  239.                 ratio=distance1/distance2;
  240.                 printf("gap=%d",gap);
  241.                 if(gap<=200)
  242.                 {
  243.                                 if(distance1<190&&distance2<180)
  244.                                 {
  245.                                         k=0;
  246.                                         Beep=0;
  247.                                         delayms(50);
  248.                                         Beep=1;
  249.                                 }
  250.                                 else if(distance1>200&&distance2>250&&k==0)
  251.                                 {
  252.                                         k=1;
  253.                                         Beep=0;
  254.                                         delayms(50);
  255.                                         Beep=1;
  256.                                         num++;
  257.                                 }
  258. //                                else continue;
  259.                 }
  260.                 else if(gap>200&&gap<400)
  261.                 {
  262.                         Beep=0;
  263.                         delayms(120);
  264.                         Beep=1;
  265.                 }
  266. //                else
  267. //                {
  268. //                        continue;
  269. //                }
  270.                 printf("times=%d\n",num);
  271.                 printf("     ");
  272.                 show1[6]=distance1/1000+0x30;
  273.                 show1[7]=distance1%1000/100+0x30;
  274.                 show1[8]=distance1%1000%100/10+0x30;
  275.                 show1[9]=distance1%10+0x30;
  276.                 show2[6]=distance2/1000+0x30;
  277.                 show2[7]=distance2%1000/100+0x30;
  278.                 show2[8]=distance2%1000%100/10+0x30;
  279.                 show2[9]=distance2%10+0x30;
  280.                 show3[4]=abs(gap)/100+0x30;
  281.                 show3[5]=abs(gap)%100/10+0x30;
  282.                 show3[6]=abs(gap)%10+0x30;
  283.                 show4[7]=num/100+0x30;
  284.                 show4[8]=num%100/10+0x30;
  285.                 show4[9]=num%10+0x30;
  286.           Display1();
  287.                 Display2();
  288.                 Display3();
  289.                 Display4();
  290.         }
  291. }
復制代碼

樓主立志做一名工程師,努力學習電子制作,雖然在項目的制作中屢屢受挫,但是仍不氣餒,我相信總有好心人為我指點迷津,是否可以大致指出我的項目哪里有什么硬傷?出現上述問題的可能原因是什么?如有則不勝感激!

最佳答案

查看完整內容

1,你要用printf的話,串口初始化要加上 TI = 1; 2,while(Echo1==0);這里最好改成 while(Echo1==0 && TR0 == 1);超時判斷,因為如果超聲模塊接收不到回聲,就會一直卡在while(Echo1==0);循環里面導致單片機卡死。 3,建議先單獨測試LCD屏幕能不能正常工作,再加上其他代碼,同理其他模塊得先確保能單獨工作的情況下,再把所有程序集成在一起。 4,超聲波測量周期建議100MS以上,否則會影響超聲波的下次測量結果,建議開個定時 ...
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:514901 發表于 2020-11-15 15:24 | 只看該作者
1,你要用printf的話,串口初始化要加上 TI = 1;
2,while(Echo1==0);這里最好改成 while(Echo1==0 && TR0 == 1);超時判斷,因為如果超聲模塊接收不到回聲,就會一直卡在while(Echo1==0);循環里面導致單片機卡死。
3,建議先單獨測試LCD屏幕能不能正常工作,再加上其他代碼,同理其他模塊得先確保能單獨工作的情況下,再把所有程序集成在一起。
4,超聲波測量周期建議100MS以上,否則會影響超聲波的下次測量結果,建議開個定時器來觸發超聲波測距
回復

使用道具 舉報

板凳
ID:648281 發表于 2020-11-15 16:39 | 只看該作者
你好!
首先把你的接線先整理一遍吧,接插件用的太多了,很容易造成斷路;
具體功能的實現,可以進行交流,軟硬件工程可以幫你完成。
回復

使用道具 舉報

地板
ID:160500 發表于 2020-11-15 18:44 | 只看該作者
絕大多數情況下單片機無法正常工作,意思就是有時候是可以正常工作的。這種問題就是線路連接的問題
回復

使用道具 舉報

5#
ID:736475 發表于 2020-11-16 22:51 | 只看該作者
51hei**1140 發表于 2020-11-15 16:39
你好!
首先把你的接線先整理一遍吧,接插件用的太多了,很容易造成斷路;
具體功能的實現,可以進行交流 ...

謝謝!
回復

使用道具 舉報

6#
ID:736475 發表于 2020-11-16 22:52 | 只看該作者
liuzx66 發表于 2020-11-15 18:44
絕大多數情況下單片機無法正常工作,意思就是有時候是可以正常工作的。這種問題就是線路連接的問題

確實,我也懷疑是線路的問題!因為我的線路全暴露在外面,我得考慮換一下杜邦線然后把他們焊在一起
回復

使用道具 舉報

7#
ID:736475 發表于 2020-11-16 22:52 | 只看該作者
鄭漢松 發表于 2020-11-16 10:57
1,你要用printf的話,串口初始化要加上 TI = 1;
2,while(Echo1==0);這里最好改成 while(Echo1==0 && TR ...

非常感謝有耐心幫我看代碼!
回復

使用道具 舉報

8#
ID:736475 發表于 2020-11-16 22:59 | 只看該作者
鄭漢松 發表于 2020-11-16 10:57
1,你要用printf的話,串口初始化要加上 TI = 1;
2,while(Echo1==0);這里最好改成 while(Echo1==0 && TR ...

可以用一個定時器來進行分頻,輪流觸發超聲波和液晶嗎?
回復

使用道具 舉報

9#
ID:736475 發表于 2020-11-16 23:15 | 只看該作者
鄭漢松 發表于 2020-11-16 10:57
1,你要用printf的話,串口初始化要加上 TI = 1;
2,while(Echo1==0);這里最好改成 while(Echo1==0 && TR ...

Timer0 function()
{
        static key_count=0;
        static display_count=0;
         key_count++;
        display_count++;
        if(key_count==10)
                {
                        key_count=0;
                        keyflag=1;
                }
        if(display_count==3)
                {
                        display_count==0;
                        display();
                }
}
類似于這樣
回復

使用道具 舉報

10#
ID:367934 發表于 2020-11-17 09:11 | 只看該作者
系統都是由簡單到復雜,想要知道問題出在哪里可以做一下簡單的測試。
1.找個萬用表測試一下電壓是否正常。可能是電壓問題。接錯或者反接一點機率會導致整個系統出問題。
2.程序下載。測試測試單片機是否出問題。如果沒有進行下一步。
3.找一個簡單的串口例程測試單片機是否有問題。或者把現在的程序把其他的功能先屏蔽掉,保留最簡單的串口通信程序。測試看有沒有問題。如果沒有進行下一步。
4.測試超聲波傳感器,使用串口可以進行測試。就這樣一步一步的把所有外設調試通過就好了。
回復

使用道具 舉報

11#
ID:426861 發表于 2020-11-17 09:31 | 只看該作者
軟件先只放一個功能的,然后測試硬件電路,只到調通了再調下一個,不要一起測試
回復

使用道具 舉報

12#
ID:89515 發表于 2020-11-17 09:41 來自觸屏版 | 只看該作者
把液晶屏換為串行通信嘛,這樣數據線只有一條,并行線太多太長接觸不良都有可能出現問題,而且不好找。就你的這個實驗用紅外對管不是更好做嗎?
回復

使用道具 舉報

13#
ID:342954 發表于 2020-11-17 09:42 | 只看該作者
查硬件,檢查電源,和單片機復位腳
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩伦理一区二区三区 | 欧美日韩精品久久久免费观看 | 欧美一区二区三区在线观看视频 | 久久99精品国产99久久6男男 | 中国av在线免费观看 | 久久综合一区 | 欧美久| 自拍视频精品 | www.狠狠干 | 免费久久网 | 精品久久电影 | 亚洲精品免费观看 | 人人看人人搞 | 91视频在线网站 | 国精日本亚洲欧州国产中文久久 | 一区二区久久电影 | 91久久久久久久久久久久久 | 国产成人精品免费视频大全最热 | 一区欧美 | 欧美激情精品久久久久久 | 亚洲男人的天堂网站 | 午夜影晥| 成人午夜电影在线观看 | 在线视频中文字幕 | 成人看片在线观看 | 欧美激情综合色综合啪啪五月 | 99色播| 正在播放亚洲 | 久久久2o19精品 | 欧美日韩精品免费 | 亚洲人成人一区二区在线观看 | 国产成人在线一区 | 亚洲国产精品激情在线观看 | 亚洲日本中文字幕在线 | 久久久久国产精品一区 | 成人妇女免费播放久久久 | 精品视频在线观看 | 国产日韩欧美一区 | 久久久久久久久久久久久久国产 | 亚洲狠狠 | 精品中文字幕久久 |