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 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à
PHP Code:
_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
PHP Code:
_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT)
Tắt luôn cả Watchdog
PHP Code:
_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
Và các định nghĩa thanh ghi điều khiển timer1 trong file header .h
PHP Code:
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
PHP Code:
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
PHP Code:
#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