PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   dsPIC - Bộ điều khiển tín hiệu số 16-bit (http://www.picvietnam.com/forum/forumdisplay.php?f=29)
-   -   Cho mình hỏi về Clock Switching... (http://www.picvietnam.com/forum/showthread.php?t=2055)

ajack 03-03-2008 10:30 AM

Cho mình hỏi về Clock Switching...
 
Mình đang dùng dòng dsPIC33F, 256GP. Trước đây mình chỉ dùng AVR, nhưng mà vì AVR không bán 32-bit ở Việt Nam nên mình chuyển sang dùng dsPIC, vì vậy mình chưa dùng con PIC nào trước ngoại trừ dsPIC...
Mình đang dùng C30 Compiler ở máy trong phòng lab của trường (có licene cho C30). Mình có thắc mắc sau đây:
Mình muốn sử dụng Primary Oscillator with PLL (nhưng mà phải switch từ internal FRC).
đây là đoạn code của mình
Code:

_FOSCSEL(FNOSC_FRC);  // Select Internal FRC at POR
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT);  // Enable Clock Switching and Configure POSC in XT mode
_FWDT(FWDTEN_OFF);  // Disable Watchdog Timer

....

int main (void)
{
            // Configure PLL prescaler, PLL postscaler, PLL divisor
        PLLFBD = 62;                        // M = 64
        CLKDIVbits.PLLPOST = 1;        // N2 = 4        N2 = 2 x (PLLPOST+1)
        CLKDIVbits.PLLPRE = 2;        // N1 = 4        N1 = PLLPRE + 2

        // Set New Oscillator Selection
//        __builtin_write_OSCCONH(0b011);
        OSCCONbits.NOSC = 0b011;

        // Request Clock Switching by Setting OSWEN bit
//        __builtin_write_OSCCONL(0b01);
        OSCCONbits.OSWEN = 1;


        // Wait for Clock switch to occur
        while(OSCCONbits.OSWEN == 0) {}
}

có vấn đề là mình không sử dụng function __builtin_write_OSCCONH (và __builtin_write_OSCCONL) được!
mình quyết định là viết ASM cho riêng function __builtin_write_OSCCONH:
Code:

        // Place the New Oscillator Selection (NOSC=0b101) in W0
        asm volatile("MOV #0x15,w0");
        // OSCCONH (high byte) Unlock Sequence
        asm ("MOV #OSCCONH, w1");
        asm volatile("MOV #0x78, w2");
        asm volatile("MOV #0x9A, w3");
        asm volatile("MOV.B w2, [w1]");        // Write 78h
        asm volatile("MOV.B w3, [w1]");        // Write 9Ah
        // Set New Oscillator Selection
        asm volatile("MOV.B w0, [w1]");

và ASM cho riêng function __builtin_write_OSCCONL:
Code:

        // Place 0x01 in W0 for setting clock switch enabled bit
        asm volatile("MOV #0x01, w0");
        // OSCCONL (low byte) Unlock Sequence
        asm volatile("MOV #OSCCONL, w1");
        asm volatile("MOV #0x46, w2");
        asm volatile("MOV #0x57, w3");
        asm volatile("MOV.B w2, [w1]");        // Write 46h
        asm volatile("MOV.B w3, [w1]");        // Write 9Ah
        // Enable Clock Switch
        asm volatile("MOV.B w0, [w1]");        //Request Clock Switching by Setting OSWEN bit

nhưng cũng không được, cái code này là mình làm theo trong datasheet của nó, và trong phần help của C30 cũng chỉ như vậy...
Cái thắc mắc ở đây nữa là tại vì muốn ghi vào register OSCCONH thì phải unlock, mà unlock bằng cách ghi giá trị 0x78 trước rồi giá trị 0x94???
Thứ 2 nữa là mình không biết cách nào để add đoạn mã ASM vào trong C30, ngoại trừ cách mỗi hàng ASM đều phải... asm volatile
Thứ 3 là dù có viết bằng ASM thì nó cũng không nhận ra register OSCCONH và OSCCONL, phải khai báo như thế nào để nó nhận ra được register đó là high bye và low byte của register OSCCON?
Và cuối cùng là làm sao để dùng được những function built-in? Mình thấy trong C30 help thì đâu cần phải include header gì hết cũng vẫn dùng được function built-in

namqn 03-03-2008 08:09 PM

Lý do nào bạn nói rằng bạn không dùng được các hàm builtin của C30? Không dịch được hay code dịch được mà không chạy?

Viết hợp ngữ trong C có 2 cú pháp, cú pháp mà bạn đã dùng là cú pháp đơn giản. Tài liệu hướng dẫn C30 có đề cập đến cú pháp mở rộng, ở mục 7-Mixing Assembly Language and C Modules, bạn có thể tham khảo cách viết này trong các ví dụ CE104 và CE204, link dưới đây:

http://www.microchip.com/stellent/id...GE&nodeId=1408

Thân,

ajack 03-03-2008 08:58 PM

lý do mình không sử dụng được function built-in chính là vì nó không compile được, một điều mà mình vô cùng thắc mắc...
Hơn nữa, có viết bằng ASM thì nó cũng không nhận ra register OSCCONH và OSCCONL, phải khai báo như thế nào để nó nhận ra được register đó là high bye và low byte của register OSCCON? (Khi compile có erorr ở chỗ đó)
Còn về chuyện thay đổi register OSCCONH và OSCCONL? Tại sao phải làm theo một trình tự là ghi giá trị 78H rồi 9AH (đối với register OSCCONH - register OSCCONL cũng phải theo trình tự như vậy...)
Còn chuyện viết assembley language thì mình dù có đọc C30 user's guide cũng hơi khó hiểu... Nhưng mà để mình đọc code example cái đã
Chẳng hiểu tại sao mà viết giao tiếp với UART và LCD lại không khó khăn lắm mà khi dùng clock switching mình lại gặp vấn đề um sùm như vậy nữa... :-(
Cám ơn namqn nhiều

namqn 03-03-2008 10:29 PM

Trích:

Nguyên văn bởi ajack (Post 14625)
lý do mình không sử dụng được function built-in chính là vì nó không compile được, một điều mà mình vô cùng thắc mắc...
Hơn nữa, có viết bằng ASM thì nó cũng không nhận ra register OSCCONH và OSCCONL, phải khai báo như thế nào để nó nhận ra được register đó là high bye và low byte của register OSCCON? (Khi compile có erorr ở chỗ đó)
Còn về chuyện thay đổi register OSCCONH và OSCCONL? Tại sao phải làm theo một trình tự là ghi giá trị 78H rồi 9AH (đối với register OSCCONH - register OSCCONL cũng phải theo trình tự như vậy...)
Còn chuyện viết assembley language thì mình dù có đọc C30 user's guide cũng hơi khó hiểu... Nhưng mà để mình đọc code example cái đã
Chẳng hiểu tại sao mà viết giao tiếp với UART và LCD lại không khó khăn lắm mà khi dùng clock switching mình lại gặp vấn đề um sùm như vậy nữa... :-(
Cám ơn namqn nhiều

Không rõ bạn dùng phiên bản nào của C30, tôi đã biên dịch thử các hàm builtin đó thấy không có vấn đề gì (tôi dùng C30 SE phiên bản 3.01).

Trình tự unlock thanh ghi là do nhà sản xuất quy định. Người ta đề xuất trình tự này để tránh ghi nhầm vào các thanh ghi OSCCON.

Thân,

khoa_ha 20-01-2011 09:18 AM

Trích:

Nguyên văn bởi ajack (Post 14610)
Mình đang dùng dòng dsPIC33F, 256GP. Trước đây mình chỉ dùng AVR, nhưng mà vì AVR không bán 32-bit ở Việt Nam nên mình chuyển sang dùng dsPIC, vì vậy mình chưa dùng con PIC nào trước ngoại trừ dsPIC...
Mình đang dùng C30 Compiler ở máy trong phòng lab của trường (có licene cho C30). Mình có thắc mắc sau đây:
Mình muốn sử dụng Primary Oscillator with PLL (nhưng mà phải switch từ internal FRC).
đây là đoạn code của mình
Code:

_FOSCSEL(FNOSC_FRC);  // Select Internal FRC at POR
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT);  // Enable Clock Switching and Configure POSC in XT mode
_FWDT(FWDTEN_OFF);  // Disable Watchdog Timer

....

int main (void)
{
            // Configure PLL prescaler, PLL postscaler, PLL divisor
        PLLFBD = 62;                        // M = 64
        CLKDIVbits.PLLPOST = 1;        // N2 = 4        N2 = 2 x (PLLPOST+1)
        CLKDIVbits.PLLPRE = 2;        // N1 = 4        N1 = PLLPRE + 2

        // Set New Oscillator Selection
//        __builtin_write_OSCCONH(0b011);
        OSCCONbits.NOSC = 0b011;

        // Request Clock Switching by Setting OSWEN bit
//        __builtin_write_OSCCONL(0b01);
        OSCCONbits.OSWEN = 1;


        // Wait for Clock switch to occur
        while(OSCCONbits.OSWEN == 0) {}
}

có vấn đề là mình không sử dụng function __builtin_write_OSCCONH (và __builtin_write_OSCCONL) được!
mình quyết định là viết ASM cho riêng function __builtin_write_OSCCONH:
Code:

        // Place the New Oscillator Selection (NOSC=0b101) in W0
        asm volatile("MOV #0x15,w0");
        // OSCCONH (high byte) Unlock Sequence
        asm ("MOV #OSCCONH, w1");
        asm volatile("MOV #0x78, w2");
        asm volatile("MOV #0x9A, w3");
        asm volatile("MOV.B w2, [w1]");        // Write 78h
        asm volatile("MOV.B w3, [w1]");        // Write 9Ah
        // Set New Oscillator Selection
        asm volatile("MOV.B w0, [w1]");

và ASM cho riêng function __builtin_write_OSCCONL:
Code:

        // Place 0x01 in W0 for setting clock switch enabled bit
        asm volatile("MOV #0x01, w0");
        // OSCCONL (low byte) Unlock Sequence
        asm volatile("MOV #OSCCONL, w1");
        asm volatile("MOV #0x46, w2");
        asm volatile("MOV #0x57, w3");
        asm volatile("MOV.B w2, [w1]");        // Write 46h
        asm volatile("MOV.B w3, [w1]");        // Write 9Ah
        // Enable Clock Switch
        asm volatile("MOV.B w0, [w1]");        //Request Clock Switching by Setting OSWEN bit

nhưng cũng không được, cái code này là mình làm theo trong datasheet của nó, và trong phần help của C30 cũng chỉ như vậy...
Cái thắc mắc ở đây nữa là tại vì muốn ghi vào register OSCCONH thì phải unlock, mà unlock bằng cách ghi giá trị 0x78 trước rồi giá trị 0x94???
Thứ 2 nữa là mình không biết cách nào để add đoạn mã ASM vào trong C30, ngoại trừ cách mỗi hàng ASM đều phải... asm volatile
Thứ 3 là dù có viết bằng ASM thì nó cũng không nhận ra register OSCCONH và OSCCONL, phải khai báo như thế nào để nó nhận ra được register đó là high bye và low byte của register OSCCON?
Và cuối cùng là làm sao để dùng được những function built-in? Mình thấy trong C30 help thì đâu cần phải include header gì hết cũng vẫn dùng được function built-in

bạn thêm vào code này là OK

void EXT_CLK_Unlock()
{
asm volatile("MOV #OSCCONL, w1");
asm volatile("MOV.B #0x02, w0");
asm volatile("MOV #0x46, w2");
asm volatile("MOV #0x57, w3");
asm volatile("MOV.B w2, [w1]");
asm volatile("MOV.B w3, [w1]");
asm volatile("MOV.B w0, [w1]");
}

kiensnow 21-07-2011 10:37 PM

Thầy nam cho em hỏi, tại sao khi dùng code C , giả sử em chuyển swich sang chế độ XT với PLL, thì khi đó có câu lệnh để chờ chuyển xong là while(OSCCONbits.COSC!=0b011 )
Cái 011 thì em hiểu nó là của 3 bit COSC, còn 0b là ở đâu ra ạ,
Theo như em đọc trong tài liệu thì có 2 cách để chuyến clock,
_Cách 1 là dùng hàm em vừa viết như trên
_Cách 2 là dùng hàm built_in như bên trên
Em hiểu như thế có đúng ko ạ, hay chỉ được dùng hàm built_in như trên kia thôi ạ


Múi giờ GMT. Hiện tại là 04:23 PM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam