看來你的例子確實是方波
如果write to device low mode(t0)
將輸出引腳低,write to device low mode(t1)
高或後退,然後週期是睡覺+一段時間的總和設立GPIO狀態。不知道爲什麼你有GPIO集線內,而不是在睡覺時間...(可能是一些平臺依賴?)
要到正弦波
使用DAC或PWM + RC濾波器帶有一些預先計算的振幅表,其中索引週期性地增加。
BYTE sintab[32]={ 128,...,255,...,128,...,0,....,127 };
編碼:128
爲零,255
是+1
和0
是-1
;現在只需添加一些指標:
int ix=0'
在一段時間
一次(在某些計時器也許)增加它,並設定輸出新的價值:
ix=(ix+1)&31;
這一點,31
正義事業壽週期指標如果結束到達,則從頭再次開始(sintab必須是2的尺寸冪)。週期是定時器頻率/ sintab大小
[註釋]
可以修改此給你的目的例如使sintab[][]
一個二維陣列,其中第一索引意味着振幅和第二個是如ix
現在。在舊平臺(MCU的),你可以直接編碼PWM序列sintab
末等等...
您可以預先計算這樣的sintab
值:
sintab[ix]=128.0+127.0*sin(float(2.0*M_PI*ix)/32.0);
或者如果你的平臺支持速度不夠快sin
你可以使用上面的行沒有直接的實際陣列...
[EDIT1]
對於sinwave
您只能使用0/1
狀態。如果你需要模擬輸出和:
你有DAC(數模轉換器)
然後發送實際的振幅像dac write sintab[ix];
,將輸出引腳上產生的模擬電壓適合你。
您沒有任何預備DAC的使用PWM脈寬調製代替
這是一個老同學的辦法來避免DAC的需要,仍然有從數字引腳模擬輸出。它的工作原理是這樣的:
的輸出值是每個時間塊,所以你產生方波信號
- 比1的累積能量/電壓:1表示半週期是H,其餘大號
- 比2:1表示的週期的2/3是H,其餘大號
的時間越多,輸出爲H越大輸出值。這仍然是數字輸出,但如果連接任何非線性器件(如電容或線圈),那麼energy inertia
將導致H電壓降至一定程度,具體取決於方波比。最常見的是RC filter(R is serial and C平行於地面)。如果你想驅動一些線圈(電機),那麼你不需要過濾器。這種使用通常會產生高音調聲音(PWM頻率)經常聽到附近的機械...
的PWM頻率必須足夠高(當時sinwave頻率高出許多倍)
爲PWM與振幅和頻率設定的某些代碼:
const int timer_T=1; // used timer interval [ms]
const int PWM_max=10; // PWM max amplitude+1
int PWM_s=0; // PWM actual step
int PWM_t=0; // PWM actual time
int PWM_a=3; // PWM amplitude <0,PWM_ratio_max)
int PWM_T=200; // PWM period [ms]
void OnTimer()
{
int PWM_T0=PWM_T/PWM_max; // PWM step period must be >=1 !!!
PWM_t+=timer_T;
if (PWM_t>=PWM_T0)
{
if (PWM_s<=pwm_a) gpio set x; else gpio clear x;
PWM_s++; if (PWM_s>=PWM_max) PWM_s=0;
PWM_t-=PWM_T0;
}
}
嗯看來你正在編寫用於USB的SW來減少GPIO,所以這不是直接用於MCU的代碼,而是用於PC?而是通過一些驅動程序將數據發送到USB板。你應該添加一些關於它的信息,甚至一個retag將是一個好主意(如果可能,將設備名稱添加到標籤中)。所以現在我不確定我的答案是否適用於此(可能存在計時問題)是設備同步IO端口還是異步的(您是否設置了IO應該切換或讀取的時間或者當您發送命令時,那麼它是執行+粗糙的一些延遲?) – Spektre