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 08-08-2009, 12:19 PM   #1
bbaacc01
Đệ tử 1 túi
 
Tham gia ngày: Apr 2009
Bài gửi: 16
:
[Help] Xin gợi ý về FIFO hoặc cái gì tương tự

Xin mọi người cho ý kiến về cách giải quyết vấn đề được nêu sau đây của mình

Mình sử dụng dspic33F
Giả sử mình cần làm một đối tượng giống như một FIFO RAM có kích thuớc là 1024 byte

Đầu ra của RAM là khi đọc RAM, sau khi đọc thì số byte có thông tin hữu ích trong RAM giảm xuống
Đầu vào của RAM, ghi dữ liệu vào RAM, nếu ghi đầy thì không cho ghi nữa hoặc set 1 cờ nào đó để báo đã đầy RAM để phía ghi biết mà không ghi dữ liệu vào nữa.
Đầu ra và đầu vào độc lập.

Mong mọi nguời hướng dẫn mình một ý tưởng để thực hiện việc này, mình định dùng module DMA nhưng thấy nó không giống ý của mình lắm.
Cảm ơn mọi nguời đã quan tâm
bbaacc01 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 18-11-2009, 07:08 PM   #2
phamminhtuan
Super Moderator
 
phamminhtuan's Avatar
 
Tham gia ngày: Feb 2006
Bài gửi: 150
:
Thế này được không ?
Code:
BYTE fifo[1024];
INT wrHead = 0;

BYTE push(BYTE b) {
    if(wrHead>1023) return 0;
    fifo[wrHead] = b;
    wrHead++;
    return 1;    
}

BYTE pop() {
    if(wrHead>=0){
        wrHead --;
        return fifo[wrHead+1];
        
    }
    return 0;
}

void ResetFifo() {
    wrHead = 0;    
}

thay đổi nội dung bởi: phamminhtuan, 20-11-2009 lúc 09:11 AM. Lý do: rd-->wr
phamminhtuan vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 18-11-2009, 08:57 PM   #3
bbaacc01
Đệ tử 1 túi
 
Tham gia ngày: Apr 2009
Bài gửi: 16
:
Thật cảm ơn anh đã trả gợi ý.

Cách làm của anh về lí mà nói thì đuợc rồi, tuy nhiên cách làm như vậy mình e là sẽ làm giảm hiệu suất của PIC đi rất nhiều, cứ mỗi lần chúng ta ghi và đọc chúng ta lại phải kiểm tra xem FIFO buffer có đang đầy hay đang rỗng không, không biết có cách nào ít số lần kiểm tra hơn không nhỉ ?
Dù sao cũng rất cảm ơn mod đã gợi ý.
bbaacc01 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 19-11-2009, 08:54 AM   #4
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 bbaacc01 View Post
tuy nhiên cách làm như vậy mình e là sẽ làm giảm hiệu suất của PIC đi rất nhiều
Theo bạn thì rất nhiều như thế nào? Bạn có tính thực hiện so sánh như vậy cần bao nhiêu lệnh? trường hợp xấu nhất cần bao nhiêu chu kỳ máy?....
__________________
- 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 19-11-2009, 12:15 PM   #5
bbaacc01
Đệ tử 1 túi
 
Tham gia ngày: Apr 2009
Bài gửi: 16
:
Nhìn duới góc độ mã ASM đi, với dspic

một lệnh ghi hoặc đọc dữ liệu bình thường sẽ thực hiện tốt nhất là 1 chu kì lệnh nếu có tham số là thanh ghi. Cứ kể nó là 3 chu kì lệnh (để bù vào các cái râu ria đi).

Ở trường hợp này (Mình chỉ lấy ví dụ của anh Tuan để giải thích, không có ý gì khác, mong anh Tuan bỏ qua)
Code:
BYTE push(BYTE b) {
    if(wrHead>1023) return 0;
    fifo[wrHead] = b;
    wrHead++;
    return 1;    
}
Vì số 1023 là một số không thể so sánh trực tiếp đuợc, nên nó phải chuyển vào một thanh ghi nào đó ==> tốn 1 lệnh di chuyển
Thực hiện so sánh 1 lần ==> một lệnh so sánh
Thực hiện lệnh rẽ nhánh, trường hợp code tốt nhất thì vẫn tốn một chu kì lệnh

==> Tốn thêm 3 chu kì lệnh.

Như vậy để thực hiện việc di chuyển 1 dữ liệu chúng ta cần
6 chu kì lệnh, 3 để di chuyển, 3 để kiểm tra
hiệu suất của quá trình này là 3/(3+3) = 50%, từ 100% xuống còn 50% là nhiều rồi
bbaacc01 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 19-11-2009, 03:19 PM   #6
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 bbaacc01 View Post
Nhìn duới góc độ mã ASM đi, với dspic

một lệnh ghi hoặc đọc dữ liệu bình thường sẽ thực hiện tốt nhất là 1 chu kì lệnh nếu có tham số là thanh ghi. Cứ kể nó là 3 chu kì lệnh (để bù vào các cái râu ria đi).

Ở trường hợp này (Mình chỉ lấy ví dụ của anh Tuan để giải thích, không có ý gì khác, mong anh Tuan bỏ qua)
Code:
BYTE push(BYTE b) {
    if(wrHead>1023) return 0;
    fifo[wrHead] = b;
    wrHead++;
    return 1;    
}
Vì số 1023 là một số không thể so sánh trực tiếp đuợc, nên nó phải chuyển vào một thanh ghi nào đó ==> tốn 1 lệnh di chuyển
Thực hiện so sánh 1 lần ==> một lệnh so sánh
Thực hiện lệnh rẽ nhánh, trường hợp code tốt nhất thì vẫn tốn một chu kì lệnh

==> Tốn thêm 3 chu kì lệnh.

Như vậy để thực hiện việc di chuyển 1 dữ liệu chúng ta cần
6 chu kì lệnh, 3 để di chuyển, 3 để kiểm tra
hiệu suất của quá trình này là 3/(3+3) = 50%, từ 100% xuống còn 50% là nhiều rồi
Quá trình so sánh bằng cách trừ cần 4 chu kỳ máy vì sau khi trừ phải phục hồi lại giá trị cũ để làm tham số cho đoạn code copy dữ liệu. Thay vì vậy, nếu so sánh với 1024 bằng cách test bit 10 thì chỉ cần 3 chu kỳ máy.

Quá trình copy dữ liệu vào mảng cần 5 chu kỳ máy vì luôn phải tăng wrHead, ngoài ra cần thêm 4 chu kỳ máy của lệnh call và return.

Thực tế nếu code đoạn mã trên bằng asm thì nhìn chung số chu kỳ máy tăng thêm chỉ khoảng 3, từ 9 lên 12.

Nếu chương trình của bạn chỉ làm mỗi việc push/pop thì hiệu suất công việc của bạn sẽ giảm đi 33%.
__________________
- 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 20-11-2009, 09:08 AM   #7
cskiller
Đệ tử 4 túi
 
Tham gia ngày: Aug 2008
Bài gửi: 89
:
Đây là gợi ý về 1 FIFO vòng, tức không cần reset các index, rdCount và wrCount sẽ tự động quay vòng giá trị trên Buffer nếu FIFO chưa đầy.

Code:
#define BUFFER_SIZE			(unsigned int)1024
#define BUFFER_SIZE_MASK	        (unsigned int)(BUFFER_SIZE-1)	//1023 = 0x3FF
#ifndef BYTE
typedef unsigned char BYTE;
#endif

unsigned int wrCount=0;
unsigned int rdCount=0;
BYTE fifo_buff[BUFFER_SIZE];

void FIFO_Init()
{
	rdCount=wrCount;	//With any value -> FIFO Empty
}

BYTE FIFO_Full()
{
	return (((wrCount+1)&BUFFER_SIZE_MASK)==rdCount);
}

BYTE FIFO_Empty()
{
	return (rdCount==wrCount);
}

unsigned int FIFO_Size()
{
	return ((wrCount-rdCount)&BUFFER_SIZE_MASK);
}

void FIFO_Push(BYTE data)
{
	fifo_buff[wrCount]=data;
	wrCount++;
	wrCount&=BUFFER_SIZE_MASK;
}

BYTE FIFO_Pop()
{
	BYTE ret;
	ret=fifo_buff[rdCount];
	rdCount++;
	rdCount&=BUFFER_SIZE_MASK;
	return (ret);
}


FIFO_Init();
...
if(!FIFO_Full()) FIFO_Push('A');
...
if(!FIFO_Empty()) FIFO_Pop();
...
printf("Current Data Size in FIFO=%d",FIFO_Size());
...
__________________
Quang báo RG/RGB 6/8/12/16 bits màu
Phone No: 0905.034.086
Email: lmquyen@gmail.com
cskiller vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 22-11-2009, 11:34 PM   #8
bbaacc01
Đệ tử 1 túi
 
Tham gia ngày: Apr 2009
Bài gửi: 16
:
Cảm ơn mọi người đã chỉ giúp, mình sẽ thử.
bbaacc01 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à 10:25 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