|
這幾天在調(diào)光立方的程序時遇到一個令我十分困擾的問題,現(xiàn)象大致如下:
一開始我在對單個光立方動畫調(diào)試時并沒有出現(xiàn)問題,都是正常運行,然而我將多個動畫程序?qū)懞寐?lián)合在一起運行時便出現(xiàn)了問題,將程序燒錄到單片機中后,程序可能能夠正常運行好幾圈沒有問題,但是終究會卡死,也有可能一圈都沒跑完就卡死了,有時重啟單片機都是卡死的。
出現(xiàn)這個問題當(dāng)時真的讓我很頭疼,想著沒道理會出現(xiàn)這種現(xiàn)象,程序本身并不復(fù)雜,也沒有用大量的資源,就是占得內(nèi)存多一點,但是這個問題卻讓我摸不著頭腦,沒有理由,程序能夠正常運行第一圈,而第二圈卻出現(xiàn)問題;于是我自網(wǎng)上看了一些相關(guān)程序跑飛的原因,如數(shù)組越界,堆棧錯誤,沒有中斷服務(wù)程序等,當(dāng)時我覺得最可能是堆棧的問題,不過還沒去驗證這個想法,后來我便找到原因了,從事后的角度來看,首先,通過程序跑飛的現(xiàn)象來看肯定不是數(shù)組越界,數(shù)組越界的話,第一圈就跑不完了,會出現(xiàn)堆棧錯誤的原因沒有去了解,這里也就不談了,所以我出現(xiàn)跑飛的原因就是,沒有中斷服務(wù)程序,程序找不到中斷入口而跑飛,可能大家會覺得這是個顯而易見的問題,怎么會忽視呢,我先講講我當(dāng)時的想法,我看到可能是沒有中斷服務(wù)程序的原因時,我首先的想法是 “我并沒有使用中斷啊,應(yīng)該不是中斷的問題” 所以我才一直懷疑是堆棧的原因,就是這么個想法,相當(dāng)于自己蒙騙了自己,由于許久沒有找到原因,在后來的調(diào)試中我準(zhǔn)備把沒有用到的函數(shù)都注釋掉,使程序看著簡潔些,順便把警告去除了,也就在這時我看到了自己的問題,在初始化函數(shù)中我居然將定時器配置了,然而我卻沒有定時器的中斷服務(wù)程序,看到這個,我想問題應(yīng)該就在這里了。那么為什么,我沒有使用定時器卻開啟了中斷配置呢,唉!因為光立方的主板是我買的,例程是店家送的,但是我覺得店家的代碼風(fēng)格和我平常上課所學(xué)習(xí)不太一樣就不習(xí)慣(店家所有的函數(shù)都在一個c文件中,因為動畫很多程序有幾千行,看著很麻煩),而且有些動畫我也不喜歡,我想做一些自己的動畫,于是我就將店家的程序改寫成模塊化的,所以基本的程序我就是copy的,問題也就這么出來了,在我寫的動畫和調(diào)用店家例程動畫中都沒有用到定時器中斷(就是連 void xxx(void) interrupt x 函數(shù)都沒有),所以這是一個簡單的問題,然而我卻沒注意,在這里將這篇心得和大家分享一下,也希望有學(xué)習(xí)單片機編程但是不熟練的同學(xué)能夠引以為戒。
將這個錯誤改正之后一直到我寫一些心得時,程序都沒有再跑飛,以前一直在學(xué)習(xí)前輩們的踩坑經(jīng)驗,今天也輪到我給萌新們分享一點自己的經(jīng)驗,可能有前輩會覺得這么簡單的問題,我寫的這么啰嗦,但實際情況卻是我因此頭疼了好久,才有此感想。我將程序也放在后面可以給想做光立方的同學(xué)參考一下,但是我這個的鎖存器是用的74hc595 是一個8位移位緩存器和 平時使用比較多的 573 不太一樣,想要參考的同學(xué)注意下,程序文件夾中我放了一個原理圖pdf可以參考。
單片機源程序如下:
- #include "common.h"
- sbit RR=P3^6;//紅
- sbit BB=P2^4;//藍(lán)
- char data cheng;
- //void delay_1us(uint i)
- //{
- // unsigned int b;
- // for(b=0;b<i;b++);
- //}
- //void delay_1ms(uint i)
- //{
- // unsigned int j,k;
- // for(k=0;k<120;k++)
- // for(j=0;j<i;j++);
- //}
- void red (void) //紅燈亮
- {
- RR=0;//紅
- BB=1;//藍(lán)
- }
- //void blue (void) //藍(lán)燈亮
- //{
- // RR=1;//紅
- // BB=0;//藍(lán)
- //}
- void initial595() //列驅(qū)動初始化
- {
- SH_CP = 0;
- ST_CP = 0;
- DS = 0;
- }
- void initial5952() //行驅(qū)動初始化
- {
- SH_CP2 = 0;
- ST_CP2 = 0;
- DS2 = 0;
- }
- /************************************ 發(fā)送數(shù)據(jù) ***************************************************************/
- //void send_data(unsigned char d)//發(fā)送一層當(dāng)中的一行顯示數(shù)據(jù),8位
- //{
- // unsigned char i;
- // for(i=0;i<8;i++)
- // {
- // DS = d&0x80;//發(fā)送最低位
- // SH_CP = 1;
- // delay_1us(15);
- // SH_CP = 0; //移位寄存器移位
- // delay_1us(15);
- // d = d<<1; //數(shù)據(jù)移位f
- // }
- // //因為使用多個595級聯(lián),此處未做數(shù)據(jù)輸出鎖存,
- // //須將所有數(shù)據(jù)發(fā)送出來后再做鎖存輸出
- //}
- //void send_data2(unsigned char d)//發(fā)送層顯示數(shù)據(jù),8位
- //{
- // unsigned char i,j=0;
- //
- // for(i=0;i<8;i+=2)
- // {
- // DS2 = d&0x80;//發(fā)送最低位
- // SH_CP2 = 1;
- // delay_1us(15);
- // SH_CP2 = 0; //移位寄存器移位
- // delay_1us(15);
- // d = d<<1; //數(shù)據(jù)移位
- // }
- // ST_CP2 = 0; //數(shù)據(jù)輸出鎖存
- // delay_1us(15);
- // ST_CP2 = 1;
- // delay_1us(15);
- // ST_CP2 = 0;
- //}
- //void send_data2_1bit(unsigned char layer)//發(fā)送層顯示數(shù)據(jù),1位
- //{
- // unsigned char ceng=0;
- //
- // ceng=0x01<<layer; //行移位,
- // DS2 = ~ceng&0x01; //發(fā)送層掃描數(shù)據(jù)
- //
- // SH_CP2 = 1;
- // delay_1us(15);
- // SH_CP2 = 0; //移位寄存器移位
- // delay_1us(15);
- //
- // ST_CP2 = 0; //數(shù)據(jù)輸出鎖存
- // delay_1us(15);
- // ST_CP2 = 1;
- // delay_1us(15);
- // ST_CP2 = 0;
- //}
- void delay(uint i)
- {
- char b;
- while (i--)
- {
- b=1;
- while(b--);
- }
- }
- /*************************************黎明途電子************************************************************/
- /*************************************脫機動畫文件************************************************/
- /*---------------------------
- //函數(shù)名:void sendbyte1 (uint num1....)
- //功能:一次發(fā)送四個數(shù)據(jù)給鎖存器
- //參數(shù):num1,num2,num3,num4
- //返回值:無
- ----------------------------*/
- void sendbyte1(unsigned int num1,unsigned int num2,unsigned int num3,unsigned int num4)
- {
- unsigned char i=0;
- for(i=0;i<8;i++)
- {
- DS = num1&0x01; //發(fā)送最低位
- SH_CP = 1;
- SH_CP = 0; //移位寄存器移位
- num1=num1>>1; //數(shù)據(jù)移位f
- }
- for(i=0;i<8;i++)
- {
- DS = num2&0x01; //發(fā)送最低位
- SH_CP = 1;
- SH_CP = 0; //移位寄存器移位
- num2 = num2>>1; //數(shù)據(jù)移位f
- }
- for(i=0;i<8;i++)
- {
- DS = num3&0x01; //發(fā)送最低位
- SH_CP = 1;
- SH_CP = 0; //移位寄存器移位
- num3 = num3>>1; //數(shù)據(jù)移位f
- }
- for(i=0;i<8;i++)
- {
- DS = num4&0x01; //發(fā)送最低位
- SH_CP = 1;
- SH_CP = 0; //移位寄存器移位
- num4 = num4>>1; //數(shù)據(jù)移位f
- }
-
- }
- /*----------------------------------------------
- //函數(shù)名 :void zhen (uchar *a,uchar V)
- //函數(shù)功能:將待顯示的數(shù)據(jù)寫入鎖存器中并顯示
- //參數(shù):*a:待顯示數(shù)據(jù)-,V循環(huán)此次數(shù)(為何循環(huán)?經(jīng)驗證只是增加顯示時間)
- //返回值:無
- ------------------------------------------------*/
-
- void zhen(uchar *a,uchar v)
- {
- char layer;
- while(v--)//?為何需要循環(huán)???增加顯示時間?√ 就是這樣 。。
- {
-
- for(layer=0;layer<8;layer++) //將每層8列數(shù)碼發(fā)送 循環(huán)8次8層數(shù)據(jù)依次發(fā)送
- { /* 數(shù)組的每一位是一列數(shù)據(jù)*/
- sendbyte1(~a[layer*8+7],~a[layer*8+6],~a[layer*8+5],~a[layer*8+4]);
- sendbyte1(~a[layer*8+3],~a[layer*8+2],~a[layer*8+1],~a[layer*8+0]);
- //和直接調(diào)顯示函數(shù)是一個道理
- cheng=0x01<<layer;
- DS2 =~cheng&0x01; //發(fā)送最低位
- ST_CP=1;
- ST_CP=0;
- SH_CP2 = 1;
- SH_CP2 = 0; //移位寄存器移位
- ST_CP2=1;
- ST_CP2=0;
- delay(300);
- }
-
- }
- }
- void clc()//全局清屏
- {
- unsigned char k;
- for(k=0;k<64;k++)
- { //d=0xff;
-
- DS = 0; //發(fā)送最低位
- SH_CP = 1;
- SH_CP = 0; //移位寄存器移位
- // d = d<<1; //數(shù)據(jù)移位f
- }
- ST_CP=1;
- ST_CP=0;
- }
復(fù)制代碼
所有資料51hei提供下載:
光立方修改.rar
(650.29 KB, 下載次數(shù): 14)
2018-11-14 11:53 上傳
點擊文件名下載附件
|
|