PDA

View Full Version : Học PIC 16 bit với dsPIC33Fj256GP710 và C30


phamminhtuan
15-08-2008, 03:16 PM
Với khả năng tính toán mạnh mẽ, các module ngoại vi phong phú, tài liệu hỗ trợ phong phú, đầy đủ... và 1 điều quan trọng là VĐK 16 bit của Microchip khá rẻ...

Vậy là mình quyết định mùa hè này sẽ phải "nghiên cứu" thằng này, sau khi đọc được nhiều bài viết của các thành viên trên diễn đàn và có vài ngày tìm hiểu, mình quyết định mở luồng này với mục đích vừa học vừa viết, học được gì viết cái đó, có thể mình nghĩ đây là phương pháp hay để có thể học nhanh dsPIC, ngoài ra còn có thể giúp cho những người khác muốn học dsPIC thuận tiện hơn. (Tạm thời mình khóa luồng này để viết xong, trong quá trình viết cũng có nhiều sai sót, mọi người có thể PM trực tiếp cho mình hoặc mở 1 luồng mới)

Trước hết, cần phải chuẩn bị đầy đủ "đồ nghề" để bắt đầu:


Phần mềm:

MPLAB IDE - Bộ công cụ phát triển phần mềm cho các sản phẩm PIC của Microchip
(http://ww1.microchip.com/downloads/en/DeviceDoc/mp810.zip)
MPLAB C30 - Trình biên dịch C30 cho PIC 16 Bit. - Tải bản Student (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en010065)
Ngoài ra bạn có thể sử dụng trình mô phỏng như Proteus


Phần cứng:

ICD2 - Mạch nạp và debug, mình nghĩ đây là công cụ cần thiết, bạn có thể tự làm hay đặt mua thì tùy, nhưng nó thật sự hữu hiệu khi dùng với MPLAB, ICD2 kết nối với máy tính qua cổng USB
Một KIT phát triển cho dsPIC, bạn có thể dùng loại nào thì tùy, nhưng nhớ là có khe cắm cho ICD2 để debug


Tài liệu

Datasheet của dsPIC33Fj256GP710 (http://ww1.microchip.com/downloads/en/DeviceDoc/70286A.pdf)
Sách học: Newnes.Programming.16-Bit.PIC.Microcontrollers.in.C (http://www.box.net/shared/k88eo2udje)
http://www.opencircuits.com/DsPIC30F_5011_Development_Board
Code mẫu từ Microchip (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2622)
Tài liệu hướng dẫn C30 trong thư mục cài đặt [C:\Program Files\Microchip\MPLAB C30\docs]


Một vài link hữu ích đã được đưa lên đầu trong Forum này, các bạn nên xem qua
Vài tấm ảnh về phần cứng - Board Explorer 16 (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en024858&part=DM240001) cho dsPIC33FJ256GP710 và ICD2

http://lh5.ggpht.com/phamminhtuan.04/SKT91gLijSI/AAAAAAAABJ0/fz73kBCGCXE/DSC00027.JPG?imgmax=800

http://lh4.ggpht.com/phamminhtuan.04/SKT9ySlm0sI/AAAAAAAABJw/SiY8X06CBP4/DSC00028.JPG?imgmax=800

Sau khi kết nối vào máy tính, do đã cài đặt MPLAB, nên máy tính sẽ tự nhận driver.

Việc cấu hình Compiler sẽ dành cho bài đầu tiên tiếp theo.
PS: Mình có 1 lời khuyên cho các bạn muốn học dsPIC, hãy đầu tư thật sự nghiêm túc cả về thời gian và tiền bạc, bạn nên bỏ tiền ra để mua các bộ công cụ Development Tools để tránh mất thời gian cho việc thiết kế và lỗi phần cứng, và dành nhiều thời gian cho việc lập trình.

phamminhtuan
16-08-2008, 12:19 AM
Vì ICD2 kết nối qua cổng USB của máy tính, nên nó sẽ đòi driver khi được cắm vào lần đầu tiên, tất cả các bước làm có thể xem hình minh họa

http://lh5.ggpht.com/phamminhtuan.04/SKWgFEPn5aI/AAAAAAAABKE/ifkhGu9nkF4/Magical%20Snap%20-%202008.08.15%2022.23%20-%20001.png?imgmax=800

http://lh6.ggpht.com/phamminhtuan.04/SKWgEaaj9yI/AAAAAAAABKA/JYMbTHlohIU/Magical%20Snap%20-%202008.08.15%2022.23%20-%20002.png?imgmax=800

Driver nằm trong thư mục cài đặt của MPLAB, mặc định là [C:\Program Files\Microchip\MPLAB IDE\ICD2]


http://lh5.ggpht.com/phamminhtuan.04/SKWgAx04eCI/AAAAAAAABJ4/74_F4IXsY58/Magical%20Snap%20-%202008.08.15%2022.24%20-%20003.png?imgmax=800

http://lh3.ggpht.com/phamminhtuan.04/SKWgDuR74dI/AAAAAAAABJ8/593b3a6ajpE/Magical%20Snap%20-%202008.08.15%2022.24%20-%20004.png?imgmax=800

Chờ trong giây lát, như vậy là xong phần cài đặt Driver cho ICD2.

Tiếp đến, chúng ta sẽ tạo một Project đơn giản để dùng ICD2 nạp thử cho dsPIC.

Tại menu Project -> Project Winzard
http://lh3.ggpht.com/phamminhtuan.04/SKWlwKBZlgI/AAAAAAAABKc/AfOr7Xq2L_U/Magical%20Snap%20-%202008.08.15%2022.29%20-%20007.png?imgmax=800

Chọn đúng loại dsPIC định sử dụng, ở đây là dsPIC33FJ256GP710
http://lh3.ggpht.com/phamminhtuan.04/SKWlvI5p9CI/AAAAAAAABKY/Vj9RywzzJ1c/Magical%20Snap%20-%202008.08.15%2022.29%20-%20008.png?imgmax=800

Chọn trình biên dịch sử dụng là Microchip C30 Toolsuite, dĩ nhiên là phải được cài đặt trước. Ngoài ra, nếu là lần khởi động đầu tiên thì có thể sẽ thấy dấu đỏ, MPLAB không nhận biết được đường dẫn đến chỗ trình dịch C30, bạn có thể trỏ nó đến, với tên file như trong MPLAB đã hướng dẫn, còn thừ mục chứa các file cần trỏ đến của C30 ở [C:\Program Files\Microchip\MPLAB C30\bin], Nếu được như hình dưới đây là ổn

http://lh3.ggpht.com/phamminhtuan.04/SKWlunMj_OI/AAAAAAAABKU/tygcCQGhId4/Magical%20Snap%20-%202008.08.15%2022.30%20-%20009.png?imgmax=800

Chọn Next->và chọn đường dẫn lưu Project vào, đặt tên như ở dưới
http://lh3.ggpht.com/phamminhtuan.04/SKWluEEtQ-I/AAAAAAAABKQ/Ev6_9sQRHUQ/Magical%20Snap%20-%202008.08.15%2022.31%20-%20011.png?imgmax=800


Save -> Next -> Finish

Hiện tại trong Project của bạn chưa có file code nào, do đó, cần tạo 1 file gọi là test_icd2.c, sau đó lưu vào thư mục vừa lưu project xong

Nếu bạn không thấy cửa sổ project thì vào Menu View->Project
tiếp theo, nhấp phải chọn add file, và thêm file test_icd2.c vào Project
http://lh4.ggpht.com/phamminhtuan.04/SKWoMaeha6I/AAAAAAAABKk/aREkAWjG2G8/Magical%20Snap%20-%202008.08.15%2023.00%20-%20014.png?imgmax=800

Bây giờ bạn có thể viết 1 nội dung đơn giản cho file code và biên dịch
http://lh6.ggpht.com/phamminhtuan.04/SKWls_LhTSI/AAAAAAAABKI/-YQI7MDdUOA/Magical%20Snap%20-%202008.08.15%2022.33%20-%20013.png?imgmax=800

Tiếp theo, chọn Debugger->Select Tool->MPLAB ICD2
http://lh4.ggpht.com/phamminhtuan.04/SKWpSVUlREI/AAAAAAAABKs/x69PfPZ6wGw/Magical%20Snap%20-%202008.08.15%2023.04%20-%20015.png?imgmax=800

Và không có vấn đề gì thì sẽ được cửa sổ Output như sau
http://lh5.ggpht.com/phamminhtuan.04/SKWpRnp5s8I/AAAAAAAABKo/Uon6Q45eVCI/Magical%20Snap%20-%202008.08.15%2023.04%20-%20016.png?imgmax=800

Tiếp theo nạp thử chương trình và chạy cho chạy thử nghiệm:

http://lh3.ggpht.com/phamminhtuan.04/SKWqF5rWOnI/AAAAAAAABKw/U3UXLV3DxfE/Magical%20Snap%20-%202008.08.15%2023.07%20-%20017.png?imgmax=800

Vậy là xong phần đầu tiên, cửa sổ Output của MPLAB và kết quả như sau:
http://lh6.ggpht.com/phamminhtuan.04/SKWsVoNu9KI/AAAAAAAABK4/38722AB-_W4/Magical%20Snap%20-%202008.08.15%2023.09%20-%20018.png?imgmax=800

http://lh3.ggpht.com/phamminhtuan.04/SKWsS6b2b1I/AAAAAAAABK0/qsjEt-zjeC4/DSC00030.JPG?imgmax=800

phamminhtuan
16-08-2008, 01:03 AM
Kết nối phần cứng đến đây là tạm ổn, từ giờ về sau, hầu như mọi công việc mà chúng ta phải làm là học và viết phần mềm trên C30. Cần nói sơ lược về cấu trúc chương trình viết cho VĐK như sau:

Trình biên dịch C30 sẽ dịch trỏ đến hàm main() sau khi reset, có nghĩa là mọi hoạt động của VĐK bắt đầu ở hàm main(), sau khi CPU thực hiện hết chuỗi lệnh trong hàm này mà không có 1 lệnh rẽ nhánh hay chuyển hướng nào thì nó sẽ nạp cho bằng hết các mã lệnh trong Flash, cho đến địa chỉ cuối cùng và nhảy về địa chỉ ban đầu, reset và tiếp tục như vậy. Nhưng chúng ta thì không muốn thế, bao giờ mình cũng cần khởi tạo các giá trị nào đó và sau đó là muốn CPU thực hiện công việc gì đó lặp đi lặp lại, vì vậy cần phải lưu ý đến vòng lặp vô hạn để giữ cho CPU làm việc trong 1 chu trình nhất định.

#include ....
void function1() {
...
}
char function2() {
...
}

void main() {
//Chương trình chính nằm ở đây
while(1) {
//Chương trình thực hiện lặp đi lặp lại ở đây
}
}
Comment

//Đây là dòng comment đơn, trình dịch sẽ bỏ qua tất cả sau 2 dấu //
/*
Đây là block comment, trình dịch sẽ bỏ qua tất cả nằm giữa 2 dấu
này
*/
Kiểu dữ liệu và khai báo,

unsinged char uchar1, uchar2, uchar3 = 'a', uchar4; //kiểu ký tự 8 bit
//không âm, giới hạn từ 0-255

char c1, c2;
signed char sc1, sc2; //cả cách khai báo đều tạo ra biến mang dấu 8 bit,
// giới hạn từ -128 đến 127

unsigned short us1, us2;
unsigned int ui1, ui2; //hai kiểu này không dấu, dương, 16 bit,
//giới hạn từ 0 đến 65535

int ia, ib;
signed int sia, sib; //Hai cách khai báo khác nhau,
//nhưng tạo ra 1 biến int 16 bit, mang dấu, giới hạn từ -32768 đến 32767

short sa, sb;
signed short ssa, ssb; //Hai cách khai báo khác nhau,
//nhưng tạo ra 1 biến short 16 bit, mang dấu, giới hạn từ -32768 đến 32767

unsigned long ul1, ul2; //32 bit, không dấu
signed long sl1, sl2; //32bit có dấu
long l1, l2; //tương tự cách khai báo với signed

unsigned long long ll1, ll2; //64bit nguyên, không dấu
long long sll1, sll2; //64 bit nguyên có dấu
signed long long sll1, sll2; //64 bit nguyên có dấu

double d1, d2; //dấu chấm động 32 bit
float f1, f2; //số thực, dấu chấm động 32 bit
long double ld1; //dấu chấm động 64 bit
Khai báo mảng, chuỗi, con trỏ

char carray[] = {1,2,3,4,5}; //Khai báo mảng kiểu Char gán luôn 5 phần tử,
//carray[0] = 1 và carray[4] = 5

int iarray[5]; //khai báo vùng biến kiểu Int, chưa gán

char str[] = "abc"; //Khai báo chuỗi, hay mảng ký tự
// str[0] = 'a';
// str[1] = 'b';
// str[2] = 'c';
// str[3] = '\0'
char str1[20] = "Hello Picvietnam"; //ok,

//Khai báo mảng 2 chiều
char str1[2][2] = {{'a', 'b'}, {'c','d'}};
//truy xuất mảng hai chiều
//str1[0][0] = 'a';...
//str1[1][1] = 'd';

//Khai báo con trỏ, dữ liệu loại nào thì khai báo con trỏ loại đó
char x;
char *ptr_x = &x;
//ptr_x mang giá trị là địa chỉ của x, *ptr_x mang giá trị của x

float f[] = {0.1, 0.2, 0.3};
float *ptr_f = &f;
//*ptr_f = f[0]
//*(ptr_f+1) = f[1]
//(*ptr_f+1) = 1.1

//Khai báo const với con trỏ
const char *menu[3] = {"Main" , "Sub", "Sub2"};

Cấu trúc

struct complex {
float re;
float im;
} a;
//Định nghĩa kiểu số phức được gọi là a
//sử dụng như sau
struct complex b;
a.re = 2.5;
b.im = 1.0;

//1 cách khác
typedef struct ComplexNumber {
float re;
float im;
} complex;
//complex như là 1 kiểu dữ liệu, sử dụng như sau
complex a = {1.1, 1.2};
complex b;
b.im = a.im;
//Sử dụng cấu trúc trong cấu trúc
struct point {
float x;
float y;
}
struc line {
struct point a;
struct point b;
}
//sử dụng
struct line my_line;
my_line.a.x = 1.2;
my_line.b.x = 2.0;

Con trỏ và cấu trúc

//con trỏ và cấu trúc
struct Strings {
char A[4];
chat *B;
} str;
//sử dụng
str.A[0] = 'r';
str.A[1] = 'e';
str.A[2] = 'd';
str.A[3] = '\0';
str.B = "Hello Wold";

typedef struct ComplexNumber {
float re;
float im;
} complex;
//
complex a = {1.2, 2.2};
complex *b;
b = &a;
b->re += 3.0; //a.re = 4.2
b->im -= 1; //a.im = 1.2


Kiểu hợp và Bit Fields

typedef union {
char a;
int b;
float c;
} u_test;
//sử dụng
u_test x, y;
x.a = 'A';
x.b = 0xFF00;
y.c = 0.1;

//Bit Fields
typedef struc {
bit0:1;
bit1:1;
bit23:2;
bit4567:4;
} bitfields;

bitfieds c;
c.bit0 = 1;
c.bit23 = 3; //ok,
c.bit4567 = 0x0F; //ok,
}


Kiểu liệt kê

enum colors {RED=1, GREEN, BLUE};//GREEN = 2, BLUE=3
int sum = REG+GREEN+BLUE; //6

enum colors {RED, GREEN, BLUE};
enum colors pixel;
pixel = RED; //0



Phần C các bạn có thể xem thêm lập trình ANSI C và MPLAB® C30 User’s Guide đã cung cấp link

phamminhtuan
16-08-2008, 11:37 PM
Như đã trình bày ở bài đầu, mình sẽ sử dụng Board Explorer 16 (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en024858&part=DM240001) với dsPIC33FJ256GP710 và nạp, debug ICD2 sử dụng MPLAB, bạn có thể tìm hiểu thông tin thêm về board Explorer 16 trên Website của Microchip, (http://www.microchip.com/Microchip.WWW.SecureSoftwareList/secsoftwaredownload.aspx?device=en024858&lang=en&ReturnURL=http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en024858&part=DM240001#) có thể tự làm nếu muốn, cả ICD2 cũng thế, một vài hình ảnh chính để tham khảo nhanh phần cứng khi viết chương trình trênBoard Explorer 16

http://lh3.ggpht.com/phamminhtuan.04/SKbzSoDyyGI/AAAAAAAABLM/VPXq7x98c8g/Magical%20Snap%20-%202008.08.16%2022.30%20-%20002.png?imgmax=800

http://lh4.ggpht.com/phamminhtuan.04/SKbzQmqXUUI/AAAAAAAABLI/hdfyuyJifS4/Magical%20Snap%20-%202008.08.16%2022.30%20-%20003.png?imgmax=800

http://lh5.ggpht.com/phamminhtuan.04/SKbzPcsJDzI/AAAAAAAABLE/-aolgXxU9O0/Magical%20Snap%20-%202008.08.16%2022.31%20-%20004.png?imgmax=800

http://lh3.ggpht.com/phamminhtuan.04/SKbzNzQJZ7I/AAAAAAAABLA/IxOIJxNBiLo/Magical%20Snap%20-%202008.08.16%2022.31%20-%20005.png?imgmax=800

http://lh4.ggpht.com/phamminhtuan.04/SKbzMljn0DI/AAAAAAAABK8/amA090jgvfo/Magical%20Snap%20-%202008.08.16%2022.31%20-%20006.png?imgmax=800

phamminhtuan
17-08-2008, 01:09 AM
Bài này mình nói về hàm printf là hàm xuất chuẩn của C ra UART, hay ra bất cứ thiết bị nào, khi học C30, chúng ta nên sử dụng nó và MPLAB SIM như công cụ để xem và kiểm tra kết quả.

cấu trúc của printf

printf( control string, arg1, arg2..);


Ví dụ

printf("Var x: %d", x);
các kí tự điều khiển
c - kí tự đơn
s - một chuỗi, kết thúc với kí tự '\0'
d - một số nguyên có dấu
o - số hệ 8, không dấu
u - số nguyên không dấu
x - số hệ 16, hex, không dấu, chữ thường
X - số hệ 16, hex, không dấu, chữ hoa
f - số thực, có dấu
e - số nguyên có dấu với số mũ, (ex: 1.23e-5)
E - số nguyên có dấu với mũ, (ex: 1.23E-5)
g - giống f nhưng phụ thuộc vào kích cỡ và kiểu của biến
G - giống g nhưng kết quả có thêm E, 1.23E-5

Sử dụng cần có header stdio.h
Sau đây là các bước tạo 1 project với MPLAB và sử dụng MPLAB SIM để mô phỏng, xem ngõ ra sử dụng printf


Tạo 1 project với project winzard

http://lh5.ggpht.com/phamminhtuan.04/SKcHjxq2N5I/AAAAAAAABL8/RRMpWM2vjTk/Magical%20Snap%20-%202008.08.16%2023.50%20-%20007.png?imgmax=800


Chọn đúng loại dsPIC mà mình đang sử dụng

http://lh4.ggpht.com/phamminhtuan.04/SKcHjXKfDLI/AAAAAAAABL4/bdCxfjssiAI/Magical%20Snap%20-%202008.08.16%2023.50%20-%20008.png?imgmax=800



Chọn trình biên dịch sẽ sử dụng, ở đây chọn C30

http://lh6.ggpht.com/phamminhtuan.04/SKcHjFGWLTI/AAAAAAAABL0/XyiCVktTNaU/Magical%20Snap%20-%202008.08.16%2023.50%20-%20009.png?imgmax=800



Next, và cho đến khi Finish, xong hãy tạo 1 file mới có tên printf.c, lưu vào và add vào project, tiếp đến add file link script vào, ở thư mục [C:\Program Files\Microchip\MPLAB C30\support\gld]

http://lh5.ggpht.com/phamminhtuan.04/SKcHikGnoPI/AAAAAAAABLw/ctF4Z0s_1Ok/Magical%20Snap%20-%202008.08.16%2023.54%20-%20013.png?imgmax=800

http://lh4.ggpht.com/phamminhtuan.04/SKcHh1iB9tI/AAAAAAAABLs/CR3bRZPt-VI/Magical%20Snap%20-%202008.08.16%2023.54%20-%20014.png?imgmax=800

http://lh5.ggpht.com/phamminhtuan.04/SKcHhC19x0I/AAAAAAAABLo/1b4d9LLFsMg/Magical%20Snap%20-%202008.08.16%2023.55%20-%20015.png?imgmax=800

http://lh4.ggpht.com/phamminhtuan.04/SKcHgaWDFuI/AAAAAAAABLk/L-eQXCZHYIM/Magical%20Snap%20-%202008.08.16%2023.55%20-%20016.png?imgmax=800

http://lh6.ggpht.com/phamminhtuan.04/SKcHf5AbH0I/AAAAAAAABLg/rhu5IS4xXlI/Magical%20Snap%20-%202008.08.16%2023.56%20-%20017.png?imgmax=800

http://lh3.ggpht.com/phamminhtuan.04/SKcHfXXiKzI/AAAAAAAABLc/dNco29wOx1U/Magical%20Snap%20-%202008.08.16%2023.56%20-%20018.png?imgmax=800

Chương trình đơn giản như sau
http://lh5.ggpht.com/phamminhtuan.04/SKcHewDSLpI/AAAAAAAABLY/6gYyTPD7aRc/Magical%20Snap%20-%202008.08.16%2023.57%20-%20019.png?imgmax=800

Biên dịch vào debug
http://lh5.ggpht.com/phamminhtuan.04/SKcHeDZBduI/AAAAAAAABLU/76Xk-FJ2Uls/Magical%20Snap%20-%202008.08.16%2023.58%20-%20021.png?imgmax=800


Kết quả cuối cùng
http://lh5.ggpht.com/phamminhtuan.04/SKcHdSk02iI/AAAAAAAABLQ/Or6Sfz1XHwA/Magical%20Snap%20-%202008.08.16%2023.58%20-%20022.png?imgmax=800

phamminhtuan
17-08-2008, 01:22 AM
Bây giờ bạn có thể làm với các bước như trên để tạo ra 1 project để học C30
chương trình sau khá đơn giản để xem hàm printf hiển thị các biến như thế nào


#include<p33fj256gp710.h>
#include<stdio.h>


int main(void) {
char c1 = -2;
unsigned char c2 = 100;
unsigned char c3 = 'a';

char *str = "Hello Picvietnam.com";

unsigned int i = 0xfFAa;

float f=1.234;

printf("[c1: %d] - [c2: %d] - [c3: %c]\n",c1,c2,c3);
printf("Str: %s\n", str);
printf("float: %3f\n", f);
printf("int hex1: %x - hex2: %X - Dec: %d", i, i, i);
while(1);
}



Kết quả:
http://lh4.ggpht.com/phamminhtuan.04/SKcMrZ2DNgI/AAAAAAAABMA/ejlkqMetOCg/Magical%20Snap%20-%202008.08.17%2000.20%20-%20024.png?imgmax=800

phamminhtuan
20-08-2008, 04:34 PM
Với bài viết này, yêu cầu là điều khiển chớp tắt các LED được nối với PORT A từ PORTA.0 đến PORTA.7

Trước tiên, để tính toán thời gian chạy cần phải cấu hình dao động cho dsPIC, phần này các bạn có thể tham khảo luồng Căn bản về dsPIC (http://www.picvietnam.com/forum/showthread.php?t=2134)của Bang chủ và xem chi tiết file p33fj256gp710.h trong thư mục [C:\Program Files\Microchip\MPLAB C30\support\h]

Yêu cầu như thế nào, hãy xem file p33fj256gp710.h từ dòng 8825 sẽ có hướng dẫn cụ thể. Trong bài này chúng ta sẽ dùng thạch anh 4Mhz, không dùng PLL, nêu dòng tiếp theo sau dòng #include<p33fj256gp710.h> là

_FOSCSEL(FNOSC_PRI & IESO_OFF & TEMP_OFF)
với 2 tùy chọn thêm là disable Startup với 2 tốc độ, và tắt chế độ bảo vệ nhiệt độ

Tiếp theo là cấu hình Clock switching và clock monitor, OSC2 Pin function, tắt cả và chọn chế độ XT

_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT)
Tắt luôn cả Watchdog

_FWDT(FWDTEN_OFF)
Các chức năng như Power-on Reset, Code Protect, Secure Segment Data Ram ... không dùng đến nên chưa đề cập ở đây

Vậy sau khi cấu hình như thế, thì Fosc = 4Mhz, và tốc độ của CPU lúc này là Fcy = 4Mhz/2 = 2Mhz

Bây giờ chúng ta tiến hành tìm hiểu về Timer1, việc dùng Timer sẽ tạo ra thời gian trễ chính xác hơn nhiều so với ngồi tính thời gian thực thi của từng lệnh. Sơ đồ khối mô tả hoạt động của Timer1
http://lh6.ggpht.com/phamminhtuan.04/SKvLdhvM_XI/AAAAAAAABMk/axjgxUlSnqU/Magical%20Snap%20-%202008.08.20%2014.44%20-%20041.png?imgmax=800
Và các định nghĩa thanh ghi điều khiển timer1 trong file header .h

extern volatile unsigned int TMR1 __attribute__((__sfr__));
extern volatile unsigned int PR1 __attribute__((__sfr__));
extern volatile unsigned int T1CON __attribute__((__sfr__));
__extension__ typedef struct tagT1CONBITS {
union {
struct {
unsigned :1;
unsigned TCS:1;
unsigned TSYNC:1;
unsigned :1;
unsigned TCKPS:2;
unsigned TGATE:1;
unsigned :6;
unsigned TSIDL:1;
unsigned :1;
unsigned TON:1;
};
struct {
unsigned :4;
unsigned TCKPS0:1;
unsigned TCKPS1:1;
};
};
} T1CONBITS;
extern volatile T1CONBITS T1CONbits __attribute__((__sfr__));
Giờ sẽ đến phần khởi tạo Timer1, Timer1 có thể chạy RealTime với thạch anh 32Khz, nhưng chúng ta chưa quan tâm, bây giờ hãy dùng Clock của nguồn dao động chính đã, tùy chọn nguồn dao động lúc này là Tcy chính là Fcy, vậy TGATE = TCS = 0 . Mình muốn cái timer1 này chạy đúng 1s thì cờ T1IF phất lên, Tcy = 2Mhz, mình chia 64, tức tần số của timer1 đếm lúc này là 2Mhz/64 = 31.25KHz, vậy mỗi xung đếm mất 1/31.25Khz = 32uS, tính ra 1s mất 1000.000/32 = 31250 xung, đây chính là giá trị nạp vào PR1, để khi timer1 đếm bằng từng này thì nó phất cờ T1IF lên, vậy mình sẽ viết 1 chương trình con như sau

void T1_init(void) {
T1CONbits.TCS = 0;
T1CONbits.TGATE = 0;
T1CONbits.TCKPS = 0b10; //chia 64
T1CONbits.TSYNC = 0;
T1CONbits.TON = 0;
TMR1 = 0;
PR1 = 31250;
}
Vậy là xong phần khởi tạo timer, chương trình chính như sau

#include<p33fj256gp710.h>
#include<stdio.h>
_FOSCSEL(FNOSC_PRI & IESO_OFF & TEMP_OFF)
_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT)
_FWDT(FWDTEN_OFF)

void T1_init(void) {
T1CONbits.TCS = 0;
T1CONbits.TGATE = 0;
T1CONbits.TCKPS = 0b10; //chia 64
T1CONbits.TSYNC = 0;
T1CONbits.TON = 0;
_T1IF = 0;
TMR1 = 0;
PR1 = 31250;
}

int main(void) {
unsigned char flag = 0;
T1_init();
T1CONbits.TON = 1;
TRISA = 0x0000;
PORTA = 0xFF00;
while(1) {
if(_T1IF) {
_T1IF = 0;
if(flag){
PORTA = 0xFFFF;
flag = 0;
printf("Xuat PORTA = 0xFFFF\n");
} else {
flag = 1;
PORTA = 0x0000;
printf("Xuat PORTA = 0x0000\n");
}
}

}
}
Chương trình đã được kiểm tra trên MPSIM, dùng lệnh printf để kiểm tra kết quả trên cửa sổ UART1, như hướng dẫn trên, cứ mỗi 1s thì chương trình sẽ thực hiện 1 lần , hình ảnh mô phỏng
http://lh4.ggpht.com/phamminhtuan.04/SKvY-qh2N5I/AAAAAAAABMs/HwOmGfDV6hM/Magical%20Snap%20-%202008.08.20%2015.42%20-%20043.png?imgmax=800