|
|||||||||||
| 技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng) 驅(qū)動(dòng)編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機(jī) | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計(jì) | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe |
用C寫單片機(jī)程序是否每個(gè)函數(shù)都可以模塊化(獨(dú)立性)? |
| 作者:fzj 欄目:單片機(jī) |
為了使程序可讀性及可移植性加強(qiáng),通常需要將函數(shù)進(jìn)行模塊化設(shè)計(jì),即函數(shù)與函數(shù)之間沒有直接的聯(lián)系,而是間接的關(guān)聯(lián),也就是函數(shù)與函數(shù)之間的調(diào)用是通過實(shí)參調(diào)用形參的方式,確實(shí)是好方法,程序中盡量少用全局變量而用局部變量,使程序的移植性得到加強(qiáng),但是作為實(shí)參調(diào)用形參的方式,想聽聽大家的高見,如果我在某個(gè)函數(shù)中需要處理4個(gè)變量,而這4個(gè)變量的值都要返回到主調(diào)函數(shù)中,是否可以利用實(shí)參調(diào)用形參的方式?或者有無其他更好的方法使該函數(shù)具有相對(duì)的獨(dú)立性.打個(gè)比方以下是個(gè)時(shí)間處理函數(shù),想將其優(yōu)化為獨(dú)立函數(shù),可否有更好的方法,可否用實(shí)參調(diào)用形參的方式?謝謝大家! void sjadd_s (void) { if (++s1>9) { s1=0; if (++s2>5) { s2=0; if (++s3>9) { s3=0; if (++s4>9) { s1=s2=s3=s4=0; }}}} } |
| 2樓: | >>參與討論 |
| 作者: xf.zhu 于 2006/1/5 15:04:00 發(fā)布:
該用全局變量的地方要大膽的用! 編譯器對(duì)局部變量可以優(yōu)化,從而提高RAM空間使用效率 |
|
| 3樓: | >>參與討論 |
| 作者: eeproom 于 2006/1/6 8:59:00 發(fā)布:
如果你的攻擊值足夠,可以構(gòu)建跨MCU的C |
|
| 4樓: | >>參與討論 |
| 作者: FZJ 于 2006/1/8 12:28:00 發(fā)布:
還沒有理解形參實(shí)參具體概念,再幫我看看,謝謝! unsigned CHAR s1,s2,s3,s4; void sjadd (a,b,c,d) unsigned CHAR a,b,c,d; { if (++a>9) { a=0; if (++b>5) { b=0; if (++c>9) { c=0; if (++d>9) { a=b=c=d=0; }}}} } void main () { sjadd (s1,s2,s3,s4); //a,b,c,d是形參,s1,s2,s3,s4是實(shí)參,想調(diào)用sjadd(....)函數(shù)來改變S1-S4的值,我這樣寫不知哪里錯(cuò)了,請(qǐng)幫忙看看,謝謝了! } |
|
| 5樓: | >>參與討論 |
| 作者: computer00 于 2006/1/8 12:57:00 發(fā)布:
這樣調(diào)用是通過值傳遞的。所以是不能改變s1-s4的值的 像你這樣,在調(diào)用時(shí),只是將s1-s4的值傳遞給了函數(shù),在函數(shù)運(yùn)行過程中,是不會(huì)修改這些變量的值的。 如果要改變他們的值,有兩種方法: 1.直接在函數(shù)里使用全局變量。 如: void sjadd(void) { s1=1; } 2.使用地址傳遞。即使用指針。 如: void sjadd(unsigned CHAR *a) { *a=1; } unsigned CHAR s1; void main(void) { sjadd((unsigned CHAR *)&s1); } |
|
| 6樓: | >>參與討論 |
| 作者: ferry 于 2006/1/8 12:59:00 發(fā)布:
實(shí)參的值沒有改變 調(diào)用前實(shí)參必須有確定的值,調(diào)用函數(shù)時(shí),給形參分配存儲(chǔ)單元,將實(shí)參的值傳給形參,調(diào)用結(jié)束,形參單元被釋放,實(shí)參單元仍是原值。因此子程序中應(yīng)把改變的形參值保存在全局臨時(shí)變量中。 |
|
| 7樓: | >>參與討論 |
| 作者: FZJ 于 2006/1/8 14:16:00 發(fā)布:
謝謝樓上的兩位,想問.... 電腦00:您好久聞您的大名想請(qǐng)教您說的第2種方法 2.使用地址傳遞。即使用指針。 如: void sjadd(unsigned CHAR *a) { *a=1; } unsigned CHAR s1; void main(void) { sjadd((unsigned CHAR *)&s1); //前面已經(jīng)定義變量類型為何這里還要聲明?可以不寫嗎? } //我要完成4個(gè)變量的調(diào)用怎么辦可以這樣調(diào)用么: unsigned CHAR s1,s2,s3,s4; void sjadd (a,b,c,d) unsigned CHAR *a,*b,*c,*d; { if (++a>9) { a=0; if (++b>5) { b=0; if (++c>9) { c=0; if (++d>9) { a=b=c=d=0; }}}} } void main () { sjadd ((unsigned CHAR *)&s1,(unsigned CHAR *)&s2,(unsigned CHAR *)&s3,(unsigned CHAR *)&s4); } |
|
| 8樓: | >>參與討論 |
| 作者: javie 于 2006/1/8 14:20:00 發(fā)布:
哎,慚愧啊,俺對(duì)C連菜鳥都不算 |
|
| 9樓: | >>參與討論 |
| 作者: FZJ 于 2006/1/8 14:25:00 發(fā)布:
謝謝 ferry!想問.. 子程序中應(yīng)把改變的形參值保存在全局臨時(shí)變量中。 您的意思是不是再定義4個(gè)全局變量然后在調(diào)用函數(shù)結(jié)束后將形參值備份?在主調(diào)函數(shù)完后將其釋放給實(shí)參?謝謝! unsigned CHAR a_temp,b_temp,c_temp,d_temp; void sjadd (void) { unsigned CHAR a,b,c,d; if (++a>9) { a=0; if (++b>5) { b=0; if (++c>9) { c=0; if (++d>9) { a=b=c=d=0; }}}} a_temp=a;b_temp=b;c_temp=c;d_temp=d; //備份 } void main () { sjadd (); s1=a_temp;s2=b_temp;s3=c_temp;s4=d_temp;//釋放 } |
|
| 10樓: | >>參與討論 |
| 作者: computer00 于 2006/1/8 14:27:00 發(fā)布:
我那個(gè)是強(qiáng)制類型轉(zhuǎn)換。在這里可以不寫 我更喜歡這樣: unsigned CHAR s1,s2,s3,s4; void sjadd(unsigned CHAR *a,unsigned CHAR *b,unsigned CHAR *c,unsigned CHAR *d) { if(++(*a)>9) //注意指針訪問時(shí),前面要加* { *a=0; if(++(*b)>5) { *b=0; if(++(*c)>9) { *c=0; if(++(*d)>9) { *a=*b=*c=*d=0; } } } } } void main(void) { sjadd (&s1,&s2,&s3,&s4); //&是取地址符,將這些變量的地址傳遞給函數(shù)。函數(shù)收到地址后,把這些地址里面值改變了。 } |
|
| 11樓: | >>參與討論 |
| 作者: FZJ 于 2006/1/8 14:53:00 發(fā)布:
多謝電腦00高手指導(dǎo) 我試了下,果然OK呵呵,謝謝,不過在C中用指針很會(huì)占用RAM,上面這句代碼編譯后要10 bytes ,為什么呀?我想最多8 bytes足夠了,想不通2個(gè)RAM跑那里去了. |
|
| 12樓: | >>參與討論 |
| 作者: FZJ 于 2006/1/8 15:04:00 發(fā)布:
又看了下發(fā)現(xiàn)指針變量不是unsigned CHAR型, 為什么呀??電腦00高手,麻煩您再看看 指針變量怎么變成16位長度的int型了?? 看了您寫的,好規(guī)范!(*a)這個(gè)括號(hào)可以去掉但為了程序的可讀性還是別丟掉對(duì)不,向您好好學(xué)習(xí)!謝謝! |
|
| 13樓: | >>參與討論 |
| 作者: computer00 于 2006/1/8 15:31:00 發(fā)布:
你是什么編譯器?如果是keil的,可以加idata關(guān)鍵詞修飾 void sjadd(unsigned CHAR idata *a,unsigned CHAR idata *b,unsigned CHAR idata *c,unsigned CHAR idata *d) { 前提是你的變量保存在內(nèi)部RAM中。因?yàn)閮?nèi)部的RAM的才使用8位的指針(外部RAM區(qū)的pdata也是使用8位的指針)。 |
|
| 14樓: | >>參與討論 |
| 作者: FZJ 于 2006/1/8 15:55:00 發(fā)布:
我是HI-TECH的PICC8.05 編譯PIC單片機(jī)的.程序在軟件調(diào)試中發(fā)現(xiàn)*a顯示的是0X1307具體什么意思不明白,也不知道她怎么會(huì)變成16BIT,而且不變化,一開始我還以為是個(gè)地址值可是一想不可能,沒有這個(gè)地址. |
|
| 15樓: | >>參與討論 |
| 作者: zhouyh 于 2006/1/8 18:11:00 發(fā)布:
好貼呀! |
|
| 16樓: | >>參與討論 |
| 作者: su_mj000 于 2006/1/9 5:27:00 發(fā)布:
多個(gè)指針參數(shù)的傳遞會(huì)消耗很多代碼 多個(gè)指針參數(shù)的傳遞會(huì)消耗很多代碼,也影響速度.如有可能,最好使用單個(gè) 數(shù)組指針或結(jié)構(gòu)指針.當(dāng)然,如果使用全局變量傳遞參數(shù)會(huì)快得多,但會(huì) 破壞程序結(jié)構(gòu),影響可移植性和可讀性. typedef struct { CHAR memA; CHAR memB; CHAR memC; CHAR memD; } data_struct; void sjadd (data_struct *sp) { if ( ++(sp->memA) > 9 ) { sp->memA=0; if ( ++(sp->memB)>5 ) { sp->memB=0; if (++(sp->memC)>9) { sp->memC=0; if (++(sp->memD)>9) { sp->memD = 0; }}}} } void main () { data_struct my_data; ... sjadd (&my_data); } |
|
| 17樓: | >>參與討論 |
| 作者: 農(nóng)民講習(xí)所 于 2006/1/9 9:01:00 發(fā)布:
定義一個(gè)BCD加法基本函數(shù),這樣才規(guī)范點(diǎn) unsigned CHAR BCD_Adding( unsigned CHAR *pBCD, unsigned CHAR mMin, unsigned CHAR mMax) { if( ++(*pBCD) > mMax ){ *pBCD = mMin; return 1; //產(chǎn)生進(jìn)位 } else return 0; } |
|
| 18樓: | >>參與討論 |
| 作者: fzj 于 2006/1/9 10:58:00 發(fā)布:
to:su_mj000 你這樣處理能保證主調(diào)函數(shù)在返回后4個(gè)變量的值有加1或者進(jìn)位的操作么? 我的程序是在主調(diào)函數(shù)中的4個(gè)變量值通過被調(diào)函數(shù)后返回4個(gè)變量值,確切的說是修改4個(gè)變量值,所以這4個(gè)變量還必須用全局變量,當(dāng)然為了調(diào)用的RAM不單單是這4個(gè),否者也不要做處理函數(shù)了,我的文字表達(dá)能力不行,不知你能否看明白,謝謝您的熱心! |
|
| 19樓: | >>參與討論 |
| 作者: fzj 于 2006/1/9 11:12:00 發(fā)布:
TO:農(nóng)民講習(xí)所 定義一個(gè)BCD加法基本函數(shù),這樣才規(guī)范點(diǎn)? 不太明白您的意思,您說一個(gè)BCD函數(shù)我想不夠,因?yàn)镸AX有2個(gè)值。 unsigned CHAR BCD_Adding( unsigned CHAR *pBCD, unsigned CHAR mMin, unsigned CHAR mMax)//為什么MAX和MIN也要定義為變量呢?? { if( ++(*pBCD) > mMax ){ *pBCD = mMin; return 1; //產(chǎn)生進(jìn)位 } else return 0; } // 直接這樣可以不? unsigned CHAR BCD_Adding( unsigned CHAR *pBCD)//MAX=9和MIN=0 { if( ++(*pBCD) > 9 ){ *pBCD = 0; return 1; //根據(jù)進(jìn)位有否 在主調(diào)函數(shù)中判斷 } else return 0; } 謝謝高人! |
|
| 20樓: | >>參與討論 |
| 作者: computer00 于 2006/1/9 12:14:00 發(fā)布:
建議樓主挑個(gè)時(shí)間,好好的把C語言的教材讀兩遍。 應(yīng)該就可以找到答案了。 |
|
| 21樓: | >>參與討論 |
| 作者: FZJ 于 2006/1/10 9:44:00 發(fā)布:
呵呵,我有點(diǎn)理解農(nóng)民講習(xí)所的話了 由于MMAX不是單單一個(gè)固定的常量,所以定義一個(gè)長度為8位的局部變量(確切的講應(yīng)該是個(gè)8位的形式參數(shù))在主函數(shù)調(diào)用是可以任意靈活修改,當(dāng)然作為最小的數(shù)也是一樣,定義一個(gè)BCD加法函數(shù)和減法函數(shù),4個(gè)變量在主調(diào)函數(shù)中分開調(diào)用,通過判斷返回值來決定是否需要進(jìn)位或者借位,但是作為我這個(gè)程序中似乎可以忽略一個(gè)MMIN變量,因?yàn)樗闹抵挥幸粋(gè)“0”,不知我理解是否正確? 電腦圈圈您在嗎?幫小弟打分打分?謝謝拉! |
|
| 22樓: | >>參與討論 |
| 作者: FZJ 于 2006/1/10 16:01:00 發(fā)布:
給大家看看高手寫的C(EEPROM讀寫) 無論是書寫格式上還是變量分配上都考慮周到,另外在硬件上的沖突也考慮周到,高人呀,俺佩服!做為初學(xué)C的人可以借鑒。 #include "pic.h" #define nop() asm("nop") #define SCL RA4 #define SDA RA5 #define SCL_DIR TRISA4 #define SDA_DIR TRISA5 #define SCL_OUTPUT SCL_DIR=0 #define SCL_HIGH() SCL=1 #define SCL_LOW() SCL=0 #define SDA_HIGH() SDA_DIR=1 #define SDA_LOW() SDA=0; SDA_DIR=0 //以上本來是個(gè)INCLUDE文件,為了分析,我把它分解了! extern void randomRead(CHAR addr,CHAR counter,CHAR *p); extern void writeByteIIC(CHAR addr, CHAR counter,CHAR *p); void BSTART(); void BSTART() // IIC start { SCL_LOW(); ADCON1=0x07; // set PORTA as DIGITAL PORT SDA_HIGH(); SCL_HIGH(); SCL_DIR=0; nop(); nop(); SDA_LOW(); nop(); nop(); SCL_LOW(); } void BSTOP() { SDA_LOW(); SCL_HIGH(); nop(); nop(); SDA_HIGH(); nop(); nop(); nop(); SCL_LOW(); } // SINGLE bit receive bit BITIN(void) { static bit DQ; SDA_HIGH(); //SDA as input SCL_HIGH(); nop(); nop(); DQ=SDA; SCL_LOW(); return(DQ); } // receive one byte from IIC DEVICE,OUTPUT:VALUE unsigned CHAR byteReceive(void) { unsigned CHAR i,VALUE; for(i=8;i!=0;i--) { VALUE<<=1; if(BITIN()) VALUE|=0x01; } return(VALUE); } // SINGLE bit transmit void BITOUT(unsigned CHAR bitval) { if(bitval) {SDA_HIGH();} else {SDA_LOW();} SCL_HIGH(); nop(); nop(); nop(); SCL_LOW(); } // signle byte transmit void byteTrans(unsigned CHAR val) { CHAR i; for (i=8;i!=0;i--) { val<<=1; BITOUT(CARRY); } i=BITIN(); // recevie ACK bit } void randomRead(CHAR addr,CHAR counter,CHAR *p) { BSTART(); byteTrans(0xa0); // slave addr write byteTrans(addr); BSTART(); byteTrans(0xa1); for(;counter!=0;counter--) { *p=byteReceive(); p++; if(counter>1)   |
|
|
|
| 免費(fèi)注冊(cè)為維庫電子開發(fā)網(wǎng)會(huì)員,參與電子工程師社區(qū)討論,點(diǎn)此進(jìn)入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號(hào) |