在昨天的博文 信號轉換問題 | 模擬電路解決方式 中對於前天的 信號轉換的解題思路 進行了實物仿真。儘快其中做了些改進,但是在控制二倍頻的三角波的頻率、幅值、佔空比方面還是有很多的問題。主要表現在:
- 控制量之間的耦合,特別是頻率,佔空比對輸出信號幅值的影響;
- 頻率對於佔空比的影響雖然經過改進之後,還是會有部分的影響;
- 輸出心慌可失真,這主要是最後一級從方波到三角波轉換的過程中,對於信號的直流分量的變化與波形失真之間的關係;
- 最後一點,也是最重要的一點,就是電路非常複雜。
那麼,通過一個單片機是否可以完成同樣的功能呢。
下面是選用的STC單片機來實現相同的功能。
01設計電路1
1.實驗電路設計
▲ 實驗原理圖
▲ 實驗電路板
2.單片機固件設置
使用STC的ISP軟件對單片機進行硬件設置,設置IRC頻率爲35MHz。
▲ STC8G1K08單片機硬件設置
下載基礎程序之後的單片機開始能夠工作。
▲ 下載固件之後的單片機
02單片機程序設計2
1.設置PWM輸出
STC8G1K 單片機的PWM輸出可以有6,7,8,.10等不同的位數。在同樣的系統時鐘下,不同的位數對應的輸出PWM的頻率以及精度各不相同。
特別注意:需要在主程序中將PWM輸出端口設置爲推輓輸出模式。
在35MHz下,6bit的PWM頻率大約爲540kHz。下面是通過510歐姆和0.1uF的電容對輸出的PWM波形進行濾波,可以得到比較平滑的直流分量。
▲ 設置PWM輸出6BIT
如果設置爲8Bit,則輸出PWM的波形的頻率降低4倍,大約137kHz。通過10k歐姆、0.1uF的阻容濾波,所得到的直流分量可以看到有一些比較明顯的波動了。
▲ PWM輸出以及濾波後的直流信號 8BIT
2.設置比較器
設置比較器,比較器結果通過CMPOE輸出。
特別注意的是,需要明確在主程序中,將比較器的輸出通過 PM_PP設置爲推輓輸出。
#if CMP_EN
void SetCMPPort(unsigned char ucPort) {
if(ucPort == CMP_P3) {
ACC = P_SW2;
ACC &= ~CMPO_S;
P_SW2 = ACC;
} else if(ucPort == CMP_P4) {
ACC = P_SW2;
ACC &= ~CMPO_S;
ACC |= CMPO_S;
P_SW2 = ACC;
}
}
void CMPInit(void) {
CMPCR1 = 0x84; // CMPEN CMPIF PIE NIE PIS NIS CMPOE CMPRFESS
// CMPEN:0: Disable Comparator; 1:Enable
// CMPIF : Interrupt flag of comparator
// PIE : 1 Enable Up edge interrupt
// NIE : 1 Enable Down edge interrupt
// PIS : 0 : +=P3.7; 1:=ADC_CHS
CMPCR1 |= 0x2; // NIS : 0 : -=BandGap; 1 : P3.6
// COMPOE : 1 : Result =P3.4,P4.1
// Compare result.
CMPCR1 |= 0x30; // Enable Up and Down Interrupt.
CMPCR2 = 0x0; // INVCOMPO: 0 : Positive; 1 : Inverse output
// DISFLT: 0 : Enable 0.1us analog filter
// LCDTY: Digital Filter
}
▲ 比較器輸出
在比較器中斷中,測量半週期:
//------------------------------------------------------------------------------
#if CMP_INT_EN
void CMP_ISR(void) interrupt 21 {
CMPCR1 &= ~0x40; // Clear the interrupt flag
if(g_nSignalPeriodCount != g_nSignalPeriod) {
g_nSignalPeriod = g_nSignalPeriodCount;
if(g_nSignalPeriod > PWM_BUFFER) {
g_nSignalPeriod = PWM_BUFFER;
}
g_ucSignalPeriodInitFlag = 1;
}
g_nSignalPeriodCount = 0;
g_nSignalPWMBufferPoint = 0;
}
#endif // CMP_INT_EN
3. :初始化TImer0輸出
//------------------------------------------------------------------------------
void InitSignalPWMBuffer(void) {
unsigned int i;
unsigned int nUpPeriod, nDownPeriod;
unsigned long nMax;
if(g_nSignalPeriod > PWM_BUFFER)
g_nSignalPeriod = PWM_BUFFER;
g_ucSignalPeriodInitFlag = 0;
nMax = g_nSignalPeriod;
nMax *= g_ucSignalPWMDuty;
nMax /= 100;
nUpPeriod = (unsigned int)nMax;
nDownPeriod = g_nSignalPeriod - nUpPeriod;
nMax = PWM_MAX;
nMax = nMax * g_ucSignalPWMAmplitude;
nMax /= 0xff;
for(i = 0; i < nUpPeriod; i ++) {
g_ucSignalPWMBuffer[i] = (unsigned char)(i * nMax / nUpPeriod);
}
for(i = 0; i < nDownPeriod; i ++) {
g_ucSignalPWMBuffer[i + nUpPeriod] = (unsigned char)((nDownPeriod - i) * nMax / nDownPeriod);
}
}
▲ 測試輸出波形
▲ 佔空比的改變
▲ 改變幅值
03極限測試
- 三角波的佔空比可以從0~100%,分成100個等級進行調節;
- 三角波的幅值從0~256,分成256個等級進行調劑
- 三角波的頻率:5.556Hz
這是由於在單片機中進行波形數據區間長度爲:buffer =9000
PWM DA輸出是Timer0的中斷,時間間隔爲 ts=200us。
那麼,三角波的週期最長爲: buffer * ts = 0.18s。對應的頻率爲5.556Hz
▲ 頻率過低的時候出現的波形斷續
- 三角波的最大頻率: 250Hz
由於PWM DA輸出的時間間隔爲0.2ms,所以按照它它的20倍來估計三角波的最短週期爲4ms,對應的頻率爲250Hz。
下面是對應的三角波的頻率在300Hz是的波形,可以明顯看出三角波的臺階。
▲ 三角波在300Hz是的波形
04結論
通過前面的實驗,可以驗證,通過一個簡單的單片機的電路,便可以完成對應的波形轉換的功能。不僅簡化了設計,同時也提高的波形轉換的性能。
本文中所涉及到的硬軟件文件可以從以下鏈接下載: