會員登陸
帳號:

密碼:

記住我



忘記密碼?

現在註冊!
網站導航
最新下載
訪問統計 (自2012/5/3)


正在流覽:   1 名訪客





PIC12F1822 輸出sine wave
初級會員
註冊日期:
2009/12/01 10:06
所屬群組:
註冊會員
文章: 22
等級: 3; EXP: 41
HP : 0 / 60
MP : 7 / 1407
離線
下述為將網路上旋波+變頻的參考資料移動到PIC12F1822+MPLAB平台,功能為20Hz~4KHz旋波可調輸出。
參考連結:https://circuitsalad.com/2014/06/10/dd ... from-pic-microcontroller/

目前已能正常工作,本身能夠理解Microchip AN1523 lookup table原理,但主程式部分取sine table語法一直無法理解(紅字標註),想請各位前輩指教
CCPR1L = (sine[((char *)&PhaseAccum)[3]]) >> 2;

PhaseAccum = PhaseAccum + ((PhaseShift << 5) + 1);



**********************************************************
#include <pic12f1822.h>
//#include <htc.h>
//#pragma config OSC=internal RC clockout

#define ADCStart ADCON0.b1 = 1 //set this bit to begin ADC conversion
//////////////////////////////////////////////////////////////////////////////
void ConvertADC(void); // Initialize ADC module

// sine wave 8 bit resolution scaled to 90% max val//
const unsigned char sine[256] =
{131,132,135,137,140,143,146,149,152,155,157,160,163,166,168,171,
174,176,179,181,184,186,189,191,194,196,198,200,202,205,207,209,
211,212,214,216,218,219,221,223,224,226,227,228,229,231,232,233,
234,234,235,236,237,237,238,238,239,239,239,239,240,240,240,239,
239,239,239,238,238,237,237,236,236,235,234,233,232,231,230,229,
227,226,225,223,222,220,219,217,216,214,212,210,208,206,204,202,
200,198,196,194,192,189,187,185,182,180,177,175,173,170,167,165,
162,160,157,154,152,149,146,144,141,138,135,133,130,127,124,122,
119,116,113,111,108,105,103,100, 97, 95, 92, 89, 87, 84, 82, 79,
77, 74, 72, 69, 67, 64, 62, 60, 58, 55, 53, 51, 49, 47, 45, 43,
41, 39, 37, 36, 34, 32, 31, 29, 28, 26, 25, 24, 22, 21, 20, 19,
18, 17, 16, 15, 15, 14, 13, 13, 12, 12, 12, 11, 11, 11, 11, 11,
11, 11, 11, 12, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18, 19, 21,
22, 23, 24, 26, 27, 29, 30, 32, 33, 35, 37, 39, 41, 43, 45, 47,
49, 51, 53, 56, 58, 60, 63, 65, 68, 70, 73, 75, 78, 81, 83, 86,
89, 92, 94, 97, 100,103,106,108,111,114,117,120,123,126,129,130};


long PhaseAccum;
long PhaseShift;

void Init_Main()
{
OSCCON = 0b1111000; //8MHz clk //32Mhz pll
TRISA = 0b00011000;
T2CON = 0b00000100;// TMR2 ON, postscale 1:1, prescale 1:1
PR2 = (0x50);// sets PWM rate to approx 98.5KHz
CCP1CON = 0b00001111;//

PhaseShift = 0x00FFFFFF;//frequency values loaded into
ANSELA = 0b00010000; //select RA4 as A2D input 32Mhz clk
ADCON0 = 0b00001101; // configure ADC
ADCON1 = 0b00100000; // configure ADC
}

void main()
{
Init_Main();//configue part
while(1)
{
while(!PIR1bits.TMR2IF);

CCPR1L = (sine[((char *)&PhaseAccum)[3]]) >> 2;

PhaseAccum = PhaseAccum + ((PhaseShift << 5) + 1);

PIR1bits.TMR2IF = 0;

ADCON0bits.ADON=1;

while ( ADCON0bits.GO_nDONE);
((char *)&PhaseShift)[1] = ADRESL;
((char *)&PhaseShift)[2] = ADRESH;

}

10月13日 13:16:44
轉換PDF檔 列印


Re: PIC12F1822 輸出sine wave
資深會員
註冊日期:
2004/07/23 16:25
所屬群組:
註冊會員
文章: 1176
等級: 29; EXP: 94
HP : 0 / 723
MP : 392 / 28170
離線
程式寫的對或錯不管,單純看程式寫法

這是查表輸出 pwm ,有一點 pid 的概念~~

整個程序的做法就是

定時 adc,將抓取的10bit adc 取 前 5biT
PhaseAccum = PhaseAccum + ((PhaseShift << 5) + 1);


CCPR1L = (sine[((char *)&PhaseAccum)[3]]) >> 2;
這是將抓取到的 adc ,積分抓第三個 byte 做為 pwm 的選擇

因為 adc 的抓取『不穩定』,累積抓取多個,可以避免『瞬間』抓到大的值造成整個亂跳。

ex: PhaseAccum=0x31 00 00 00 , 抓到的 adc 只有 0x8230, 取前5bit = 0x10

系統會一直以 sine(0x31)輸出, 0x31 00 00 00 + 0x10..... 要累計很久之後,才會變成0x32 xx xx xx ,這樣pwm 的值才會改變。

10月16日 10:56:20
轉換PDF檔 列印


Re: PIC12F1822 輸出sine wave
版主
註冊日期:
2004/04/30 10:53
來自 CAE, Microchip
所屬群組:
站務管理者
註冊會員
MICROCHIP
文章: 14151
等級: 72; EXP: 51
HP : 1072 / 1787
MP : 4717 / 70813
離線
通常要改變 PWM 的輸出 Duty 的方法是改變去抓取 PWM Table 的時間。

也就是 Sin PWM 的查表會是在 Timer 的中斷裡去抓 PWM 表格,每中斷一次抓下一個 PWM 表格。如果 Timer 中斷時間變短則 PWM 的輸出頻率就變快,反之就變慢。

這樣也就可以用 ADC 的輸入去改變 Timer 的中斷時間就可以用 VR 改變 Sine Wave 的輸出頻率。

10月16日 11:43:08
轉換PDF檔 列印


Re: PIC12F1822 輸出sine wave
資深會員
註冊日期:
2004/07/23 16:25
所屬群組:
註冊會員
文章: 1176
等級: 29; EXP: 94
HP : 0 / 723
MP : 392 / 28170
離線
看錯了重寫
PhaseShift=ADC*256

PhaseShift<<5 =ADC*256*32

PhaseAccum = PhaseAccum + ((PhaseShift << 5) + 1);

ADC 的 前5BIT加到 PhaseAccum[3]之中。

PhaseAccum[3]增加的速度沒我之前寫的這麼慢

10月16日 15:10:47
轉換PDF檔 列印


Re: PIC12F1822 輸出sine wave
初級會員
註冊日期:
2009/12/01 10:06
所屬群組:
註冊會員
文章: 22
等級: 3; EXP: 41
HP : 0 / 60
MP : 7 / 1407
離線
引用:

Ryang 寫道:
通常要改變 PWM 的輸出 Duty 的方法是改變去抓取 PWM Table 的時間。

也就是 Sin PWM 的查表會是在 Timer 的中斷裡去抓 PWM 表格,每中斷一次抓下一個 PWM 表格。如果 Timer 中斷時間變短則 PWM 的輸出頻率就變快,反之就變慢。

這樣也就可以用 ADC 的輸入去改變 Timer 的中斷時間就可以用 VR 改變 Sine Wave 的輸出頻率。


不同頻率的SINE Wave輸出, 只是不同PWM開關速度的快慢調整,經過RCRC濾波器來完成。

10月17日 11:12:46
轉換PDF檔 列印






無法在此發表文章
可以在此觀看文章
無法回覆文章
無法編輯自己的文章
無法刪除自己的文章
無法發起投票調查
無法在此投票
無法上傳附加檔案
無法不經審核直接發表文章

[進階搜尋]


搜尋
Microchip連結

網頁捷徑
2017 Summer Elite 報名
教育訓練
其它網站連結
電話: 02-25000405
產品技術問題產品技術支援專線:0800-717718 台北02-25088600 新竹03-5778366 Ext. 8600 高雄07-2137830 MicrochipDIRECT 專線: 07-2137830
Powered by XOOPS © 2001-2012 The XOOPS Project