PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > dsPIC - Bộ điều khiển tín hiệu số 16-bit

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

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

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 05-08-2009, 04:14 PM   #1
enti
Đệ tử 2 túi
 
Tham gia ngày: Nov 2006
Bài gửi: 26
:
Hỏi về delay trong C30 với PIC24F

Mình đang dùng PIC24FJ256GB106, bây giờ cần dùng delay, nhưng với C30 chưa có delayus hoặc delay_ms.
Có bạn nào đã làm rồi thì có thể hướng đẫn mình.
Cám ơn.
enti vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-08-2009, 04:36 PM   #2
enti
Đệ tử 2 túi
 
Tham gia ngày: Nov 2006
Bài gửi: 26
:
Mình dùng Timer1 nhưng không được như mong muốn, code như sau:
Code:
#include <p24FJ256GB106.h>

//Configs, EC clock, No protect, Watchdog Off
_CONFIG1 (JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & ICS_PGx1 & FWDTEN_OFF & WINDIS_OFF & FWPSA_PR128 & WDTPS_PS1)
_CONFIG2 (IESO_OFF & PLLDIV_DIV5 & PLL_96MHZ_ON & FNOSC_PRIPLL & FCKSM_CSDCMD & OSCIOFNC_ON & IOL1WAY_OFF & DISUVREG_OFF & POSCMOD_HS)

int main ()
{
	TRISE = 0;
	LATE = 0;

	T1CON = 0x0000;
	T1CONbits.TCKPS1 = 0;
	T1CONbits.TCKPS0 = 0;
	TMR1 = 0x0000;
	PR1 = 0x0002;
	_T1IP = 0x01;
	_T1IF = 0;
	_T1IE = 1;
	_TON = 1;
	while (1)
	{
	}
	return 1;
}

void __attribute__((interrupt, auto_psv)) _T1Interrupt(void)
{
	_T1IF = 0;
	TMR1 = 0x0000;
	_LATE0 = !_LATE0;
}
Với đoạn code trên mình dùng máy đo thì tín hiệu trên chân RE0 thay đổi mỗi 2us.
Nếu thay đổi
T1CONbits.TCKPS1 = 0;
T1CONbits.TCKPS0 = 1;
Cũng không thay đổi, dù theo datasheet thì tần số sẽ 1:8
Có bạn nào có kinh nghiệm đã làm rồi thì hướng dẫn giúp mình.
enti vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-08-2009, 10:41 PM   #3
bebungbu
Đệ tử 1 túi
 
Tham gia ngày: Jun 2009
Bài gửi: 25
:
Bạn dùng thử đoạn code này xem sao nhe.
Code:
/* 
** Delay routines using TMR1
**
*/
#include <p24Fxxxx.h>

void Delayms( unsigned t)
{
    T1CON = 0x8000;     // enable tmr1, Tcy, 1:1
    while (t--)
    {
        TMR1 = 0;
        while (TMR1<16000);
    }
} // Delayms
bebungbu vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-08-2009, 09:32 AM   #4
enti
Đệ tử 2 túi
 
Tham gia ngày: Nov 2006
Bài gửi: 26
:
Trích:
Nguyên văn bởi bebungbu View Post
Bạn dùng thử đoạn code này xem sao nhe.
Code:
/* 
** Delay routines using TMR1
**
*/
#include <p24Fxxxx.h>

void Delayms( unsigned t)
{
    T1CON = 0x8000;     // enable tmr1, Tcy, 1:1
    while (t--)
    {
        TMR1 = 0;
        while (TMR1<16000);
    }
} // Delayms
Mình dùng code này thì tạo delay 1ms được, nhưng sửa lại thì nhanh nhất vẫn là 2us. Vậy để tạo 1us, có cách nào khác không?
enti vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-08-2009, 09:51 PM   #5
bebungbu
Đệ tử 1 túi
 
Tham gia ngày: Jun 2009
Bài gửi: 25
:
Cái này để mình tìm hiểu thêm. Các tiền bối chỉ giúp mình được không vậy ?
bebungbu vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-08-2009, 11:32 PM   #6
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Trích:
Nguyên văn bởi enti View Post
Mình đang dùng PIC24FJ256GB106, bây giờ cần dùng delay, nhưng với C30 chưa có delayus hoặc delay_ms.
Có bạn nào đã làm rồi thì có thể hướng đẫn mình.
Cám ơn.
C Compiler for PIC24 MCUs có hàm __delay32(n) để delay n chu kỳ máy (cần include thêm tập tin libpic30.h khi biên dịch). Nếu bạn biết tốc độ thực thi lệnh thì có thể delay đúng 1 us.

Ví dụ, giả sử bạn có tốc độ thực thi lệnh là 16 MIPS (tức là 16 triệu lệnh/giây, hay 16 lệnh/us). Việc delay 1 us khi đó sẽ có thể thực hiện bằng cách gọi __delay32(16) (khi mô phỏng với MPLAB SIM thì tôi nhận thấy hàm này làm trễ n+2 chu kỳ máy, chứ không phải n chu kỳ máy như trong tài liệu hướng dẫn đề cập, do đó để chính xác hơn thì phải dùng __delay32(14)).

Chú ý là hàm __delay32(n) không thể delay dưới 11 chu kỳ máy. Để delay dưới 11 chu kỳ máy thì bạn có thể dùng một số lệnh nop liên tiếp.

Để delay các thời gian trong tầm ms thì chỉ cần dùng một trong những timer. Bạn hãy tham khảo các tutorial đầu tiên mà tôi đã viết cho dsPIC30F, chúng hoàn toàn có thể áp dụng cho PIC24.

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

thay đổi nội dung bởi: namqn, 06-08-2009 lúc 11:53 PM.
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 10-08-2009, 10:53 AM   #7
enti
Đệ tử 2 túi
 
Tham gia ngày: Nov 2006
Bài gửi: 26
:
Trích:
Nguyên văn bởi namqn View Post
C Compiler for PIC24 MCUs có hàm __delay32(n) để delay n chu kỳ máy (cần include thêm tập tin libpic30.h khi biên dịch). Nếu bạn biết tốc độ thực thi lệnh thì có thể delay đúng 1 us.

Ví dụ, giả sử bạn có tốc độ thực thi lệnh là 16 MIPS (tức là 16 triệu lệnh/giây, hay 16 lệnh/us). Việc delay 1 us khi đó sẽ có thể thực hiện bằng cách gọi __delay32(16) (khi mô phỏng với MPLAB SIM thì tôi nhận thấy hàm này làm trễ n+2 chu kỳ máy, chứ không phải n chu kỳ máy như trong tài liệu hướng dẫn đề cập, do đó để chính xác hơn thì phải dùng __delay32(14)).

Chú ý là hàm __delay32(n) không thể delay dưới 11 chu kỳ máy. Để delay dưới 11 chu kỳ máy thì bạn có thể dùng một số lệnh nop liên tiếp.

Để delay các thời gian trong tầm ms thì chỉ cần dùng một trong những timer. Bạn hãy tham khảo các tutorial đầu tiên mà tôi đã viết cho dsPIC30F, chúng hoàn toàn có thể áp dụng cho PIC24.

Thân,
Chào bạn,
Mỉnh không biết vì lý do gì, nhưng mình dùng hàm __delay32(n), với n = 11 thì thời gian delay là 1.6us, mình dùng máy hiện sóng để đo.
enti vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 10-08-2009, 11:29 AM   #8
enti
Đệ tử 2 túi
 
Tham gia ngày: Nov 2006
Bài gửi: 26
:
Đây là đoạn code mình mới viết,
sử dụng câu lệnh repeat của asm để thực hiện các câu lệnh nop.

Code:
void Delayus( unsigned int u2_Timer)
{
	register int abcd asm("w0");
	mnop = (((u2_Timer - 1) * 16));
	abcd = mnop;
	asm ("REPEAT  W0");
	asm ("nop");
}
Các bạn củng thảo luận để đưa ra cách tính chình xác.
enti vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 10-08-2009, 02:04 PM   #9
bebungbu
Đệ tử 1 túi
 
Tham gia ngày: Jun 2009
Bài gửi: 25
:
Trích:
Nguyên văn bởi enti View Post
Đây là đoạn code mình mới viết,
sử dụng câu lệnh repeat của asm để thực hiện các câu lệnh nop.

Code:
void Delayus( unsigned int u2_Timer)
{
	register int abcd asm("w0");
	mnop = (((u2_Timer - 1) * 16));
	abcd = mnop;
	asm ("REPEAT  W0");
	asm ("nop");
}
Các bạn củng thảo luận để đưa ra cách tính chình xác.
Code này chạy ở tốc độ nào vậy bạn?
bebungbu vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 10-08-2009, 03:52 PM   #10
enti
Đệ tử 2 túi
 
Tham gia ngày: Nov 2006
Bài gửi: 26
:
Trích:
Nguyên văn bởi bebungbu View Post
Code này chạy ở tốc độ nào vậy bạn?
Code chạy ở tốc độ 32Mhz.
Config của PIC24F
Code:
_CONFIG1 (JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & ICS_PGx1 & FWDTEN_OFF & WINDIS_OFF & FWPSA_PR128 & WDTPS_PS1)
_CONFIG2 (IESO_OFF & PLLDIV_DIV5 & PLL_96MHZ_ON & FNOSC_PRIPLL & FCKSM_CSDCMD & OSCIOFNC_ON & IOL1WAY_OFF & DISUVREG_OFF & POSCMOD_HS)
enti vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 10-08-2009, 09:35 PM   #11
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Trích:
Nguyên văn bởi enti View Post
Chào bạn,
Mỉnh không biết vì lý do gì, nhưng mình dùng hàm __delay32(n), với n = 11 thì thời gian delay là 1.6us, mình dùng máy hiện sóng để đo.
Một trong những lý do là tần số thực thi lệnh của bạn không phải là giá trị mà tôi đã giả thiết (16 MIPS). Nói cách khác, tần số xung clock của bạn nhỏ hơn tần số giả định 32 MHz của tôi. Bạn kiểm tra lại xem.

Ngoài ra, bạn kiểm tra lại code hợp ngữ mà trình biên dịch đã tạo ra xem có phát sinh thêm lệnh thừa nào 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
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 11-08-2009, 12:34 PM   #12
enti
Đệ tử 2 túi
 
Tham gia ngày: Nov 2006
Bài gửi: 26
:
Trích:
Nguyên văn bởi namqn View Post
Một trong những lý do là tần số thực thi lệnh của bạn không phải là giá trị mà tôi đã giả thiết (16 MIPS). Nói cách khác, tần số xung clock của bạn nhỏ hơn tần số giả định 32 MHz của tôi. Bạn kiểm tra lại xem.

Ngoài ra, bạn kiểm tra lại code hợp ngữ mà trình biên dịch đã tạo ra xem có phát sinh thêm lệnh thừa nào hay không.

Thân,
Mình đã kiểm tra, theo như config mình đã post,
Code:
_CONFIG1 (JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF &
               ICS_PGx1 & FWDTEN_OFF & WINDIS_OFF & FWPSA_PR128 & WDTPS_PS1)
_CONFIG2 (IESO_OFF & PLLDIV_DIV5 & PLL_96MHZ_ON & FNOSC_PRIPLL &
               FCKSM_CSDCMD & OSCIOFNC_ON & IOL1WAY_OFF & DISUVREG_OFF & POSCMOD_HS)
theo mình nghĩ thì đúng 32Mhz, ngoài ra mình có dùng REFO để đo, đúng 32Mhz.
Vì mình muốn viết function giống CCS, tức là cần delay bao nhiêu us thì truyền tham số vào.
vì vậy mình viết hàm delayus(unsigned int u2_timer), có thể chính việc gọi hàm làm thời gian delay không đúng theo lý thuyết nữa.
Để xem được code asm khi compile bằng C30, thì làm như thế nào? Mình dùng MPLAB nên khi compile xong ko có file mã asm.
Cám ơn nhiều.
enti vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 11-08-2009, 02:11 PM   #13
bien_van_khat
...Damned...
 
bien_van_khat's Avatar
 
Tham gia ngày: Apr 2006
Nơi Cư Ngụ: Hồ Chí Minh
Bài gửi: 522
:
Trích:
Nguyên văn bởi enti View Post
Để xem được code asm khi compile bằng C30, thì làm như thế nào? Mình dùng MPLAB nên khi compile xong ko có file mã asm.
View/Disassembly Listing
__________________
- Xin đọc trước khi post bài

Xin đặt code trong thẻ [ code ] [ /code ]
bien_van_khat vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 26-09-2009, 02:41 AM   #14
popeye_ts22
Đệ tử 2 túi
 
popeye_ts22's Avatar
 
Tham gia ngày: Jul 2008
Nơi Cư Ngụ: Hà Nội
Bài gửi: 42
:
Send a message via Yahoo to popeye_ts22
Smile Thạch anh và delay

Cho em hỏi sao trong các đoạn config đầu tiên của PIC24 viết bằng C30 không thấy nói đến tần số thạch anh mình dùng trên mạch nhỉ (ví dụ như CCS là #use delay(clock=8000000) ).
Em muốn delay_ms trong C30 không dùng timer nhưng thử mấy đoạn code sau đều không được nhỉ, em nghĩ hàm delay thực chất chỉ là thực hiện vòng lặp liên tục thui đúng không các anh...
Bác nào làm Pic24F trên C30 rùi chỉ em cách tạo hàm delay mà ko dùng timer nhé...
Code:
 #include <p24FJ128GA010.h>

_CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & COE_OFF & FWDTEN_OFF & ICS_PGx2) 
_CONFIG2( FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMOD_HS & FNOSC_PRI)

#define DELAY_1MS 16000/9
void  DelayMs(unsigned int time){
unsigned delay;
while(time--)
for(delay=0; delay<DELAY_1MS; delay++); 
}
int main(void)
{
TRISA=0;
while(1){
PORTA=0XFFFF;
DelayMs(1000);
PORTA=0x0000;
}
}
__________________
Best Regard.

thay đổi nội dung bởi: popeye_ts22, 26-09-2009 lúc 02:47 AM.
popeye_ts22 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-10-2009, 05:19 PM   #15
npbaoduy
Đệ tử 2 túi
 
Tham gia ngày: Sep 2008
Nơi Cư Ngụ: Tp. HCM
Bài gửi: 38
:
Theo mình nghĩ C30 không có khai báo tần số dao động và cũng không có hàm delay_ms hay delay_us như CCS.
Em xin hỏi một tí về delay mà không dùng timer, nếu như viết bằng asm thì chúng ta biết được một lệnh mất bao nhiêu chu kỳ máy, từ đó có thể viết một vòng lặp để thực hiện delay, nhưng với C30 thì sao? Làm sao mình biết một lệnh mất bao nhiêu chu kỳ máy?
npbaoduy vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 12:49 AM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam