|
Tài trợ cho PIC Vietnam |
dsPIC - Bộ điều khiển tín hiệu số 16-bit Theo dự kiến của Microchip, vào khoảng năm 2011 dsPIC sẽ có doanh số lớn hơn PIC |
|
Ðiều Chỉnh | Xếp Bài |
|
08-05-2008, 04:48 PM | #1 |
Đệ tử 1 túi
Tham gia ngày: Sep 2006
Bài gửi: 14
: |
Anh Nam Cho Em Hỏi Một Vấn Đề Lớn, Chắc Chỉ Có Anh Mới Trả Lời Được
Cám ơn anh trước.
Em tạo một tín hiệu sin bằng việc đặt tra theo bảng sau; sinTable[] = {5,6,7,8,9,9,10,10,10,10,10,9,9,8,7,6,5,4,3,2,1,1, 0,0,0,0,0,1,1,2,3,4}; và dưới đây là một tín hiệu hình sin có biên độ và tần số giống như trên nhưng dịch di 90 độ sinTable_s90[] = {10,10,10,9,9,8,7,6,5,4,3,2,1,1,0,0,0,0,0,1,1,2,3, 4,5,6,7,8,9,9,10,10}; bây giờ em có một tín hiệu được chuyển đổi ADC (có tần số bằng tần số của hai tín hiệu trên) => vậy bây giờ em muốn có hai tín hiệu mới :I = sin_table x input_sig và Q = sin_table_s90 x input_sig. và sau đó cho hai tín hiệu qua bộ lọc FIR(bộ lọc được hỗ trợ ngay trong con dspic) để được tín hiệu I,Q cuối cùng thì em phải làm cách nào, em làm rồi mà nó chạy không đúng Chương trình của em: Code:
=================ISR_Timer #include "p30f4011.h" #include "common.h" #include "dsp.h" void Init_Timers( void ); void Init_Timers( void ) { TMR1 = 0; //Xoa so dem trong TMR1 PR1 = 200; //TMR1 tran moi ms _T1IF = 0; //Xoa co ngat cua Timer 1 T1CON = 0x0020; //Dung fcy lam clock, prescale = 1:64, tat Timer 1 _T1IE = 1; //Cho phep ngat Timer 1 T2CON = 0; // chon he so chia la 1, tat timer 2 IFS0bits.T2IF = 0; // Xoa co ngat IPC1bits.T2IP = 5; // Uu tien ngat PR2 = SAMPCOUNT; // chu ky lay mau TMR2 = 0; // Xoa so dem trong timer 2 IEC0bits.T2IE = 1; // Cho phep ngat khi tran // set up TMR3 to generate signals for the ADC convert // tan so lay mau 320kHz TMR3 = 0x0000; //chon he so chia la 1, tat timer 3 PR3 = SAMPCOUNT; // chu ky lay mau IFS0bits.T3IF = 0; IEC0bits.T3IE = 0; // delay turning the output timer on until the main loop T2CONbits.TON = 0; } ==========================main #include <p30f4011.h> #include <stdio.h> #include "common.h" #include "dsp.h" #include "lcd8bit.h" #include "delay.h" #include "string.h" _FOSC(CSW_FSCM_OFF & XT_PLL16); _FWDT(WDT_OFF); _FBORPOR(PBOR_OFF & MCLR_EN); _FGS(CODE_PROT_OFF); extern FIRStruct lowpassexample_psvFilter; /*Contains filter structures for FIR-LPF*/ fractional i_Ptr_sig[NUMSAMP]; fractional ref_input_sig[NUMSAMP]; fractional ref_input_s90_sig[NUMSAMP]; fractional input_I_signal[NUMSAMP]; fractional input_Q_signal[NUMSAMP]; fractional output_I_signal[NUMSAMP]; fractional output_Q_signal[NUMSAMP]; //fractional output_REF_signal[NUMSAMP]; //fractional output_REF2_signal[NUMSAMP]; fractional* ref_input_s90; fractional* ref_input; fractional* i_Ptr; fractional* o1_Ptr; fractional* o2_Ptr; fractional* i1_Ptr; fractional* i2_Ptr; volatile fractional fin; volatile fractional fqn; unsigned int doFilterFlag; int main(void) { float fI,fQ,adc,in; float mag,phi; char sBuff[40]; fractional tI,tQ; TRISE = 0xFFF0; ref_input =& ref_input_sig[0]; ref_input_s90 =& ref_input_s90_sig[0]; i_Ptr =& i_Ptr_sig[0]; input_I_signal[0] = (i_Ptr_sig[0])*(ref_input_sig[0]); input_Q_signal[0] = (i_Ptr_sig[0])*(ref_input_s90_sig[0]); // i1_Ptr =&input_I_signal[0]; // i2_Ptr =&input_Q_signal[0]; o1_Ptr =&output_I_signal[0]; o2_Ptr =&output_Q_signal[0]; // ref_input =&output_REF_signal[0]; // ref_input_s90 =&output_REF2_signal[0]; // i_Ptr =&input[0]; FIRDelayInit(&lowpassexample_psvFilter); Init_Timers(); Init_ADC(); TMR1 = 0; TMR2 = 0; TMR3 = 0; T1CONbits.TON = 1; T2CONbits.TON = 1; T3CONbits.TON = 1; while(!doFilterFlag); while (1) { if (doFilterFlag) { o1_Ptr = FIR(NUMSAMP,&output_I_signal[0],&input_I_signal[0],&lowpassexample_psvFilter); o2_Ptr = FIR(NUMSAMP,&output_Q_signal[0],&input_Q_signal[0],&lowpassexample_psvFilter); fin = output_I_signal[0]; fqn = output_Q_signal[0]; tI = fin; tQ = fqn; fI = Fract2Float(tI); fQ = Fract2Float(tQ); in= *i1_Ptr; adc= i_Ptr_sig[0]; mag=sqrt(fI*fI+fQ*fQ); phi=atan2(fQ,fI)*180.0f/PI; Init_LCD(); lcd_cmd(lcd_homeL1); sprintf(sBuff," Mag = %8.5f ",mag); // sprintf(sBuff," Iout = %8.5f ",in); puts_lcd(sBuff,strlen(sBuff)); lcd_cmd(lcd_homeL2); sprintf(sBuff," Phi = %8.3f ",phi); // sprintf(sBuff," ADC =%8.3f ",adc); puts_lcd(sBuff,strlen(sBuff)); doFilterFlag = 0; } } return 0; } // ĐỀ TÀI EM LÀM LÀ VỀ BỘ KHUYẾCH ĐẠI LOCK IN thay đổi nội dung bởi: falleaf, 08-05-2008 lúc 05:34 PM. |
09-05-2008, 01:00 AM | #2 |
Trưởng lão PIC bang
|
Tôi đã xem qua các tập tin nguồn của bạn, nhưng không hề thấy 2 bảng sin trên được nhập vào chỗ nào. Nếu không có hai bảng sin đó thì code của bạn sẽ dùng giá trị nào?
Trong lý thuyết, các tín hiệu reference là những hàm sin thực sự, có trị trung bình bằng 0, còn trong hai bảng sin của bạn thì trị trung bình của hàm là khác 0. Vậy có cần điều chỉnh lại công thức tính toán hay không, và nếu cần thì điều chỉnh ra sao? Đề tài là của bạn, do đó bạn nhất định là người phải tìm hiểu, thực hiện đề tài. Những người khác chỉ có thể giúp bạn khi bạn có vướng mắc ở khâu nào đó. Riêng ở picvietnam, những vướng mắc đó chỉ giới hạn trong những vấn đề liên quan đến PIC/dsPIC. Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
09-05-2008, 02:16 PM | #3 |
Đệ tử 1 túi
Tham gia ngày: Sep 2006
Bài gửi: 14
: |
Sory anh, em có gửi kem file 00_program.rar mà. Trong đó có hàm khởi tạo sóng sin reference, hàm sin này sử dụng 4 bít, nó điều khiển và cho ra sóng sin sau khi qua bộ biến đổi dac r-2r network. Vả sau đó là qua bộ lọc thông thấp để làm mịn tín hiệu(Đo ra miột tín hiệu rất đẹp_cái này đã làm được và em đã kiểm tra rồi ko sai gì cả)Tín hiệu này sau khi được hình thành sẽ cung cấp cho 1 sensor(cấu tạo theo kiểu cầu trở) tín hiệu từ senor ra sẽ có tần số đúng bằng tần số của tín hiệu reference tạo ra.
-Ở đây em chỉ muốn hỏi anh là để nhân tín hiệu sau khi biến đổi ADC với tín hiệu referen em tạo ra theo bảng thì nhân như thế nào. ///==============Hàm tạo tín hiệu reference============== #include <p30f4011.h> #include "common.h" #include "dsp.h" volatile unsigned char _sinTableIndex; extern fractional* ref_input_s90; extern fractional* ref_input; static unsigned char sinTable[] = {5,6,7,8,9,9,10,10,10,10,10,9,9,8,7,6,5,4,3,2,1,1, 0,0,0,0,0,1,1,2,3,4}; static unsigned char sinTable_s90[] = {10,10,10,9,9,8,7,6,5,4,3,2,1,1,0,0,0,0,0,1,1,2,3, 4,5,6,7,8,9,9,10,10}; void __attribute__((__interrupt__,no_auto_psv)) _T2Interrupt( void ) { _sinTableIndex++; _sinTableIndex &= 0b00011111; LATE = (sinTable[_sinTableIndex]); *ref_input = (sinTable[_sinTableIndex]); *ref_input_s90 = (sinTable_s90[_sinTableIndex]); IFS0bits.T2IF = 0; // Xoa co ngat } #include "p30f4011.h" #include "common.h" #include "dsp.h" //extern fractional input_I_signal[NUMSAMP]; //extern fractional input_Q_signal[NUMSAMP]; //extern fractional output_I_signal[NUMSAMP]; //extern fractional output_Q_signal[NUMSAMP]; extern unsigned int doFilterFlag; // extern int sample; extern fractional* i_Ptr; //extern fractional* i1_Ptr; //extern fractional* i2_Ptr; void Init_ADC(void); void __attribute__((__interrupt__)) _ADCInterrupt(void); void Init_ADC(void) { /* ADCON1bits.FORM = 3; // 1.15 fractional //number format. // signed fractional ADCON1bits.SSRC = 2; // Timer 3 cham dut lay mau va kich hoat ADCON1bits.ASAM = 1; // Khoi dong che do tu dong lay mau ADCON2bits.SMPI = 0; // ngat sau moi mau thu duoc; ADCON3bits.SAMC = 31; ADCON3bits.ADCS = 63; ADCHS = 0x0008; // Kenh 8 doc tin hieu giua AN8 va AVss ADCSSL = 0x0000; // Khong quet cac ngo vao ADPCFG = 0xFFFF; ADPCFGbits.PCFG8 = 0; IFS0bits.ADIF = 0; // xoa co ngat ADC IEC0bits.ADIE = 1; // cho phep ngat ADC ADCON1bits.ADON = 1; // bat ADC T3CONbits.TON = 1; // bat timer 3 */ ADCON1bits.FORM = 3; // 1.15 fractional ADCON1bits.SSRC = 2; // Timer 3 cham dut lay mau va kich hoat ADCON1bits.ASAM = 1; // Khoi dong che do tu dong lay mau ADCON1bits.SIMSAM = 0; // Samples multiple channels individually in sequence ADCON2bits.SMPI = 0; // ngat sau moi mau thu duoc; ADCON2bits.CHPS = 0; // ADCON2=0; ADCON3bits.SAMC = 1; // dung 1TAD cho lay mau ADCON3bits.ADCS = 3; // dung clock he thong,TAD = 2xTcy = 250 ns ADCHS = 0x0008; //Kenh 0 doc tin hieu giua AN8 va AVss ADCSSL = 0x0000; //Khong quet cac ngo vao ADPCFG = 0xFFFF; ADPCFGbits.PCFG8 = 0; // AN8 la ADC con lai la digital IFS0bits.ADIF = 0; // xoa co ngat IEC0bits.ADIE = 1; // cho phep ngat ADCON1bits.ADON = 1; // bat modul ADC } void __attribute__((__interrupt__)) _ADCInterrupt(void) { //Clear the Timer3 Interrupt Flag IFS0bits.T3IF = 0; // sample = ADCBUF0; // int format *i_Ptr = ADCBUF0; doFilterFlag = 1; IFS0bits.ADIF = 0; } |
09-05-2008, 02:18 PM | #4 |
Đệ tử 1 túi
Tham gia ngày: Sep 2006
Bài gửi: 14
: |
nhân *i_Ptr với bảng sin_Table[]. Nhân hai sóng trong xử lý tín hiệu số
|
09-05-2008, 08:17 PM | #5 |
Trưởng lão PIC bang
|
Nếu bạn thực hiện việc nhân và lọc ngay sau khi lấy mẫu, thì tại thời điểm lấy mẫu tn = nT (T là chu kỳ lấy mẫu), bạn nhân hai mẫu thứ n với nhau rồi lưu vào bộ đệm. Tôi không hiểu có vấn đề gì ở đây mà bạn không thể nhân chúng với nhau được.
Bạn viết code rải rác ở nhiều tập tin nguồn, đối với tôi là khá khó khăn trong việc theo dõi. Do đó, liệu bạn có thể mô tả vắn tắt bạn thực hiện những gì trong chương trình của bạn hay không? Quan trọng nhất là phần thực hiện lấy mẫu và lọc tín hiệu: Bạn lấy mẫu toàn bộ một chu kỳ ngõ vào rồi mới lọc và xử lý hay là thực hiện lọc và xử lý sau mỗi lần lấy mẫu ngõ vào? Dựa vào chú thích của bạn, tôi cho là tần số lấy mẫu và chuyển đổi ADC là 320 kHz (do Timer3 tạo ra). Và với mỗi ngắt ADC, bạn đều bật cờ doFilterFlag. Khi cờ doFilterFlag được bật, bạn thực hiện một loạt các thao tác tính toán và hiển thị. Trong một lần xử lý cờ doFilterFlag, bạn có 3 phép nhân float, 1 phép chia float, 1 lần gọi hàm sqrt(), 1 lần gọi hàm atan2(), cùng với 1 loạt thao tác hiển thị ra LCD. Với tần số lấy mẫu và chuyển đổi ADC là 320 kHz, bạn sẽ bật cờ doFilterFlag mỗi 3.125 us. Liệu 3.125 us (khoảng 94 chu kỳ máy khi dsPIC30F4011 chạy ở 30 MIPS) có đủ cho một loạt các thao tác vừa kể trên hay không? Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
15-05-2008, 10:01 AM | #6 |
Đệ tử 1 túi
Tham gia ngày: Sep 2006
Bài gửi: 14
: |
Em thực hiện lọc và xử lý sau mỗi lần lấy mẫu ngõ vào. Sau mỗi lần lấy mẫu em thực hiện nhân hai tín hiệu với nhau và sau đó là cho qua lọc số FIR. Em cũng đã bỏ qua, các bước lọc số. Em chỉ nhân và hiện thị kết quả thông thường ra LCD thì kết quả = 0.00000. Không có ji thay đổi khi em cho tín hiệu vào cả.
|
15-05-2008, 10:09 AM | #7 |
Đệ tử 1 túi
Tham gia ngày: Sep 2006
Bài gửi: 14
: |
à anh cho em hỏi nữa, cấu trúc nhân hai phép nhân của em không bít có đúng không.
|
15-05-2008, 06:45 PM | #8 |
Trưởng lão PIC bang
|
Bạn hãy đọc lại post #5 của tôi. Với code hiện tại của bạn, dsPIC không đủ thời gian để xử lý.
Thân,
__________________
Biển học mênh mông, sức người có hạn. Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau: http://www.picvietnam.com/forum/showthread.php?t=1263 |
|
|