![]() |
|
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 |
|
|
|
|
#1 |
|
Đệ tử 1 túi
Tham gia ngày: Aug 2005
Bài gửi: 14
: |
Bác Namqn ah, em đang cần dùng các hàm làm việc với ma trận như MatrixAdd, MatrixScale, MatrixInvert nhưng dữ liệu của em là float, mà hình như các hàm này chỉ hỗ trợ int hoặc fractional.
Mong bác giúp đỡ. Cảm ơn bác nhiều. |
|
|
|
|
|
#2 | |
|
Trưởng lão PIC bang
|
Trích:
Thanh ghi CORCON: US: Bit điều khiển dấu các phép nhân của DSP (có dấu hay không dấu) EDT: Bit điều khiển chấm dứt sớm vòng lặp DO, đọc về luôn là '0' DL<2:0>: Các bit thể hiện mức lồng của vòng lặp DO (0 đến 7) SATA: Bit cho phép thanh ghi AccA bão hòa (bị chặn) SATB: Bit cho phép thanh ghi AccB bão hòa (bị chặn) SATDW: Bit cho phép bão hòa không gian dữ liệu ghi từ DSP ACCSAT: Bit chọn chế độ bão hòa của thanh ghi tích lũy (bình thường hay siêu bão hòa) IPL3: Bit trạng thái mức ưu tiên ngắt (dùng kết hợp với IPL<2:0> trong thanh ghi trạng thái SR) PSV: Bit cho phép PSV (Program Space Visibility) trong không gian dữ liệu RND: Bit chọn chế độ làm tròn (có thiên hướng-quy ước hay không thiên hướng-hội tụ) IF: Bit chọn chế độ nhân số nguyên hay fractional Lõi DSP trong dsPIC chỉ xử lý số nguyên hay fractional, các số float sẽ được chuyển thành số fractional để xử lý, sau đó trả kết quả về dạng float trở lại. Để tăng tốc độ tính toán, dsPIC dùng 2 thanh ghi tích lũy, để load đồng thời hai toán hạng. Đây cũng là lý do để xuất hiện hai thanh ghi địa chỉ X và Y, cũng như các vùng nhớ tương ứng. Nếu dùng các lệnh DSP có đọc dữ liệu thì bắt buộc phải dùng cả hai vùng nhớ X và Y, do đó phải set up các thanh ghi XMODSRT, XMODEND, YMODSRT, và YMODEND cho chính xác. Các lệnh DSP ghi dữ liệu chỉ thông qua bus X. XMODSRT, XMODEND: các thanh ghi địa chỉ bắt đầu và kết thúc cho các bộ đệm modulo (vòng) trong không gian địa chỉ bộ nhớ dữ liệu X YMODSRT, YMODEND: các thanh ghi địa chỉ bắt đầu và kết thúc cho các bộ đệm modulo (vòng) trong không gian địa chỉ bộ nhớ dữ liệu Y Bạn xem thông tin chi tiết trong các tài liệu sau của Microchip: DS51456c: 16-bit Language Tool Libraries DS70046e: dsPIC30F Family Reference Manual DS70157b: dsPIC30F/33F Programmer's Reference Manual Về việc dùng các hàm ma trận với dữ liệu float, thư viện DSP của Microchip cung cấp hai hàm chuyển đổi giữa float và fractional, do đó bạn có thể chuyển số float thành fractional, dùng các hàm xử lý, sau đó trả lại về số float nếu bạn muốn, thông qua 2 hàm chuyển đổi này. 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 |
|
|
|
|
|
|
#3 |
|
Đệ tử 1 túi
Tham gia ngày: Aug 2005
Bài gửi: 14
: |
Cảm ơn bác Namqn nhiều nhé. Em đang làm luận văn đến chỗ này thì bị tắc. HIC
Bác ơi, em đã em 2 hàm Float2Fract(aVal) và Fract2Float(aval) nhưng hàm này chỉ cho chuyển số Float trong khoảng [-1;1) thì bây giờ em phải làm sao (số Float của em >1), giảm đi 10 lần à? Bác trả lời giùm em với nhé. thay đổi nội dung bởi: escapevn, 16-05-2006 lúc 02:04 AM. |
|
|
|
|
|
#4 |
|
Trưởng lão PIC bang
|
Việc bạn cần làm là chuẩn hóa các giá trị (normalize), bạn dựa vào giá trị cực đại của các biến để chuẩn hóa (tức là bạn đang làm việc trong hệ đơn vị tương đối). Khi đó các biến của bạn sẽ là float trong phạm vi [-1, 1) (chú ý cái cận trên nhé).
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 |
|
|
|
|
|
#5 |
|
Đệ tử 1 túi
Tham gia ngày: Aug 2005
Bài gửi: 14
: |
Bác Namqn à, cái phần normalize em đã làm xong but em thấy cái hàm Float2Fract(aVal) nó ngốn nhiều thời gian quá, đến 5888 cycles lận, còn quả Fract2Float(aVal) cũng ngốn tới 1762 cycles, tốn kém quá.
Em đang thử viết cái hàm này dựa theo AN908 (nó nói chỉ mất tất cả chỉ có 29 cycles thôi, mà có cả sample/hold nữa nhé) nhưng mà nó viết khó hiểu thật, bác có ví dụ nào về cái này không? share cho em với. ![]() thay đổi nội dung bởi: escapevn, 18-05-2006 lúc 12:44 PM. |
|
|
|
|
|
#6 |
|
Đệ tử 1 túi
Tham gia ngày: Aug 2005
Bài gửi: 14
: |
Từ Float em nhân nó với 0x8000 được chứ đại ca, còn từ Fract chuyển ngược lại thì dễ rùi.
Mong sớm nhận được support của đại ca. |
|
|
|
|
|
#7 |
|
Trưởng lão PIC bang
|
Hai hàm chuyển đổi giữa float và fractional của C30 được viết bằng C, do đó chúng tiêu tốn khá nhiều chu kỳ máy, nhưng nếu chúng được thực hiện chỉ khi khởi tạo các tham số thì cũng không thành vấn đề.
Tôi không nghĩ là nhân số float với 0x8000 sẽ chuyển đổi được float sang fractional (bạn hãy kiểm tra xem 0x8000 là giá trị nào trong định dạng cho số float). Nhưng nếu bạn vẫn muốn chuyển đổi nhanh giữa float và fractional, với điều kiện ràng buộc tương tự như 2 hàm của C30 (float nằm trong giữa -1 và 1, không kể giá trị 1) thì vẫn có thể làm được. Tuy nhiên, bạn phải tìm hiểu định dạng của số float trong 32 bit (gồm 1 bit dấu, 8 bit cho số mũ theo cơ số 2, và 23 bit định trị), khi đó tôi tin là bạn sẽ có thể viết một đoạn chương trình cho phép chuyển đổi giữa float và fractional chỉ mất vài chục chu kỳ máy. Tôi không có thời gian để tìm hiểu kỹ hơn, nên chỉ gợi ý cho bạn như vậy thôi. Nếu bạn thử nghiệm thì nên dùng 2 hàm của C30 để khẳng định là hàm của bạn chạy tốt. Về AN908, người ta đã chuẩn hóa các phương trình ngay từ đầu, chủ yếu dùng dạng fractional trong xử lý, và tôi nghĩ họ cũng có dùng cách chuyển đổi tôi vừa nêu trên, nhưng không viết cụ thể thành một chương trình con, do đó họ có thể thực hiện được như đã khẳng định trong tài liệu. Chúc bạn thành cô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 |
|
|
|
|
|
#8 |
|
Đệ tử 1 túi
Tham gia ngày: Aug 2005
Bài gửi: 14
: |
Anh Namqn à, em đã làm rồi, chuyển cả số âm và dương trong khoảng [1,-1) và thấy khi em viết không có vấn đề gì, đỡ tốn kém nhiều lắm (giảm khoảng hơn 10 lần) và em cũng đã so sánh kết quả hàm em viết với hàm của dsp.h thì thấy kết quả không sai khác là bao nhiêu (chỉ 10^-5 thôi), em nghĩ là như vậy cũng tạm ổn.
À em muốn hỏi anh là khi sử dụng các hàm với ma trận như cộng trừ nhân đảo thì có phải modify thanh ghi CORCON không? em thấy với một số ma trận đơn giản (kiểu fractional) thì em thử tính không có sai, nhưng với ma trận lớn thì chưa thử được, không biết có sao không. Mong đại ca chỉ giáo cho. |
|
|
|
|
|
#9 |
|
Trưởng lão PIC bang
|
Có lẽ bạn dùng cách tương tự của AN908, các lệnh chuyển đổi mất khoảng 200 chu kỳ máy. Sai lệch của chuyển đổi float sang fractional là hiển nhiên, vì fractional chỉ có độ phân giải là
Theo tài liệu "16-bit Language Tools Libraries" của Microchip thì nhiều hàm thư viện DSP đặt chip vào chế độ làm việc đặc biệt, chúng sẽ đặt CORCON vào stack, điều chỉnh CORCON, sau đó lấy CORCON từ stack để trả về chương trình gọi khi đã thực hiện xong. Do đó bạn phải tìm hiểu xem các lệnh mà bạn dùng có xử lý thanh ghi CORCON hay không, nếu không thì bạn phải tự điều chỉnh thanh ghi CORCON cho thích hợp. Tài liệu đó cũng có đề cập đến việc hầu hết các chương trình con trong thư viện DSP sử dụng số dạng fractional 9.31 để đảm bảo độ chính xác khi tính toán, nhưng kết quả sẽ được trả về ở dạng 1.15. Cần chú ý là chương trình con tính ma trận đảo sẽ dùng số floating point ở cả đầu vào và đầu ra. Theo tôi, tùy vào độ lớn của ma trận mà bạn thực hiện scaling thích hợp để tránh việc kết quả bị tràn đối với dạng fractional 1.15, tất nhiên làm vậy thì độ chính xác sẽ bị ảnh hưởng đôi chút. Có lẽ lấy ví dụ cụ thể sẽ dễ hình dung hơn, giả sử bạn có ma trận vuông cấp 4, nếu thực hiện cộng 2 ma trận với nhau thì độ lớn của mỗi phần tử phải dưới 0.5. Nếu nhân 2 ma trận với nhau thì bạn cộng 4 tích số với nhau, mỗi tích số phải dưới 0.25, nên mỗi phần tử cũng phải có độ lớn dưới 0.5. Tôi cũng đang học dsPIC cùng với các bạn, nên không dám 'chỉ giáo' cho ai hết. Tôi rất cảm ơn nếu các bạn không dùng từ này. 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 |
|
|
|
|
|
#10 | |
|
Đệ tử 1 túi
Tham gia ngày: Aug 2005
Bài gửi: 12
: |
Em dùng ds4011 truyền thông với PC. Trên PC sử dụng tiện ích HyperTerminal của Win.
- Dùng thạch anh 8MHz, PLLx4. Không hiểu sao chương trình của em ko chạy. Chương trình em bỏ chỉ dẫn đi cho dễ nhìn. Ai có mạch chạy thử giúp em chương trình này. Chương trình như sau Trích:
thay đổi nội dung bởi: pham_v_quang3i, 24-08-2006 lúc 12:30 PM. |
|
|
|
|
|
|
#11 |
|
Trưởng lão PIC bang
|
Bạn thử chương trình sau nhé, tôi dùng C30 Student Edition, dịch với optimization level 1. Chương trình sau chờ nhận một ký tự qua UART1, sau đó gửi trả ký tự đã nhận cũng qua UART1.
Code:
void Init_UART1_Module(void);
unsigned short temp;
int main(void) {
Init_UART1_Module();
while (1);
}
void Init_UART1_Module(void) {
U1BRG = (((8000000/9600)/16)-1); //9600 bps @ Fcy = 8 MHz
U1MODE = 0x8000; //Main I/O, 8-bit, no parity, 1 stop bit
// U1MODE = 0x8400; //Alt I/O, 8-bit, no parity, 1 stop bit
U1STA = 0x0400; //Interrupt when a character is received
// U1STA = 0x04C0; //Interrupt when rec. buffer is full
_U1RXIF = 0; //Clear the interrupt flag
_U1RXIE = 1; //Enable UART1 Receive Interrupt
IPC2bits.U1RXIP = 4; //UART1 Receiver Interrupt at priority 4
}
void _ISR _U1RXInterrupt(void) {
temp = U1RXREG;
U1TXREG = temp;
_U1RXIF = 0; //Clear the interrupt flag before returning
}
__________________
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 |
|
|
|
|
|
#12 |
|
Đệ tử 1 túi
Tham gia ngày: Aug 2005
Bài gửi: 12
: |
Tâm sự một tý :
Em thấy C30 có nhiều cú pháp rất "loàng ngoàng", nếu mình không sử dụng các cú pháp này cũng không sao. Nhưng theo em hiểu để có được mã tối ưu thì ta nên sử dụng các cú pháp "loàng ngoàng "này. Trong " C30_Users_Guide " có viết một số kiểu cú pháp mà em đọc em chả hiểu gì. Nhưng nếu em không sử dụng các cú pháp này mà vẫn sử dụng cú pháp như C thông thường thì chương trình vẫn chạy bình thường ( Em ko nhớ là em đọc ở chỗ nào ). Vì vậy mong các đại ca thảo luận , hoặc có những câu hỏi đặt ra về một số cú pháp "loàng ngoàng" để anh em cùng trao đổi -> mới ra được vấn đề. Hoặc đại ca nào thấy không có vấn đề gì với nó thì em mong đại ca đó viết một bài tổng quan về C30 và các cú "pháp loàng" ngoàng đó. Em xin cảm ơn và hậu tạ. |
|
|
|
|
|
#13 |
|
Đệ tử 1 túi
Tham gia ngày: Nov 2005
Bài gửi: 19
: |
Mong các bác chỉ giúp em phần I2C slave cho dsPIC.
Đây là toàn bộ chương trình cho con slave : Code:
#include <p30f4011.h>
_FOSC(CSW_FSCM_OFF & FRC_PLL4);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_ON & BORV_27 & PWRT_4 & MCLR_EN & RST_IOPIN);
_FGS(CODE_PROT_OFF);
#include <i2c.h>
void SI2C_init(void);
void slave_reply(unsigned char data);
unsigned char rcv_data,trn_data;
unsigned char data_request;
void _ISR_PSV _SI2CInterrupt(void)
{
_SI2CIF = 0;
if(_R_W) //Read data from Slave
{
data_request = 1;
}else //Write data to Slave
{
if(_D_A) //I2CRSR chua du lieu
rcv_data = I2CRCV;//doc du lieu
else //I2CRSR chua dia chi
Nop();//Khong lam gi ca
}
}
int main(void)
{
SI2C_init();
while(1)
{
if(data_request)
{
data_request = 0;
trn_data ++;
slave_reply(trn_data);
}
if(rcv_data)
{
rcv_data = 0;
}
}
return 0;
}
void SI2C_init(void)
{
I2CADD = 0x10;
I2CCON = I2C_ON & I2C_IDLE_STOP & I2C_CLK_REL
& I2C_IPMI_DIS & I2C_7BIT_ADD
& I2C_SLW_DIS & I2C_SM_DIS
& I2C_GCALL_DIS & I2C_STR_DIS
& I2C_ACK & I2C_ACK_DIS & I2C_RCV_DIS
& I2C_STOP_DIS & I2C_RESTART_DIS
& I2C_START_DIS;
IPC3bits.SI2CIP = 1;
IEC0bits.SI2CIE = 1;
_SI2CIF = 0;
}
void slave_reply(unsigned char data)
{
I2CTRN = data;
_SCLREL = 1;//Giai phong SCL
}
thay đổi nội dung bởi: alamanda, 08-01-2008 lúc 09:29 PM. Lý do: Bổ sung code |
|
|
|
|
|
#14 |
|
Đệ tử 1 túi
Tham gia ngày: Nov 2005
Bài gửi: 19
: |
hic,sao kô thấy các cao thủ có cao kiến gì vậy? Chẳng lẽ chưa ai tìm hiểu về I2C Slave trên dsPIC?
|
|
|
|
|
|
#15 |
|
Trưởng lão PIC bang
|
Giả sử các hằng số _R_W và _D_A đã được bạn định nghĩa đúng, chương trình bên phía slave của bạn về giải thuật là ổn. Tuy nhiên, chương trình bên phía master của bạn ra sao, phần cứng của bạn thế nào thì bạn chưa nói. Master của bạn làm việc với EEPROM không có nghĩa là nó sẽ làm việc với một slave dsPIC. Bạn có thể cần chỉnh lại phần cứng, có thể cần phải thay đổi chương trình của master (địa chỉ slave mới chẳng hạn), và những vấn đề thực tế khác (thời gian chờ giữa các giai đoạn chẳng hạn, phần này khi giao tiếp với EEPROM thì hardware của EEPROM thực hiện cho bạn, còn khi viết slave thì bạn phải hiện thực nó).
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 |
|
|
|
![]() |
| Ðiều Chỉnh | |
| Xếp Bài | |
|
|
Similar Threads
|
||||
| Ðề tài | Người gửi | Chuyên mục | Trả lời | Bài mới |
| dsPIC Tutorial 1-Tạo và biên dịch một project (ASM30) | namqn | dsPIC - Bộ điều khiển tín hiệu số 16-bit | 16 | 22-08-2012 12:35 AM |