slide - Pay It Forward

Download Report

Transcript slide - Pay It Forward

04/06/2010
Giới thiệu PIC16F887
- Vi điều khiển 8-bit của Microchip, thuộc
dòng Low-power.
- Kiến trúc Harvard (vs. Von Neumann), tập
lệnh RISC (Reduced Instructions Set
Computer) (vs. Complexed Instructions Set
Computer)
- Thạch anh gắn ngoài tối đa 20MHz.
- Tầm điện áp hoạt động 2.0V- 5.5V.
- 5 port, 35 chân xuất nhập (I/O pins)
- Có đầy đủ các chức năng cần thiết của Vi
điều khiển 8-bit: Timer (3 bộ), ADC (14 kênh
ADC 10-bit), USART, SPI, I2C, PWM,
Compare, …  được lựa chọn để bắt đầu.
04/06/2010
Giới thiệu PIC16F887
04/06/2010
Giới thiệu PIC16F887
CONG NAP
VCC
Cổng nạp chuẩn ICSPTM
MCLR
0
PGD
PGC
1
2
3
4
5
6
C_PGC
LOAD GATE
(In-Circuit Serial ProgrammingTM):
PGC
J_LOAD
47p
0
04/06/2010
Giới thiệu PIC16F887
VCC
MAIN MCU
Các nguồn xung nhịp cho chip: PIC16F887
R_RS
10K
SW_RS
PVN1
MCLR
0
1
J_PA
1
2
3
4
5
6
2
3
4
5
6
7
RB0/INT
RB1
RB2
RB3/PGM
RB4
RB5
RB6/PGC
RB7/PGD
33
34
35
36
37
38
39
40
1 J_PB
2
3
4
5
6
PGC 7
PGD
8
19
20
21
22
27
28
29
30
1 J_PD
2
3
4
5
6
7
8
8
9
10
1
2
3
PORT A
VCC
J_PC 1
2
3
4
5
6
7
8
PORT C
C_1112
104
0
VCC
SCK
SDI
SDO
SCL
SDA
TX
RX
C_X1
15
16
17
18
23
24
25
26
13
22p
4Mhz
XTAL
0
C_X2
14
22p
0
- Bộ RC gắn ngoài.
- Xung clock từ một nguồn khác.
12
31
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RC2/CCP1
RC3/SCK/SCL
RC4/SDI/SDA
RC5/SDO
RC6/TX/CK
RC7/RX/DT
RD0/PSP0
RD1/PSP1
RD2/PSP2
RD3/PSP3
RD4/PSP4
RD5/PSP5
RD6/PSP6
RD7/PSP7
J_PE
OSC1/CLKIN
RE0/RD*/AN5
RE1/WR*/AN6
RE2/CS*/AN7
OSC2/CLKOUT
VSS
VSS
PORT E
C_3231
104
SS*
RA0/AN0
RA1/AN1
RA2/AN2/VREF-/CVREF
RA3/AN3/VREF+
RA4/T0CKI/C1OUT
RA5/AN4/SS*/C2OUT
PORT D
- Bộ dao động RC nội (RC internal oscillator)
- Bộ dao động tạo bởi thạch anh (và tụ) gắn ngoài
(External Crystal and Ceramic Oscillator)
PORT B
SW RESET
MCLR*/VPP
VCC
VDD
VDD
11
32
PIC16F887
0
04/06/2010
Giới thiệu PIC16F887
5 port xuất nhập (I/O Port)
VCC
MAIN MCU
PIC16F887
R_RS
10K
SW_RS
PVN1
0
1
SS*
2
3
4
5
6
7
J_PA
1
2
3
4
5
6
PORT A
SW RESET
VCC
PORT C
J_PC 1
2
3
4
5
6
7
8
0
VCC
SCL
SDA
TX
RX
C_X1
13
22p
4Mhz
XTAL
0
C_X2
0
14
22p
12
31
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RC2/CCP1
RC3/SCK/SCL
RC4/SDI/SDA
RC5/SDO
RC6/TX/CK
RC7/RX/DT
RD0/PSP0
RD1/PSP1
RD2/PSP2
RD3/PSP3
RD4/PSP4
RD5/PSP5
RD6/PSP6
RD7/PSP7
33
34
35
36
37
38
39
40
1 J_PB
2
3
4
5
6
PGC 7
PGD
8
19
20
21
22
27
28
29
30
1 J_PD
2
3
4
5
6
7
8
8
9
10
1
2
3
J_PE
OSC1/CLKIN
RE0/RD*/AN5
RE1/WR*/AN6
RE2/CS*/AN7
OSC2/CLKOUT
VSS
VSS
PORT E
C_3231
104
SCK
SDI
SDO
15
16
17
18
23
24
25
26
RA0/AN0
RA1/AN1
RA2/AN2/VREF-/CVREF
RA3/AN3/VREF+
RA4/T0CKI/C1OUT
RA5/AN4/SS*/C2OUT
RB0/INT
RB1
RB2
RB3/PGM
RB4
RB5
RB6/PGC
RB7/PGD
PORT D
C_1112
104
MCLR*/VPP
PORT B
MCLR
VCC
VDD
VDD
11
32
PIC16F887
0
04/06/2010
Giới thiệu PIC16F887
Thanh ghi PORTX và TRISX (X: A, B, C, D, E)
Thanh ghi TRISX là thanh ghi quy định hướng của
PortX
…
TRISA7=0: Pin A7 có chức năng Output
=1: Pin A7 có chức năng Intput
04/06/2010
Giới thiệu PIC16F887
Thanh ghi PORTX và TRISX (X: A, B, C, D, E)
Thanh ghi PORTX là thanh ghi quy định trạng thái
logic của PortX
…
RA7 =0: Pin A7 có mức logic “0”
=1: Pin A7 có mức logic “1”
04/06/2010
Giới thiệu PIC16F887
Thanh ghi ANSEL và ANSELH
PIC16F887 có 13 kênh ADC dùng chung với các chân I/O.
2 thanh ghi ANSEL và ANSELH quy định các chân đó là chân
tín hiệu analog hay digital
Bit:
ANSx = 0 : Pin ANx là pin Digital
ANSx = 1 : Pin ANx là pin Analog
Register:
ANSEL = 0 //AN0-7 là digital
ANSELH = 0 // AN8-13 là digital
04/06/2010
Giới thiệu PIC16F887
Thanh ghi ANSEL và ANSELH
04/06/2010
Tóm tắt
Để thực hiện xuất / nhập trên 1 chân (Pin):
- Cài đặt đúng giá trị cho thanh ghi TRISx (hoặc
bit TRISx-n)
- Đặt kiểu tín hiệu của pin là Analog hay Digital
qua 2 thanh ghi ANSEL và ANSELH.
- Xuất tín hiệu bằng cách ghi giá trị “0” hoặc “1”
vào port tương ứng (bit: Rx-n hay port: PORTx)
- Đọc giá trị của chân bằng cách đọc mức logic
trên port tương ứng.
04/06/2010
Cách viết chương trình C với HiTech PIC
#include <htc.h>
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN &
UNPROTECT & SWBOREN & IESODIS & FCMDIS &
LVPDIS & DEBUGDIS); //1st config. Word
__CONFIG(BORV21); //2st config. Word
#define _XTAL_FREQ
#define HANG_SO 123
//Khai báo biến toàn cục
int a,b=1,c=3;
char bien_char;
4000000 //tần số thạch anh 4Mhz
04/06/2010
Cách viết chương trình C với HiTech PIC
//Khai báo các chương trình con
void init_port(void)
{
//chương trình con ở đây
}
char tinh_toan(char a, int b)
{
//………
}
/* chương trình con cũng có thể được viết sau hàm main(),
nhưng trước main() phải có khai báo
void init_port(void);
char tinh_toan(char a, int b); */
04/06/2010
Cách viết chương trình C với HiTech PIC
//Chương trình chính
void main(void)
{
// Phần khởi tạo
//vòng lặp vô tận
while(1)
{
//thực hiện lệnh
};
}
04/06/2010
Ví dụ 1
#include <htc.h>
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN &
UNPROTECT & SWBOREN & IESODIS & FCMDIS &
LVPDIS & DEBUGDIS); //1st config. Word
__CONFIG(BORV21); //2st config. Word
#define _XTAL_FREQ
4000000 //tần số thạch anh 4Mhz
// khai báo tần số thạch anh dùng cho lệnh delay
04/06/2010
Ví dụ 1
//Chương trình chính
void main(void)
{
ANSEL=0;
ANSELH=0;
//Tất cả các port là digital
TRISB=0x00;
//8 pins PortB là output
PORTB=0xFF;
//Xuất mức “1”
while(1)
{
PORTB=0x00;
__delay_ms(150);
PORTB=0xFF;
__delay_ms(150);
};
}
04/06/2010
Giải thích
Với đoạn chương trình trên, chúng ta quan tâm tới các vấn đề sau:
1. Để viết code với HiTech Pic thì phải #include file htc.h
2. PIC16F887 có 2 từ (word) configuration, để chip hoạt động đúng thì
các bạn phải cấu hình (configure) đúng cho nó. Mỗi bit trong word
config. được đại diện bằng 1 cụm chữ cái in hoa.
Bạn chỉ cần quan tâm tới bit config đầu tiên: cấu hình nguồn xung
nhịp (clock) cho chip.
- XT: External Crystal – dùng bộ dao động thạch anh gắn ngoài với
tần số thạch anh từ 4Mhz trở xuống
- HS: High Speed: dùng bộ dao động thạch anh gắn ngoài với tần số
thạch anh trên 4Mhz (tới 20Mhz)
- INTIO: Dùng bộ dao động RC nội
- Và các loại nguồn xung nhịp khác được kí hiệu bằng
các chữ cái khác nhưng ta ít dùng.
04/06/2010
Giải thích
Trong ví dụ trên, ta dùng thạch anh 4Mhz gắn ngoài nên bit config đầu
tiên ta ghi là XT
Tương tự:
__CONFIG(HS & … // nếu dùng thạch anh có tần số 8Mhz
__CONFIG(INTIO & … // nếu dùng bộ dao động RC nội
(Lưu ý: Trước CONFIG bắt đầu bằng 2 dấu gạch dưới “_”, các bit config
còn lại các bạn giữ nguyên, 2 từ config phải được viết trên 2 dòng khác
nhau, không gộp chung được)
3. Định nghĩa tần số thạch anh:
#define _XTAL_FREQ 4000000
- Không có dấu “;” sau hàng định nghĩa hằng số. Trong ví dụ này thạch
anh có giá trị 4Mhz thì ta ghi là 4000000 (4 triệu), nếu dùng thạch anh
20Mhz thì ghi giá trị tần số thạch anh là 20000000 (20 triệu)
-_XTAL_FREQ bắt đầu bằng 1 dấu gạch dưới và bạn không
được phép thay đổi tên hằng số này.
04/06/2010
Giải thích
4. Chương trình chính
Ví dụ này ta kết nối portB với 8 Led đơn, sơ đồ led như sau:
LED MODULE
VCC
R_L1
1k
LED1
R_L2
1k
LED2
R_L3
1k
LED3
R_L4
1k
LED4
R_L5
1k
LED5
R_L6
1k
LED6
R_L7
1k
LED7
R_L8
1k
LED8
1
2
3
4
5
6
7
8
LED_BUS1
LED_BUS là port dùng để nối vào chân
VĐK.
Theo cách mắc mạch như trên, khi
chân VĐK xuất mức “1” Led sẽ tắt, xuất
mức “0” Led sẽ sáng.
Như vậy trong hàm main(), chúng ta
làm các việc:
- Ở phần khởi tạo, quy định các chân là digital, khởi tạo portB là
output để xuất Led, sau đó xuất mức 1 tất cả 8 chân của portB:
0b11111111 = 0xFF để tắt hết các Led.
- Trong vòng lặp while sẽ thực hiện bật led trong thời gian
150ms, rồi tắt 150ms. Thời gian delay là thời gian để cho mắt
kịp nhìn thấy sự thay đổi của led.
04/06/2010
Giải thích
5. Hàm delay
__delay_ms(n);
__delay_us(n);
Được tạo ra bằng cách lặp nhiều lần lệnh “NOP” – không làm gì
cả.
Số n tối đa khoảng 190, nếu bạn muốn delay nhiều hơn 190ms thì
các bạn gọi hàm này nhiều lần, hoặc dùng 1 vòng lặp để gọi nó.
Ví dụ delay 1s:
for(char i=0;i<10;i++) __delay_ms(100);
04/06/2010
Ví dụ 2
Trong ví dụ 2, ta chỉ bật tắt led ở 1 chân duy nhất của portB, ta sẽ
cấu hình bit TRISBn và RBn tương ứng của chân đó mà không
ảnh hưởng tới giá trị của toàn bộ thanh ghi TRISB, PORTB
void main(void)
{
ANSEL=0;
ANSELH=0;
//Tất cả các port là digital
TRISB1=0;
//PortB.1 là output
RB1=1;
//Xuất mức “1”
while(1)
{
RB1=0;
__delay_ms(150);
RB1=1;
__delay_ms(150);
};
}
04/06/2010
Ví dụ 3
Cải tiến ví dụ 2
1 bit xor với 1 để lấy bù của nó (1 ^1  kết quả =0; 0^1  kết quả
=1). RB1 ^=1; nghĩa là xor giá trị RB1 với 1 rồi ghi kết quả vừa
nhận được vào chính RB1, tức là phép lấy bù của RB1.
void main(void)
{
char i;
ANSEL=0;
ANSELH=0;
//Tất cả các port là digital
TRISB1=0;
//PortB.1 là output
RB1=1;
//Xuất mức “1”
while(1)
{
RB1 ^=1;
for(i=0;i<10;i++) __delay_ms(100); //delay 1s
};
}
04/06/2010
Insert Title Text
04/06/2010