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

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

一個程序順序引發的血案(關于軟件PWM編程)

作者:huqin   來源:本站原創   點擊數:  更新時間:2014年04月15日   【字體:

四段不同順序的程序會有如此巨大的差別!

程序段一:

__interrupt  interrupt_isr(void)

{      

         if(FTC0IRQ==1)                                     //0.02ms

         {

                   FTC0IRQ  = 0;          

                   if(PWM_Flag==0)

                   {      

                            num++;

                            sum++;                                                 

                            if(sum >= 100)                    //2ms

                            {

                                     num=0;

                                     sum=0;

                                     INPUT1=1;//低電平輸出結束,引腳輸出高電平

                                     INPUT2=1;

                            }

                            if(num >= work)               

                            {

                                     INPUT1=0;//高電平輸出結束,引腳輸出低電平

                                     INPUT2=0;

                            }

                            Tim_1S++;

                            if(Tim_1S==50000)

                            {

                                     PWM_Flag=1;

                            }               

                   }

                   if(PWM_Flag==1)

                   {      

                            INPUT1=0;//高電平輸出結束,引腳輸出低電平

                            INPUT2=0;               

                            Tim_1S--;

                            if(Tim_1S==0)

                            {

                                     PWM_Flag=0;

                                     num=0;

                                     sum=0;

                            }               

                   }                                                                                                                      

         }

}

顯然這個程序的功能是引腳輸出一個可調的PWM波形,然后輸出一個低電平的波形,PWM的波形和這個低電平的波形持續的時間都是1S鐘,程序段一是正確的程序.

下面分析下面的三個程序的問題:

程序段二:

__interrupt  interrupt_isr(void)

{      

         if(FTC0IRQ==1)                                     //0.02ms

         {

                   FTC0IRQ  = 0;          

                   if(PWM_Flag==0)

                   {                                                              

                            if(++sum >= 100)               //2ms

                            {

                                     num=0;

                                     sum=0;

                                     INPUT1=1;//低電平輸出結束,引腳輸出高電平

                                     INPUT2=1;

                            }

                            if(++num >= work)           

                            {               

                                     INPUT1=0;//高電平輸出結束,引腳輸出低電平

                                     INPUT2=0;

                            }

                            Tim_1S++;

                            if(Tim_1S==50000)

                            {

                                     PWM_Flag=1;

                            }               

                   }

                   if(PWM_Flag==1)

                   {      

                            INPUT1=0;//高電平輸出結束,引腳輸出低電平

                            INPUT2=0;               

                            Tim_1S--;

                            if(Tim_1S==0)

                            {

                                     PWM_Flag=0;

                                     num=0;

                                     sum=0;

                            }               

                   }                                                                                                                      

         }

}

 

程序段二:

現在假設系統初始化,sum和num都是0,現在假設work=20,系統初始化后開始疊加運算,等到num變為20后會有高電平輸出結束,引腳輸出低電平,占空比為20%,系統正常運行,但等到sum加到100后sum,num會置為0,然后num會加1變為1,此時下一個周期到來了,但是初始化卻和第一個周期不一樣了,這時num總會比sum大1,也就是最后輸出的占空比總是比設定的值會小1,比如設置work值為100,那么從起始狀態開始分析,起始狀態下num和sum都是0,等sum變為100的時候會先將num置為0,然后num的值會做想應的加1然后下一個周期來了,sum和num有了不同的初始值sum的初始值為0而num的初始值卻變為1,這樣話,時過境遷,num會首先變為100,這時sum才是99,這時就會了出現一個短暫的低電平,這個低電平的持續時間剛好是一個周期,這樣就和我們的初衷相違背了,這時輸出的占空比不是100%,而是99%.同樣的道理這樣的問題不僅會出現有占空比為100%的情況,比如此里的占空比是設置的是20%,那么從初始狀態到sum變為20,然后緊接著num又會加1變為1,那么從下一個周期開始兩個數據又會出現不同步的情況,從而直接導致下一次等到sum變為99的候,num己經是100了,從而又直接導致下一個周期的起始狀態又變成了sum=0,而num=1.周而復始,從而真正得到地占空比變為19%.

 

程序段三:

__interrupt  interrupt_isr(void)

{      

         if(FTC0IRQ==1)                                     //0.02ms

         {

                   FTC0IRQ  = 0;          

                   if(PWM_Flag==0)

                   {      

                            num++;

                            sum++;                                                                    

                            if(num >= work)               

                            {               

                                     INPUT1=0;//高電平輸出結束,引腳輸出低電平

                                     INPUT2=0;

                            }

                            if(sum >= 100)           //2ms

                            {

                                     num=0;

                                     sum=0;

                                     INPUT1=1;//低電平輸出結束,引腳輸出高電平

                                     INPUT2=1;

                            }

                            Tim_1S++;

                            if(Tim_1S==50000)

                            {

                                     PWM_Flag=1;

                            }               

                   }

                   if(PWM_Flag==1)

                   {      

                            INPUT1=0;//高電平輸出結束,引腳輸出低電平

                            INPUT2=0;               

                            Tim_1S--;

                            if(Tim_1S==0)

                            {

                                     PWM_Flag=0;

                                     num=0;

                                     sum=0;

                            }               

                   }                                                                                                                      

         }

}

關于第三種情況:

第三種情況倒不存在num和sum不同步的問題,但是有一個小問題就是當work是100

的時候num會首先加到100輸出一個低電平,而這里的期望占空比是100%,也就是沒這里會有一個非常短暫的低電平,用示波器也是發現不了的,因為示波器的分辨能力還是沒有單片機執行指令的速度快,所以說這個誤差可以忽略不計,不過在邏輯是還是不完美的.

程序段四:

__interrupt  interrupt_isr(void)

{      

         if(FTC0IRQ==1)                                     //0.02ms

         {

                   FTC0IRQ  = 0;          

                   if(PWM_Flag==0)

                   {                                                                       

                            if(++num >= work)           

                            {               

                                     INPUT1=0;//高電平輸出結束,引腳輸出低電平

                                     INPUT2=0;

                            }

                            if(++sum >= 100)               //2ms

                            {

                                     num=0;

                                     sum=0;

                                     INPUT1=1;//低電平輸出結束,引腳輸出高電平

                                     INPUT2=1;

                            }

                            Tim_1S++;

                            if(Tim_1S==50000)

                            {

                                     PWM_Flag=1;

                            }               

                   }

                   if(PWM_Flag==1)

                   {      

                            INPUT1=0;//高電平輸出結束,引腳輸出低電平

                            INPUT2=0;               

                            Tim_1S--;

                            if(Tim_1S==0)

                            {

                                     PWM_Flag=0;

                                     num=0;

                                     sum=0;

                            }               

                   }                                                                                                                      

         }

}

關于第四種情況:

         第四種情況和第三種情況累似,也不存在num和sum不同步的問題,同樣的問題也會出現一個非常短暫的低電平,同樣存在邏輯上的不完美.可以發現這兩個程序都有一個共同的特點,就是num=0;和sum=0;都在程序的后面,就是這么一個小小的程序順序上的差別,都能直接導致num和sum的同步和不同步.這個問題雖然不是很嚴重,也就是說這個問題只會出現在work=100;的時候.也就是在其他的情況下沒有這個問題.不過我還是不想讓他出現這個問題.

關于這個程序的改進

         上面的程序可以進行如下的改進,沒有必要使用兩個變量來分別對時間來進先計數,可以只用一個變量,這樣也可以將計數的不同步問題得到根本的上的解決,同時這個程序的PWM波的周期也不可調節,改進的程序應增加對PWM波形的調節能力,廢話不多話直接上程序.

__interrupt  interrupt_isr(void)

{

         if(FTC0IRQ==1)                                     //0.02ms

         {

                   FTC0IRQ  = 0;

                   if(PWM_Flag==0)                        //輸出PWM波形的狀態

                   {

                            num++;

                            if(num >= work)

                            {

                                     INPUT1=0;//高電平輸出結束,引腳輸出低電平

INPUT2=0;

                            }

                            if(num>=sum)//周期為sum

            {

                 num=0;//計數器清0,重新開始計數,

                 INPUT1=1;//高電平輸出結束,引腳輸出高電平

INPUT2=1;

            }

                            Tim_1S++;

                            if(Tim_1S==50000)

                            {

                                     PWM_Flag=1;

                            }

                   }

                   if(PWM_Flag==1)                        //輸出低電平波形的狀態

                   {

                            INPUT1=0;//高電平輸出結束,引腳輸出低電平

                            INPUT2=0;

                            Tim_1S--;

                            if(Tim_1S==0)

                            {

                                     PWM_Flag=0;

                                     num=0;

                                     sum=0;

                            }

                   }

         }

}

         這個改進版的程序輸入有兩個有效的參數,一個為work,一個為sum,sum用來控制PWM波形的周期,work用來控制PWM波形的占空比,簡單粗暴,異常性感.當然可以把這個程序移殖到應廣單片機上啊,這個是松瀚單片機的源程序,這個過程是很簡單的.

         總而言之,這個改進版的程序有以下三個方面的明顯提升:

1.      計數的變量由兩個變量變為了一個變量.

2.      而且原來的程序的PWM波的周期不可調,現在的程序的周期可調.

3.      實現了模塊化的編程,就像函數的模式,有兩個輸入參數,沒有輸出參數.
         還可以想一想如果用<=的方式能不能,構建一個完美的程序,這個問題有時間再想.先想到這里吧.這個問題有想過,會有一點小小的不完美.具體細節以后再說.

關閉窗口

相關文章

主站蜘蛛池模板: 91精品国产91久久久久青草 | 国产成人jvid在线播放 | 精品中文字幕在线观看 | 夜夜草 | 亚洲美女视频 | 中文字幕99| 日韩av在线一区二区 | 福利片在线看 | 中文字幕一区二区三区乱码在线 | 久久伊人青青草 | 国产黄色小视频 | 一区二区三区不卡视频 | 国产精品视频在线观看 | 日韩在线视频一区二区三区 | 在线视频一区二区 | 中文字幕视频在线免费 | 国产精品久久久久久久久久久久久 | 亚欧精品一区 | 国产三级在线观看播放 | 久久久片 | 91观看 | 久久午夜国产精品www忘忧草 | 久久天天| 日本亚洲一区 | 成人国产精品久久久 | 一区二区三区高清在线观看 | 天天av综合| 国产视频一区二区 | 精品久久久网站 | 天天操天天操 | 欧美日韩精品久久久免费观看 | 欧美一区二区网站 | 亚洲精品美女在线观看 | 男女午夜免费视频 | 久久国产精品免费一区二区三区 | 久久国产欧美日韩精品 | 久久久久9999亚洲精品 | 国产精品久久久99 | 色婷婷av一区二区三区软件 | 人人干人人看 | 不卡一二三区 |