PDA

View Full Version : Các thắc mắc về ASM30, C30


namqn
23-04-2006, 06:47 PM
Hiện nay đã có một số bạn quan tâm đến dsPIC, sử dụng ASM30 hay C30 để viết chương trình, và có những thắc mắc, cũng như trở ngại trong khi viết chương trình cho dsPIC. Tôi mở luồng này để các bạn có thể post những câu hỏi, những vấn đề liên quan đến việc viết chương trình cho dsPIC.

Nào các bạn, hãy cùng nhau chinh phục dsPIC đi!

Thân,

ThanhPhuc
29-04-2006, 11:36 PM
Khi xử dụng ADC của dsPIC và UART có ảnh hưởng gì không ?
Khi chuyển ADC on bằng lệnh (ADCON1bits.ADON =1 ;) thì không thể set ADON =1 được .Đoạn chương trình như sau :
ADPCFG =0xFFFB;
ADCON1=0x0000;
ADCHS = 0x0002;
ADCSSL =0 ;
ADCON3 =0x0002;
ADCON2=0;
a=100;
ADCON1bits.ADON =1;
if(!ADCON1bits.ADON)
printf("%d", a);
..
Đoạn trên là chương trình mẫu của DS70064D,hai lệnh cuối dùng để kiểm tra ADON.
Khi kiểm tra bằng phần mềm khi vào đoạn chương trình trên lệnh printf thực hiện nên trên PC nhận giá trị 100.Các anh xem giúp đoạn trên có lỗi gì không?

namqn
30-04-2006, 06:52 PM
Bạn mô tả thêm phần cứng: chip được sử dụng, các từ cấu hình liên quan đang dùng, các chân I/O đang được sử dụng.

Thân,

ThanhPhuc
01-05-2006, 10:20 AM
Em dùng bootloader cấu himhf như sau :
#include <p30f4012.h>
#include "stdio.h"
#include "uart.h"
_FOSC(CSW_FSCM_OFF & XT_PLL4); //Set up for crystal multiplied by 4x PLL
_FWDT(WDT_OFF); //Turn off the Watch-Dog Timer.
_FBORPOR(MCLR_EN & PWRT_OFF); //Enable MCLR reset pin and turn off the power-up timers.
_FGS(CODE_PROT_OFF);
Phần khai báo UART như hướng dẫn của anh.Em sử dụng hàm
void OpenUART1(unsigned int config1,unsigned int config2, unsigned int ubrg) .Phần giao tiếp với PC hoạt động tốt

namqn
01-05-2006, 08:06 PM
Bạn sử dụng mã nguồn mẫu của Microchip, phần UART chạy tốt, hai lệnh bạn thêm vào để kiểm tra bit ADON không có vấn đề. Vậy các phần bạn đã post ở đây không có vấn đề gì. Tôi đã thử kiểm tra phần mã của hai lệnh bạn thêm vào do C30 dịch ra, vẫn không có vấn đề gì. Bạn thử kiểm tra xem module ADC của bạn có làm việc hay không, bằng cách dùng một tín hiệu chuẩn nào đó (pin 1.5V chẳng hạn) để xem ADC có đọc về đúng và ổn định hay không. Tôi thường không kiểm tra bit ADON đó, vì khi bật module thì các kết quả đọc được từ ADC về chứng tỏ nó đang hoạt động tốt.

Tôi sẽ thử dùng kết hợp ADC và UART, sẽ thông báo kết quả cho bạn sau.

Thân,

namqn
02-05-2006, 06:54 PM
Tôi đã thử dùng ADC cùng với UART, chip làm việc bình thường. Các giá trị ADC đọc được đã được truyền lên PC mà không gặp vấn đề gì. Sử dụng 2 lệnh tương tự như của bạn để kiểm tra bit ADON cho thấy bit đã được set thành công, không có thông báo được xuất lên PC thể hiện bit ADON không thể set được.

Thân,

ThanhPhuc
06-05-2006, 10:52 AM
Em đã thử module ADC,do Module ADC chưa làm việc nên mới kiểm tra các thanh ghi liên quan đến ADC.Em đang tìm các tài liệu liên quan đến ADC để kiểm tra xem còn cần phải khai báo thêm lệnh gì nửa,nếu chương trình đúng thì module ADC bị hỏng.

namqn
06-05-2006, 08:59 PM
Em đã thử module ADC,do Module ADC chưa làm việc nên mới kiểm tra các thanh ghi liên quan đến ADC.Em đang tìm các tài liệu liên quan đến ADC để kiểm tra xem còn cần phải khai báo thêm lệnh gì nửa,nếu chương trình đúng thì module ADC bị hỏng.
Tôi dùng đoạn chương trình mẫu của Microchip, và đoạn chương trình tôi tự viết, không có điểm gì khác biệt. Những thanh ghi cần thiết đã được thiết lập trong chương trình mẫu. Bạn nên kiểm tra lại phần cứng, đo thử xem điện áp tại AVDD so với VDD có chênh lệch quá không, và tương tự đối với AVSS và VSS.

Đoạn chương trình liên quan đến thiết lập chế độ cho ADC của tôi:
ADPCFG = 0xFFFE;
ADCON1 = 0x0000;
ADCON2 = 0x0000;
ADCHS = 0x0000;
ADCSSL = 0x0000;
ADCON3 = 0x0002;
ADCON1bits.ADON = 1;
if (!ADCON1bits.ADON) printf("ADON is off");

Trong vòng lặp:
while (1) {
if (k != 0) {
ADCON1bits.SAMP = 1;
asm("repeat #200");
asm("nop");
ADCON1bits.SAMP = 0;
while (!ADCON1bits.DONE);
ADCValue = ADCBUF0;
printf("\nADC Value is: %d", ADCValue);
k = 0;
};

Tôi dùng một ngắt timer để đặt k = 1 sau mỗi 0,5 giây.

Thân,

ThanhPhuc
09-05-2006, 11:17 PM
Chương trình của em cũng tương tự như trên,riêng phần cứng em nối AVDD với VDD,AVSS nối với VSS.Các chân nầy nối với nhau có ảnh hưởng gì không?
Em đã thử với dspic30F4011 cũng gặp lỗi như trên.

namqn
10-05-2006, 12:10 AM
Tôi vẫn nối AVDD vào VDD, và AVSS vào VSS trong nhiều mạch của tôi.

Tuy nhiên, một lần tôi phát hiện ra module ADC trong một mạch dsPIC của tôi không làm việc, dò phần mềm không phát hiện lỗi, cuối cùng phát hiện ra mạch in khi chạy bị đứt một phần ground plane, do đó cái ground plane của ADC và ground plane của board không nối với nhau. Sửa xong phần đó thì mạch chạy tốt. Vì thế tôi mới khuyên bạn nên đo thử trên mạch thật, biết đâu vẽ mạch thì đúng, nhưng làm mạch thì lại bị lỗi đâu đó.

Thân,

ThanhPhuc
10-05-2006, 10:51 PM
EM đã tìm được lỗi rồi, do chương trình bootloader disable adc module.Em bỏ lệnh nầy mạch và chương trình hoạt động tốt.
Cám ơn anh nhiều !

namqn
10-05-2006, 11:50 PM
EM đã tìm được lỗi rồi, do chương trình bootloader disable adc module.Em bỏ lệnh nầy mạch và chương trình hoạt động tốt.
Cám ơn anh nhiều !
Anh không nghĩ là em lại có lệnh disable module ADC trong bootloader đối với con 4012. Em chỉ cần lệnh đó đối với 2011 và 3012 (mấy con chỉ có 18 chân).

Dù sao cũng là tin tốt, em đã tìm ra lỗi và xác nhận rằng module ADC có thể làm việc bình thường với UART.

Thân,

escapevn
14-05-2006, 05:21 PM
Bác Namqn à, em hiện đang dùng con dsPIC30F3012 nhưng đến phần sử dụng các hàm dsp thì khi em khai báo ma trận và sử dụng các hàm như Matrixadd và Matrixinvert thì lại bị báo lỗi. Mong bác chỉ cho em cách sử dụng và khai báo các hàm này. Cảm ơn bác nhiều lắm, em đang rất cần cái này.

namqn
14-05-2006, 07:09 PM
Bác Namqn à, em hiện đang dùng con dsPIC30F3012 nhưng đến phần sử dụng các hàm dsp thì khi em khai báo ma trận và sử dụng các hàm như Matrixadd và Matrixinvert thì lại bị báo lỗi. Mong bác chỉ cho em cách sử dụng và khai báo các hàm này. Cảm ơn bác nhiều lắm, em đang rất cần cái này.
Bạn có thể cho biết thêm thông tin về: phiên bản MPLAB, phiên bản C30 đang dùng hay không?. Đồng thời, bạn có thể post phần khai báo, phần code liên quan đến các hàm trong thư viện DSP được dùng, và phần thông báo lỗi hay không?

Thân,

escapevn
15-05-2006, 12:03 AM
Hic, tại lúc trước em quên ko add file libdsp-coff.a nên sử dụng hàm dsp mới không được anh à. Bây giờ thì OK rồi.
Bác giải thích cho em về các thanh ghi CORCON và các thanh Accumulator, vai trò của nó trong các hàm DSP đc không? Các hàm dsp tác động tới số kiểu fractional và float thì khác nhau thế nào?
Còn các thanh ghi như XMODSRT, XMODEND, YMODSRT, YMODEND có vai trò thế nào trong dsp? em thấy trong ví dụ về FIR của microchip thì họ có modified mấy thanh ghi này.
Mong bác giúp đỡ.

escapevn
15-05-2006, 07:16 PM
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.

namqn
15-05-2006, 08:59 PM
Hic, tại lúc trước em quên ko add file libdsp-coff.a nên sử dụng hàm dsp mới không được anh à. Bây giờ thì OK rồi.
Bác giải thích cho em về các thanh ghi CORCON và các thanh Accumulator, vai trò của nó trong các hàm DSP đc không? Các hàm dsp tác động tới số kiểu fractional và float thì khác nhau thế nào?
Còn các thanh ghi như XMODSRT, XMODEND, YMODSRT, YMODEND có vai trò thế nào trong dsp? em thấy trong ví dụ về FIR của microchip thì họ có modified mấy thanh ghi này.
Mong bác giúp đỡ.
Phần này khá dài dòng, tôi giải thích vắn tắt dưới đây:
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,

escapevn
15-05-2006, 10:55 PM
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é.

namqn
16-05-2006, 06:17 PM
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,

escapevn
18-05-2006, 12:19 PM
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. :(

escapevn
18-05-2006, 03:50 PM
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.

namqn
19-05-2006, 08:20 PM
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,

escapevn
19-05-2006, 09:54 PM
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.

namqn
21-05-2006, 09:47 PM
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à 2^{-15} \approx 3\times10^{-5}. Do đó, sai lệch trung bình khi chuyển từ float sang fractional là khoảng 1.5\times10^{-5}.

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,

pham_v_quang3i
24-08-2006, 12:16 PM
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
#include <p30fxxxx.h>
#include <ports.h>
#include<uart.h>
//------- Chuong trinh con phuc vu ngat TX UART1 ----------------------------------

void _ISR _U1TXInterrupt(void)
{
IFS0bits.U1TXIF = 0; // Clear TX interrupt flag
}
//------- Chuong trinh con phuc vu ngat RX UART1 ----------------------------------

void _ISR _U1RXInterrupt(void)
{
IFS0bits.U1RXIF = 0; // Clear RX interrupt flag
}

//------- Thiet lap cac thong so cho UART1 -----------------------------------------

void Uart1Init ()
{
unsigned int baud;
unsigned int U1MODEvalue;
unsigned int U1STAvalue;
CloseUART1();
ConfigIntUART1(UART_RX_INT_EN &
UART_RX_INT_PR5 &
UART_TX_INT_EN &
UART_TX_INT_PR3);
baud = 51; // baud 9600

U1MODEvalue = UART_EN & UART_IDLE_CON &
UART_RX_TX &
UART_DIS_WAKE & UART_DIS_LOOPBACK &
UART_DIS_ABAUD & UART_NO_PAR_8BIT & UART_1STOPBIT;

U1STAvalue = UART_INT_TX & UART_TX_PIN_NORMAL &
UART_TX_ENABLE &
UART_INT_RX_CHAR & UART_ADR_DETECT_DIS &
UART_RX_OVERRUN_CLEAR;

OpenUART1(U1MODEvalue, U1STAvalue, baud);


}

int main(void)
{
Uart1Init;
while(1)
{
char Txdata[] = "Chao Pic Viet Nam";
putsUART1 ((unsigned int *)Txdata);
while(BusyUART1());
return 0;
}
}

namqn
25-08-2006, 08:51 PM
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.

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
}

Thân,

pham_v_quang3i
30-08-2006, 11:57 AM
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ạ.

pham_v_quang3i
30-08-2006, 12:31 PM
Hôm trước em đã hỏi bác Nam một số câu hỏi , bác trả lời nhưng em chưa hiểu. Em post lại một số câu hỏi lên đây mong bác hoặc các Trưởng lão PIC bang trả lời cụ thể giúp em :
- Như em đã hỏi con 5013 của em dùng thạch anh ngoài không chạy, em thử thay bằng con 6014 ( chứ ko phải 6014A) , dùng thạch anh ngoài cũng không chạy. Cả hai trương hợp trên dùng mạch RC bên trong thì chạy, vậy em muốn hỏi, các bác đang ở trong nước , có bác nào dùng dsPIC dán ( loại có RAM lớn) lần nào chưa, nếu dùng rồi thì đó là loại gì, mua ở đâu ? Có khi nào dòng PIC này bị lỗi, hay PIC em dùng là hàng Sample , nó ko được OK lắm.
- Trong "dsPIC30F Family Reference Manual" Năm 2005. Bảng 7-3 ( oscillator system -VERSION2 ) - trang 180. Bảng 7-4 ( oscillator system -VERSION3 ) - trang 182.
Tùy thuộc vào giá trị của FOS<2:0>, FPR<4:0>, mà ta lựa chon nguồn clock. Em muốn hỏi . Khi nguồn ta chọn nguồn OSC là Primary , FOS<2:0> = 11; FPR<4:0>=1010 (hoặc 0001,0011 ) khác so với khi ta chọn nguồn OSC là Internal FRC ( FOS<2:0> =01) ở chỗ nào. Khác ở đây không nói đến có hay không có nhân PLL mà em muốn hỏi về bản chất. Các đại ca cứ giải thích trường hợp này thì các trường hợp EC, LPRC.... cũng tương tự
- Trong file.h ở phần cuối có các chỉ dẫn config nhưng có mottj số chỉ dẫn về OSC em không hiểu
Ví dụ :
_FOSC(CSW_FSCM_OFF & FRC & XT_PLL16);
_FOSC(CSW_FSCM_OFF & FRC & XTL);
_FOSC(CSW_FSCM_OFF & FRC & FRC_PLL4);
_FOSC(CSW_FSCM_OFF & LPRC & EC_PLL16);
_FOSC(CSW_FSCM_OFF & LPRC & ERC);
_FOSC(CSW_FSCM_OFF & LPRC & ERCIO);
_FOSC(CSW_FSCM_OFF & LPRC & XT);
_FOSC(CSW_FSCM_OFF & LPRC & XT_PLL4);
Nguồn OSC đã là FRC thì còn có XT làm gì em ko hiểu , mong đại ca nào hiểu nói cụ thể , rõ ràng cho em.
__________________________________________________ ___________
Nhân tiên đây em xin cảm ơn bác Nam vì bác đã nhiệt tình giúp đỡ em, thanks

pham_v_quang3i
30-08-2006, 04:55 PM
Đôi lời về ngắt
Cú pháp của ngắt :
- Khi khai báo sử dụng một ngắt, cú pháp khai báo đơn giản
void _ISR _INT0Interrupt(void); // ngăt ngoài
void _ISR _U1TXInterrupt(void) // ngắt UART
void _ISR _U1RXInterrupt(void)
- Trang 94 của C30_Users_Guide có định nghĩa cách khai báo đầy đủ :
__attribute__((interrupt [(
[ save(symbol-list)]
[, irq(irqid)]
[, altirq(altirqid)]
[, preprologue(asm)]
)]
))
Trong đấy :
Save : Lưu giữ biến vào của chương trình ngắt
Irq : cho phép đặt vector ngắt
altirq : cho phép đặt vector ngắt thay thế
preprologue : cho phép insert hợp ngữ
Em chỉ dịch Word - by - Word chứ chưa hiểu ý nghĩa thật sự của các mục

* Trong các tài liệu hướng dẫn của microchip có một số khai báo dùng ngắt, sử dụng cú pháp trên ( trong dsPIC® Language Tools Getting Started có nhiều ví dụ về khai báo ngắt kiểu này)
void __attribute__((__interrupt__(__save__(variable1,va riable2)))) _INT0Interrupt(void)
/* interrupt routine code */
{
/* Interrupt Service Routine code goes here */
}
void __attribute__((__interrupt__)) _ADCInterrupt(void);
void __attribute__((__interrupt__, __shadow__)) _T1Interrupt(void);

Các đại ca ai hiểu giải thích cụ thể cho em nhé
+ Giải thích cụ thể về từ khóa __attribute__ , __shadow__vì em thấy nó dùng rất nhiều.
+ Khi nào thì mình cần dùng đầy đủ cú pháp của ngắt, em thấy dùng cú pháp đơn giản như trên cũng chẳng sao.
Thanks

namqn
30-08-2006, 07:17 PM
Hôm trước em đã hỏi bác Nam một số câu hỏi , bác trả lời nhưng em chưa hiểu. Em post lại một số câu hỏi lên đây mong bác hoặc các Trưởng lão PIC bang trả lời cụ thể giúp em :
- Như em đã hỏi con 5013 của em dùng thạch anh ngoài không chạy, em thử thay bằng con 6014 ( chứ ko phải 6014A) , dùng thạch anh ngoài cũng không chạy. Cả hai trương hợp trên dùng mạch RC bên trong thì chạy, vậy em muốn hỏi, các bác đang ở trong nước , có bác nào dùng dsPIC dán ( loại có RAM lớn) lần nào chưa, nếu dùng rồi thì đó là loại gì, mua ở đâu ? Có khi nào dòng PIC này bị lỗi, hay PIC em dùng là hàng Sample , nó ko được OK lắm.
- Trong "dsPIC30F Family Reference Manual" Năm 2005. Bảng 7-3 ( oscillator system -VERSION2 ) - trang 180. Bảng 7-4 ( oscillator system -VERSION3 ) - trang 182.
Tùy thuộc vào giá trị của FOS<2:0>, FPR<4:0>, mà ta lựa chon nguồn clock. Em muốn hỏi . Khi nguồn ta chọn nguồn OSC là Primary , FOS<2:0> = 11; FPR<4:0>=1010 (hoặc 0001,0011 ) khác so với khi ta chọn nguồn OSC là Internal FRC ( FOS<2:0> =01) ở chỗ nào. Khác ở đây không nói đến có hay không có nhân PLL mà em muốn hỏi về bản chất. Các đại ca cứ giải thích trường hợp này thì các trường hợp EC, LPRC.... cũng tương tự
- Trong file.h ở phần cuối có các chỉ dẫn config nhưng có mottj số chỉ dẫn về OSC em không hiểu
Ví dụ :
_FOSC(CSW_FSCM_OFF & FRC & XT_PLL16);
_FOSC(CSW_FSCM_OFF & FRC & XTL);
_FOSC(CSW_FSCM_OFF & FRC & FRC_PLL4);
_FOSC(CSW_FSCM_OFF & LPRC & EC_PLL16);
_FOSC(CSW_FSCM_OFF & LPRC & ERC);
_FOSC(CSW_FSCM_OFF & LPRC & ERCIO);
_FOSC(CSW_FSCM_OFF & LPRC & XT);
_FOSC(CSW_FSCM_OFF & LPRC & XT_PLL4);
Nguồn OSC đã là FRC thì còn có XT làm gì em ko hiểu , mong đại ca nào hiểu nói cụ thể , rõ ràng cho em.
Dùng thạch anh ngoài tức là chúng ta dùng bộ dao động tích hợp bên trong của chip, trong một số trường hợp (vì thạch anh không đúng chủng loại) thì mạch không dao động được, Microchip cũng đã từng có hướng dẫn là trong một số trường hợp cần bổ sung điện trở hồi tiếp ngoài giữa các chân OSC1 và OSC2.

Nếu bạn không dùng thạch anh ngoài được thì vẫn còn các option khác đảm bảo cho bạn có tốc độ đủ cao. Việc bạn dùng được FRC (có và không có PLL) có nghĩa là ít nhất thì chân OSC1 và khối PLL của chip làm việc tốt.
Như vậy bạn có thể dùng các chế độ EC (external clock) hay ERC (RC ngoài chip). Với chế độ EC, bạn cần dùng một vi mạch dao động (đợt vừa rồi khi về nước tôi có mua được vài bộ 24.576 MHz ở chợ Nhật Tảo, tôi nghĩ là ở Hà Nội cũng có loại vi mạch dao động này). Do đó, bạn nên thử thêm các chế độ EC và ERC.

Bây giờ tôi thử giải thích thêm về bảng 7-3. Các bit FPR<3:0> dùng để chọn các cấu hình khác nhau khi ta chọn primary source cho clock (tức là khi FOS<1:0> = 11, đây là chế độ mặc định, những cấu hình này cũng ảnh hưởng đến chức năng của chân OSC2. Nếu ta chọn nguồn cho clock là FRC, hay LP, hay LPRC (những nguồn này là secondary hay internal) thì các bit FPR<3:0> không có ý nghĩa vì chỉ có một cấu hình, tuy nhiên, chức năng của chân OSC2 vẫn lệ thuộc vào các FPR<3:0> như đối với trường hợp dùng primary source.

Vậy có thể nói là khi ta chọn nguồn OSC là Primary , FOS<1:0> = 11; FPR<3:0> = 1010 (hay 0001, hay 0011) khác so với khi ta chọn nguồn OSC là Internal FRC ( FOS<2:0> = 01) ở chỗ Internal FRC không quan tâm đến việc FPR<3:0> = 1010 (hay 0001, hay 0011) và sẽ cấp clock cho chip bằng tần số dao động của Internal FRC, còn primary thì dùng FPR<3:0> = 1010 (hay 0001, hay 0011) để chọn hệ số nhân cho PLL, với đầu vào của PLL lấy từ Internal FRC. Nói cách khác, nếu bạn chọn Internal FRC thì bỏ qua PLL, nhưng bạn vẫn có thể dùng Internal FRC với PLL nếu bạn chọn nguồn clock cho PLL là Internal FRC (điều này không làm được với Version 1, bảng 7-2).

Đây chỉ là cách phân chia các cấu hình clock thôi.

Và với những giải thích ở trên, việc các cấu hình như
_FOSC(CSW_FSCM_OFF & FRC & XT_PLL16);
_FOSC(CSW_FSCM_OFF & FRC & XTL);
_FOSC(CSW_FSCM_OFF & FRC & FRC_PLL4);
_FOSC(CSW_FSCM_OFF & LPRC & EC_PLL16);
_FOSC(CSW_FSCM_OFF & LPRC & ERC);
_FOSC(CSW_FSCM_OFF & LPRC & ERCIO);
_FOSC(CSW_FSCM_OFF & LPRC & XT);
_FOSC(CSW_FSCM_OFF & LPRC & XT_PLL4);

là không có gì khó hiểu, chúng ta muốn dùng FRC hay LPRC, với phần FPR<3:0> được thiết lập giống như của XT_PLL16, XTL, ...

Hy vọng lần này tôi đã giải thích rõ hơn.

Thân,

pham_v_quang3i
01-09-2006, 11:45 AM
OK, em hiểu rồi.
Nếu ta cấu hình chip như thế này :
_FOSC(CSW_FSCM_OFF & FRC & XT_PLL16);
_FOSC(CSW_FSCM_OFF & FRC & XTL);
Thì trong cả hai trường hợp này XT_PLL16 và XTL là không có ý nghĩa. Trong cả hai trường hợp trên chip đều sử dụng mạch dao động FRC trong, nhưng cấu hình của FPR<3:0> vẫn để ở XT_PLL16 hoặc XTL. Vậy mục đích của việc thiết kế này chỉ là để làm hài lòng người dùng thôi ư, nếu người sử dụng muốn thay đổi nguồn clock việc gì mà không cấu hình lại từ đầu. Hay mục đích của việc này là nhờ vào clock switch để 1 chip có thể chạy nhiều tần số khác nhau ở những khoảng khác nhau . Hi , thấy nó cứ là lạ.

namqn
01-09-2006, 06:13 PM
OK, em hiểu rồi.
Nếu ta cấu hình chip như thế này :
_FOSC(CSW_FSCM_OFF & FRC & XT_PLL16);
_FOSC(CSW_FSCM_OFF & FRC & XTL);
Thì trong cả hai trường hợp này XT_PLL16 và XTL là không có ý nghĩa. Trong cả hai trường hợp trên chip đều sử dụng mạch dao động FRC trong, nhưng cấu hình của FPR<3:0> vẫn để ở XT_PLL16 hoặc XTL. Vậy mục đích của việc thiết kế này chỉ là để làm hài lòng người dùng thôi ư, nếu người sử dụng muốn thay đổi nguồn clock việc gì mà không cấu hình lại từ đầu. Hay mục đích của việc này là nhờ vào clock switch để 1 chip có thể chạy nhiều tần số khác nhau ở những khoảng khác nhau . Hi , thấy nó cứ là lạ.
Mục đích của việc đặt FPR<3:0> chính là cho clock switching, chúng ta cấu hình sẵn primary và chuyển từ FRC sang primary khi cần thiết (thường là cho các hệ thống liên quan đến tiết kiệm năng lượng nhưng vẫn cần năng lực tính toán cao, các hệ portable chẳng hạn). Việc đặt FPR<3:0> chỉ không có ý nghĩa khi chúng ta tắt clock switching, nhưng nên chú ý là chân OSC2 vẫn chịu ảnh hưởng của các thiết lập đó, không cần biết clock switching có bật hay không.

Thân,

alamanda
06-01-2008, 11:26 PM
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 :

#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
}

Vấn đề là không biết chương trình trên sai hay thiếu chỗ nào mà I2C master ko nhận được tín hiệu Ack từ slave khi truyền đến slave đó. Bus I2C ở đây chỉ có 2 IC và chương trình I2C Master đã chạy đúng với EEPROM.

alamanda
16-01-2008, 10:33 PM
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?

namqn
17-01-2008, 02:51 AM
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,

alamanda
22-01-2008, 11:28 PM
Về phần cứng,ban đầu em dùng 2 điện trở 1.5k kéo lên;sau khi tham khảo datasheet,em đổi sang dùng điện trở 2.2k,kết quả vẫn như nhau.
Về chương trình Master,em viết theo chương trình Tutorial về I2C của anh,kiểm tra bit _Ackstat sau mỗi lần gửi,nếu ko có tín hiệu Ack trả về thì dừng,và báo lỗi qua UART2(do đó,em biết được I2C bị lỗi ở giai đoạn nào).Nếu có tín hiệu Ack trả về,thì tiếp tục truyền (như vậy ko biết em còn phải chờ gì nữa?).Còn về phần địa chỉ, em cũng đã thử thay đổi địa chỉ slave nằm trong vùng địa chỉ cho phép, nhưng cũng ko ăn thua.
Hiện tại em ko biết mình sai ở phần nào,phần cứng hay phần mềm?