找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

調(diào)試光立方踩坑經(jīng)驗(yàn)-單片機(jī)程序跑飛原因之一

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:134415 發(fā)表于 2018-11-14 11:53 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
        這幾天在調(diào)光立方的程序時(shí)遇到一個(gè)令我十分困擾的問題,現(xiàn)象大致如下:

一開始我在對單個(gè)光立方動(dòng)畫調(diào)試時(shí)并沒有出現(xiàn)問題,都是正常運(yùn)行,然而我將多個(gè)動(dòng)畫程序?qū)懞寐?lián)合在一起運(yùn)行時(shí)便出現(xiàn)了問題,將程序燒錄到單片機(jī)中后,程序可能能夠正常運(yùn)行好幾圈沒有問題,但是終究會(huì)卡死,也有可能一圈都沒跑完就卡死了,有時(shí)重啟單片機(jī)都是卡死的。
       出現(xiàn)這個(gè)問題當(dāng)時(shí)真的讓我很頭疼,想著沒道理會(huì)出現(xiàn)這種現(xiàn)象,程序本身并不復(fù)雜,也沒有用大量的資源,就是占得內(nèi)存多一點(diǎn),但是這個(gè)問題卻讓我摸不著頭腦,沒有理由,程序能夠正常運(yùn)行第一圈,而第二圈卻出現(xiàn)問題;于是我自網(wǎng)上看了一些相關(guān)程序跑飛的原因,如數(shù)組越界,堆棧錯(cuò)誤,沒有中斷服務(wù)程序等,當(dāng)時(shí)我覺得最可能是堆棧的問題,不過還沒去驗(yàn)證這個(gè)想法,后來我便找到原因了,從事后的角度來看,首先,通過程序跑飛的現(xiàn)象來看肯定不是數(shù)組越界,數(shù)組越界的話,第一圈就跑不完了,會(huì)出現(xiàn)堆棧錯(cuò)誤的原因沒有去了解,這里也就不談了,所以我出現(xiàn)跑飛的原因就是,沒有中斷服務(wù)程序,程序找不到中斷入口而跑飛,可能大家會(huì)覺得這是個(gè)顯而易見的問題,怎么會(huì)忽視呢,我先講講我當(dāng)時(shí)的想法,我看到可能是沒有中斷服務(wù)程序的原因時(shí),我首先的想法是   “我并沒有使用中斷啊,應(yīng)該不是中斷的問題”  所以我才一直懷疑是堆棧的原因,就是這么個(gè)想法,相當(dāng)于自己蒙騙了自己,由于許久沒有找到原因,在后來的調(diào)試中我準(zhǔn)備把沒有用到的函數(shù)都注釋掉,使程序看著簡潔些,順便把警告去除了,也就在這時(shí)我看到了自己的問題,在初始化函數(shù)中我居然將定時(shí)器配置了,然而我卻沒有定時(shí)器的中斷服務(wù)程序,看到這個(gè),我想問題應(yīng)該就在這里了。那么為什么,我沒有使用定時(shí)器卻開啟了中斷配置呢,唉!因?yàn)楣饬⒎降闹靼迨俏屹I的,例程是店家送的,但是我覺得店家的代碼風(fēng)格和我平常上課所學(xué)習(xí)不太一樣就不習(xí)慣(店家所有的函數(shù)都在一個(gè)c文件中,因?yàn)閯?dòng)畫很多程序有幾千行,看著很麻煩),而且有些動(dòng)畫我也不喜歡,我想做一些自己的動(dòng)畫,于是我就將店家的程序改寫成模塊化的,所以基本的程序我就是copy的,問題也就這么出來了,在我寫的動(dòng)畫和調(diào)用店家例程動(dòng)畫中都沒有用到定時(shí)器中斷(就是連 void xxx(void) interrupt x 函數(shù)都沒有),所以這是一個(gè)簡單的問題,然而我卻沒注意,在這里將這篇心得和大家分享一下,也希望有學(xué)習(xí)單片機(jī)編程但是不熟練的同學(xué)能夠引以為戒。
       將這個(gè)錯(cuò)誤改正之后一直到我寫一些心得時(shí),程序都沒有再跑飛,以前一直在學(xué)習(xí)前輩們的踩坑經(jīng)驗(yàn),今天也輪到我給萌新們分享一點(diǎn)自己的經(jīng)驗(yàn),可能有前輩會(huì)覺得這么簡單的問題,我寫的這么啰嗦,但實(shí)際情況卻是我因此頭疼了好久,才有此感想。我將程序也放在后面可以給想做光立方的同學(xué)參考一下,但是我這個(gè)的鎖存器是用的74hc595 是一個(gè)8位移位緩存器和 平時(shí)使用比較多的 573 不太一樣,想要參考的同學(xué)注意下,程序文件夾中我放了一個(gè)原理圖pdf可以參考。

單片機(jī)源程序如下:
  1. #include "common.h"
  2. sbit RR=P3^6;//紅
  3. sbit BB=P2^4;//藍(lán)
  4. char data cheng;
  5. //void delay_1us(uint i)
  6. //{
  7. // unsigned int b;
  8. //   for(b=0;b<i;b++);
  9. //}
  10. //void delay_1ms(uint i)
  11. //{
  12. // unsigned int j,k;
  13. //   for(k=0;k<120;k++)
  14. //    for(j=0;j<i;j++);
  15. //}
  16. void  red (void)        //紅燈亮
  17. {
  18.     RR=0;//紅
  19.     BB=1;//藍(lán)
  20. }
  21. //void  blue (void)  //藍(lán)燈亮
  22. //{
  23. //    RR=1;//紅
  24. //    BB=0;//藍(lán)
  25. //}

  26. void initial595()         //列驅(qū)動(dòng)初始化
  27. {
  28.                 SH_CP = 0;
  29.                 ST_CP = 0;
  30.                 DS = 0;
  31. }
  32.   void initial5952() //行驅(qū)動(dòng)初始化
  33. {
  34.                 SH_CP2 = 0;
  35.                 ST_CP2 = 0;
  36.                 DS2 = 0;
  37. }

  38. /************************************ 發(fā)送數(shù)據(jù) ***************************************************************/
  39. //void send_data(unsigned char d)//發(fā)送一層當(dāng)中的一行顯示數(shù)據(jù),8位
  40. //{
  41. //                unsigned char i;
  42. //                for(i=0;i<8;i++)
  43. //                {
  44. //                        DS = d&0x80;//發(fā)送最低位
  45. //                        SH_CP = 1;
  46. //                        delay_1us(15);
  47. //                        SH_CP = 0; //移位寄存器移位
  48. //                        delay_1us(15);
  49. //                        d = d<<1; //數(shù)據(jù)移位f
  50. //                }
  51. //                //因?yàn)槭褂枚鄠(gè)595級聯(lián),此處未做數(shù)據(jù)輸出鎖存,
  52. //                //須將所有數(shù)據(jù)發(fā)送出來后再做鎖存輸出
  53. //}

  54. //void send_data2(unsigned char d)//發(fā)送層顯示數(shù)據(jù),8位
  55. //{
  56. //         unsigned char i,j=0;
  57. //
  58. //                for(i=0;i<8;i+=2)
  59. //                {
  60. //                        DS2 = d&0x80;//發(fā)送最低位
  61. //                        SH_CP2 = 1;
  62. //                        delay_1us(15);
  63. //                        SH_CP2 = 0; //移位寄存器移位
  64. //                        delay_1us(15);
  65. //                        d = d<<1; //數(shù)據(jù)移位
  66. //                }
  67. //            ST_CP2 = 0;                   //數(shù)據(jù)輸出鎖存
  68. //                delay_1us(15);
  69. //                ST_CP2 = 1;        
  70. //                delay_1us(15);
  71. //            ST_CP2 = 0;        
  72. //}
  73. //void send_data2_1bit(unsigned char layer)//發(fā)送層顯示數(shù)據(jù),1位
  74. //{
  75. //        unsigned char ceng=0;
  76. //
  77. //        ceng=0x01<<layer;                 //行移位,
  78. //        DS2 = ~ceng&0x01;                 //發(fā)送層掃描數(shù)據(jù)
  79. //
  80. //        SH_CP2 = 1;
  81. //        delay_1us(15);
  82. //        SH_CP2 = 0; //移位寄存器移位
  83. //        delay_1us(15);
  84. //
  85. //    ST_CP2 = 0;                   //數(shù)據(jù)輸出鎖存
  86. //        delay_1us(15);
  87. //        ST_CP2 = 1;        
  88. //        delay_1us(15);
  89. //    ST_CP2 = 0;        
  90. //}
  91. void delay(uint i)
  92. {                                                                                       
  93.         char b;
  94.         while (i--)
  95.         {
  96.            b=1;
  97.                 while(b--);
  98.         }
  99. }

  100. /*************************************黎明途電子************************************************************/        
  101. /*************************************脫機(jī)動(dòng)畫文件************************************************/



  102. /*---------------------------
  103. //函數(shù)名:void sendbyte1 (uint num1....)
  104. //功能:一次發(fā)送四個(gè)數(shù)據(jù)給鎖存器
  105. //參數(shù):num1,num2,num3,num4
  106. //返回值:無
  107. ----------------------------*/
  108. void sendbyte1(unsigned int num1,unsigned int num2,unsigned int num3,unsigned int num4)
  109. {
  110.         unsigned char i=0;
  111.         for(i=0;i<8;i++)
  112.         {
  113.                 DS = num1&0x01;         //發(fā)送最低位
  114.                 SH_CP = 1;
  115.                 SH_CP = 0;                 //移位寄存器移位
  116.            num1=num1>>1;         //數(shù)據(jù)移位f
  117.         }

  118.          for(i=0;i<8;i++)
  119.         {
  120.                 DS = num2&0x01;         //發(fā)送最低位
  121.                 SH_CP = 1;
  122.                 SH_CP = 0;                 //移位寄存器移位
  123.                 num2 = num2>>1;                 //數(shù)據(jù)移位f
  124.         }

  125.         for(i=0;i<8;i++)
  126.         {
  127.                 DS = num3&0x01;         //發(fā)送最低位
  128.                 SH_CP = 1;
  129.                 SH_CP = 0;                 //移位寄存器移位
  130.                 num3 = num3>>1;         //數(shù)據(jù)移位f
  131.         }

  132.          for(i=0;i<8;i++)
  133.         {
  134.                 DS = num4&0x01;         //發(fā)送最低位
  135.                 SH_CP = 1;
  136.                 SH_CP = 0;                 //移位寄存器移位
  137.                 num4 = num4>>1;                 //數(shù)據(jù)移位f
  138.         }
  139.    
  140. }
  141. /*----------------------------------------------
  142. //函數(shù)名  :void zhen (uchar *a,uchar V)
  143. //函數(shù)功能:將待顯示的數(shù)據(jù)寫入鎖存器中并顯示
  144. //參數(shù):*a:待顯示數(shù)據(jù)-,V循環(huán)此次數(shù)(為何循環(huán)?經(jīng)驗(yàn)證只是增加顯示時(shí)間)
  145. //返回值:無
  146. ------------------------------------------------*/
  147.                         
  148. void zhen(uchar *a,uchar v)         
  149. {
  150. char layer;

  151. while(v--)//?為何需要循環(huán)???增加顯示時(shí)間?√ 就是這樣 。。
  152. {
  153.   
  154.   for(layer=0;layer<8;layer++) //將每層8列數(shù)碼發(fā)送 循環(huán)8次8層數(shù)據(jù)依次發(fā)送
  155.   {                                                                     /* 數(shù)組的每一位是一列數(shù)據(jù)*/
  156.         sendbyte1(~a[layer*8+7],~a[layer*8+6],~a[layer*8+5],~a[layer*8+4]);        
  157.         sendbyte1(~a[layer*8+3],~a[layer*8+2],~a[layer*8+1],~a[layer*8+0]);
  158.                                               //和直接調(diào)顯示函數(shù)是一個(gè)道理
  159.         cheng=0x01<<layer;
  160.     DS2 =~cheng&0x01;         //發(fā)送最低位
  161.             ST_CP=1;        
  162.             ST_CP=0;
  163.                 SH_CP2 = 1;
  164.                 SH_CP2 = 0;                 //移位寄存器移位
  165.                 ST_CP2=1;        
  166.             ST_CP2=0;                                             
  167.                 delay(300);                                                
  168.   }

  169. }
  170. }

  171. void clc()//全局清屏
  172. {
  173.           unsigned char k;         
  174. for(k=0;k<64;k++)
  175. {        //d=0xff;
  176.    
  177.                 DS = 0;         //發(fā)送最低位
  178.                 SH_CP = 1;
  179.                 SH_CP = 0;                 //移位寄存器移位
  180.         //        d = d<<1;                 //數(shù)據(jù)移位f

  181.   }
  182.           ST_CP=1;        
  183.           ST_CP=0;         
  184. }
復(fù)制代碼

所有資料51hei提供下載:
光立方修改.rar (650.29 KB, 下載次數(shù): 14)


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

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

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