|
發(fā)布時間: 2018-1-15 09:56
正文摘要:STC15的ADC結(jié)果控制PWM輸出,關(guān)系曲線如下,請問各位大神,如何建立兩者的關(guān)系,用關(guān)系式的話用什么樣的關(guān)系式運行速度會快一些,謝謝! |
| 我這陣子也在琢磨PWM頻率怎么等于adc轉(zhuǎn)化結(jié)果,我用的stc8,PWM八位,ADC12位 |
村風(fēng) 發(fā)表于 2018-1-18 12:52 /*********************主函數(shù)**************************/ void main() { ADC_init(); //ADC初始化 PWM_init(); //PWM初始化 while(1) { ADC_Value(); //ADC結(jié)果賦值 LED_display(); //led顯示 Update_PWM(); //PWM輸出 } } /****************************************************/ /************************ADC初始化函數(shù)*********************/ void ADC_init() { P1M1=0x20; P1M0=0; //I/O口模式為P1.5僅為輸入(高阻),作為A/D使用,P1其他口為準雙向 //P1.1為準雙向口,作為PWM使用 P1ASF=0x20; //設(shè)置P1.5端口為模擬輸入 CLK_DIV=0x00; // MCK0_S1=0, MCK0_S1=0 : 主時鐘不對外輸出時鐘 //ADRJ=0 :10位A/D轉(zhuǎn)換結(jié)果的高8位存放于ADC_RES中,低2位存放于ADC_RESL的低2位中; //Tx_Rx=0 :串口1為正常工作方式 //CLKS2=0 , CLKS1=0 , CLKS0=0 :主時鐘頻率/1,不分頻 ADC_RES = 0; //清除之前ADC結(jié)果 ADC_RESL = 0; //清除之前ADC結(jié)果 ADC_CONTR = ADC_POWER | ADC_SPEEDLL; //ADC電源打開; //轉(zhuǎn)換速度:540個時鐘周期 delay(2); //延時,等待ADC_CONTR設(shè)置完成 } /********************************************************/ /******************獲取ADC結(jié)果**********************/ uchar Get_ADC_result() { uchar ch = 5; //模擬輸入通道號5(P1.5) ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START; //ADC電源打開;轉(zhuǎn)換速度:540個時鐘周期 //模擬輸入通道P1.5;ADC開始 _nop_(); _nop_(); _nop_(); _nop_(); //等待ADC_CONTR設(shè)置完成 while(!(ADC_CONTR&ADC_FLAG)); //等待ADC結(jié)束標志位置1 ADC_CONTR &= ~ADC_FLAG; //關(guān)閉ADC return ADC_RES; //返回ADC結(jié)果 } /**************************************************/ /*******************ADC結(jié)果賦值*******************/ void ADC_Value() { adc = Get_ADC_result(); //ADC結(jié)果賦值 } /****************************************************/ /******************PWM初始化***********************/ void PWM_init() { ACC = P_SW1; ACC &= ~( CCP_S0 | CCP_S1 ); //將P_SW1的運算結(jié)果放入累加器 P_SW1 = ACC; //CCP在(P1.2/ECI,P1.1/CCP0,P1.0/CCP1,P3.7/CCP2) CCON = 0x00; //PCA定時器停止運行, //PCA計數(shù)器溢出標志位CF清零, //模塊中斷標志位清零 CMOD = 0x02; //空閑模式PCA計數(shù)器繼續(xù)工作 //PCA計數(shù)器時鐘源:系統(tǒng)時鐘頻率SYSclk/2 //禁止PCA計數(shù)器中斷使能(計數(shù)器CCON中CF位) PCA_PWM0 = 0x00; //PCA模塊0工作在8位PWM } /**************************************************/ /********************PCA計數(shù)器復(fù)位***********************/ void PCA_reset() { CL = 0x00; CH = 0x00; //重置PCA計數(shù)器 } /**************************************************/ /*********************PWM更新**********************/ void Update_PWM() { if(adc <= 11) { //PWM0輸出占空比(100H-CCAP0L)/100H) PCA_reset(); //PCA計數(shù)器復(fù)位 CCAP0H = CCAP0L = 17; //PWM0輸出占空比(100H-CCAP0L)/100H) CCAPM0 = 0x42; //PCA比較/捕獲寄存器模塊0(P1.1)允許比較器功能 //工作在PWM模式 CR = 1; //PCA計數(shù)器開始運行 } if(adc > 11 && adc <= 22) // { PCA_reset(); //PCA計數(shù)器復(fù)位 CCAP0H = CCAP0L = 9.6 * adc - 54; // CCAPM0 = 0x42; CR = 1; } if(adc > 22 && adc <= 35) { PCA_reset(); //PCA計數(shù)器復(fù)位 CCAP0H = CCAP0L = 1.19 * adc + 132; // CCAPM0 = 0x42; CR = 1; } if(adc > 35 && adc <= 68) { PCA_reset(); //PCA計數(shù)器復(fù)位 CCAP0H = CCAP0L = 0.33 * adc + 163; // CCAPM0 = 0x42; CR = 1; } if(adc > 68 && adc <= 108) { PCA_reset(); //PCA計數(shù)器復(fù)位 CCAP0H = CCAP0L = 0.106 * adc + 178.6; // CCAPM0 = 0x42; CR = 1; } if(adc > 108) { PCA_reset(); //PCA計數(shù)器復(fù)位 CCAP0H = CCAP0L = 165; // CCAPM0 = 0x42; CR = 1; } } /*****************************************************/ 這是我寫的程序,求幫我看一下 |
村風(fēng) 發(fā)表于 2018-1-18 12:52 按照你說的做的分段的直線方程式輸出大致上吻合,但是一直存在一個問題,就是在中間有幾個電壓點不穩(wěn)定,會有來回跳動的現(xiàn)象,是不是我設(shè)置的PWM頻率不對,還是可能的其他原因。像這樣 PWM應(yīng)該用多少頻率,我用的是系統(tǒng)時鐘頻率SYSclk/2,8位的PWM。 |
chenshui7601 發(fā)表于 2018-1-17 11:22 你這個本身就是非線性的,ADC和PWM本身也不是完全的非線性,要做到這個曲線,說明在某段區(qū)間的增量不同,通過軟件參數(shù)分段調(diào)節(jié)就可以達到所需要求,另外如果用積分電路去平滑PWM,還要考慮元器件本身的惰性和電壓電流慣性,遲滯性問題,我說的只是一種方法,僅供參考。 |
村風(fēng) 發(fā)表于 2018-1-15 12:35 因為AD采樣的值直接賦給PWM輸出的電壓值跟需要的不一致,滿足上面的曲線關(guān)系,電壓才能滿足需要。 |
| 你的問題已經(jīng)給你做出了答案,因為ADC一般采樣的是8位或者10位,PWM通常8位也可以做成16位,就拿8位PWM和8位AD轉(zhuǎn)換結(jié)果而言,直接把AD采樣值賦給PWM脈寬控制定時器值就OK了。 |
| 參與人數(shù) 1 | 黑幣 +50 | 收起 理由 |
|---|---|---|
|
| + 50 | 回帖助人的獎勵! |
Powered by 單片機教程網(wǎng)