Khi các hàm chức năng ngoại vi được cho phép, ta cần quan tâm chặt chẽ tới giá trị các Bit của thanh ghi TRISC và mặt định các chân này là Ouput, ngoài ra một số chức năng ngoại vi khác
Trang 1Chương Dẫn Nhập
Ngày nay với sự phát triển của công nghiệp vi điện tử, kỹ thuật số Các hệ thống điều khiển dần dần được tự động hóa và được ứng dụng thực tế trong xã hội hiện nay Các chip Vi điều khiển ra đời đã mang lại nhiều tiện nghi thiết thực, góp phần đẩy mạnh đưa nền công nghiệp của nước ta từng bước hiện đại, dần dần thay thế sức lao động chân tay bằng các hệ thống điều khiển tự động đòi hỏi trí tuệ cao
Để đáp ứng được yêu cầu đó đòi hỏi những kiến thức cơ bản về Vi Điều Khiển cũng như những kiến thức khởi tạo trong lĩnh vực tự động Được sự đồng ý của khoa
Điện Tử – Tin Học của trường Cao Đẳng Kỹ Thuật Cao Thắng nhóm chúng em đã tiến
thành thực hiện đề tài “ Ngôi nhà thông minh chuẩn không dây ” sử dụng chíp VĐK
PIC 16F877A – Dòng VĐK ứng dụng khá phổ biến hiện nay
II Giới hạn đề tài:
Với thời gian ngắn, cũng như trình độ chuyên môn có hạn, chúng em đã cố gắng hết sức để hoàn thành đề tài này, nhưng vẫn còn gặp nhiều vấn đề khó khăn trong quá trình thi công và thiết kế nên chỉ thực hiện được những phần sau :
• Tìm hiểu ngôn ngữ C lập trình cho PIC
• Tìm hiểu về Zigbee
• Tìm hiểu về các module thu phát RF
III Mục đích nghiên cứu:
Mục đích trước hết khi thực hiện đề tài này là để hoàn tất chương trình học để đủ điều kiện ra trường
Ngoài ra, quá trình thực hiện đề tài là một cơ hội để chúng em tự kiểm tra lại những kiến thức trong suốt thời gian học ở trường Đồng thời đây cũng là dịp để chúng
em tự khẳng định mình trước khi ra trường để trở thành một người có ích cho xã hội trong lĩnh vực Kỹ thuật
Trang 2Chương 2:
Giới Thiệu Vi Điều Khiển Pic16F877A
2.1 Giới Thiệu Chung Về Pic
PIC bắt nguồn là chữ viết tắt của "Programmable Intelligent Computer" (Máy tính khả trình thông minh) là một sản phẩm của hãng General Instruments đặt cho dòng sản phẩm đầu tiên của họ là PIC1650 Lúc này, PIC1650 được dùng để giao tiếp với các thiết
bị ngoại vi cho máy chủ 16bit CP1600, vì vậy, người ta cũng gọi PIC với cái tên
"Peripheral Interface Controller" (Bộ điều khiển giao tiếp ngoại vi) CP1600 là một CPU tốt, nhưng lại kém về các hoạt động xuất nhập, và vì vậy PIC 8-bit được phát triển vào khoảng năm 1975 để hỗ trợ hoạt động xuất nhập cho CP1600 PIC sử dụng microcode đơn giản đặt trong ROM, và mặc dù, cụm từ RISC chưa được sử dụng thời bây giờ, nhưng PIC thực sự là một vi điều khiển với kiến trúc RISC, chạy một lệnh một chu kỳ máy (4 chu kỳ của bộ dao động)
Năm 1985, General Instruments bán bộ phận vi điện tử của họ, và chủ sở hữu mới hủy bỏ hầu hết các dự án - lúc đó đã quá lỗi thời Tuy nhiên PIC được bổ sung EEPROM
để tạo thành 1 bộ điều khiển vào ra khả trình Ngày nay rất nhiều dòng PIC được xuất xưởng với hàng loạt các module ngoại vi tích hợp sẵn (như USART, PWM, ADC ), với
bộ nhớ chương trình từ 512 Word đến 32K Word
Họ vi điều khiển này có thể tìm mua dễ dàng tại thị trường Việt Nam Giá thành không quá đắt Có đầy đủ các tính năng của một vi điều khiển khi hoạt động độc lập Là một sự bổ sung rất tốt về kiến thức cũng như về ứng dụng cho họ vi điều khiển mang tính truyền thống như họ vi điều khiển 8051 Hiện nay tại Việt Nam cũng như trên thế giới có một số lượng lớn người sử dụng họ vi điều khiển PIC, vì vậy họ vi điều khiển này được
sử dụng khá rộng rãi Điều này tạo nhiều thuận lợi trong quá trình tìm hiểu và phát triển các ứng dụng, cũng như dễ dàng trao đổi, học tập, dễ dàng tìm được sự chỉ dẫn khi gặp khó khăn,…đồng thời cũng được sự hỗ trợ của nhà sản xuất về trình biên dịch, các công
cụ lập trình, nạp chương trình từ đơn giản đến phức tạp,… Do đó các tính năng đa dạng của vi điều khiển PIC không ngừng được phát triển
2.1.1 Các dòng Pic và cách lựa chọn Vi điều khiển Pic
Các sản phẩm vi điều khiển PIC của Microchip có gần 100 loại sản phẩm từ họ 10Fxxx đến các họ 12Cxxx, 12Fxxx, 16Cxx, 17Cxx, 16Fxx, 16Fxxx, 16FxxxA, 16LFxxxA, 18Fxxx, 18LFxxx, 18Fxxxx, 18LFxxxx,…
Cách phân loại PIC theo chữ cái:
Các họ PIC xxCxxx được đưa vào một nhóm, gọi là OTP (One Time Programmable): chúng ta chỉ có thể lập trình và nạp chương trình cho nó được một lần duy nhất
Trang 3Nhóm thứ hai có chữ cái F hoặc LF: chúng ta gọi nhóm này là nhóm Flash, nhóm này cho phép ghi xóa nhiều lần bằng các mạch điện thông thường
Cách phân loại theo hai con số đầu tiên của sản phẩm:
Loại thứ nhất là dòng PIC cơ bản( Base – line ), gồm các PIC 12Cxxx, có
độ dài 12bit
Loại thứ hai là các dòng PIC 10F, 12F va 16F, gọi là dòng phổ thông ( Mid – Range ), có dộ dài 14 bit
Loại thứ ba là dòng PIC 18( High – End ), có độ dài 16 bit
Ở Việt Nam phổ biến nhất là các họ vi điều khiển PIC do hãng Microchip sản xuất Cách lựa chọn một vi điều khiển PIC phù hợp: Trước hết cần chú ý đến số chân của
vi điều khiển cần thiết cho ứng dụng Có nhiều vi điều khiển PIC với số lượng chân khác nhau, thậm chí có vi điều khiển chỉ có 8 chân,ngoài ra còn có các vi điều khiển 18, 28,
40, 44, … chân Cần chọn vi điều khiển PIC có bộ nhớ flash để có thể nạp xóa chương trình được nhiều lần hơn Tiếp theo cần chú ý đến các khối chức năng được tích hợp sẵn trong vi điều khiển, các chuẩn giao tiếp bên trong Sau cùng cần chú ý đến bộ nhớ chương trình mà vi điều khiển cho phép
2.1.2 Ngôn ngữ lập trình cho Pic
Ngôn ngữ lập trình cho PIC rất đa dạng Ngôn ngữ lập trình cấp thấp có MPLAB (được cung cấp miễn phí bởi nhà sản xuất Microchip), các ngôn ngữ lập trình cấp cao hơn bao gồm C, Basic, Pascal, … Ngoài ra còn có một số ngôn ngữ lập trình được phát triển dành riêng cho PIC như PICBasic, MikroBasic,…
2.1.3 Mạch nạp Pic
Đây cũng là một dòng sản phẩm rất đa dạng dành cho vi điều khiển PIC Có thể sử dụng các mạch nạp được cung cấp bởi nhà sản xuất là hãng Microchip như: PICSTART plus, MPLAB ICD 2, MPLAB PM 3, PRO MATE II Có thể dùng các sản phẩm này để nạp cho vi điều khiển khác thông qua chương trình MPLAB Dòng sản phẩm chính thống này có ưu thế là nạp được cho tất cả các vi điều khiển PIC, tuy nhiên giá thành rất cao và thường gặp rất nhiều khó khăn trong quá trình mua sản phẩm
2.2 Cấu trúc tổng quát Pic 16F877A
Hình 2.2 (a): Vi điều khiển PIC16F877A các dạng sơ đồ chân
Trang 4Đây là vi điều khiển thuộc họ PIC16Fxxx( 40 pin) với tập lệnh gồm 35 lệnh có độ dài 14 bit Mỗi lệnh đều được thực thi trong một chu kì xung clock Tần số hoạt động tối
đa là 20 MHz với một chu kì lệnh là 200ns Bộ nhớ chương trình 8K Flash ROM, bộ nhớ
dữ liệu 368 bytes RAM và bộ nhớ dữ liệu EEPROM với dung lượng 256 bytes Số Port In/Out (I/O) là 5 Port( A, B, C, D, E) với 33 pin I/O với tính hiệu điều khiển độc lập
Hình 2.2(b): Sơ đồ khối vi điều khiển PIC16F877A
Các khối chức năng bên trong Pic16F877A:
Timer0: bộ đếm 8 bit
Timer1: bộ đếm 16 bit với bộ chia tần số, có thể họat động trong cả chế độ tiết kiệm năng lượng( Sleep Mode) với nguồn xung clock ngoài
Trang 5Các chuẩn giao tiếp nối tiếp SSP (Synchronous Serial Port), SPI và I2C
Chuẩn giao tiếp nối tiếp USART với 9 bit địa chỉ
Nạp được chương trình ngay trên mạch điện ICSP (In Circuit Serial Programming) thông qua 2 chân
Một vài đặc tính khác của vi điều khiển như:
Được chế tao bằng công nghệ CMOS
Bộ nhớ flash với khả năng ghi xóa được 100.000 lần
Bộ nhớ EEPROM với khả năng ghi xóa được 1.000.000 lần
Dữ liệu bộ nhớ EEPROM có thể lưu trữ trên 40 năm
Khả năng tự nạp chương trình với sự điều khiển của phần mềm
Chức năng bảo mật mã chương trình
Chế độ Sleep
Có thể hoạt động với nhiều dạng Oscillator khác nhau
2.2.1 Sơ lược về các chân của Pic16F877A
PIC16F877A là họ vi điều khiển có 40 chân, mỗi chân có một chức năng khác nhau Trong đó có một số chân đa công dụng( đa hợp): mỗi chân có thể họat động như một đường xuất nhập ( I/O) hoặc là một chân chức năng đặc biệt dùng để giao tiếp với các thiết bị ngoại vi
Cổng xuất nhập (I/O port) chính là phương tiện mà vi điều khiển dùng để tương tác với bên ngoài Vi điều khiển PIC16F877A có 5 cổng xuất nhập, bao gồm PORTA, PORTB, PORTC, PORTD và PORTE
2.2.1.1 Port A và thanh ghi TRISA
PortA gồm 6 chân từ RA0-RA5 Việc ghi các giá trị vào thanh ghi TRISA sẽ quy định các chân của PortA là Input hay Output Nếu là 0 thì là Output, 1 là Input
Việc đọc thanh ghi PortA sẽ đọc trạng thái các chân PortA Việc ghi giá trị vào thanh ghi PortA sẽ thay đổi trạng thái của các chân PortA
Riêng chân RA4 được tích hợp thêm chức năng là chân cung cấp xung Clock ngoài cho Timer0 (RA4/TOCKI) Những chân khác của PortA được đa hợp với các chân ngõ vào Analog của ADC và chân ngỏ vào điện thế so sánh của bộ so sánh (Comparator) Hoạt động của những chân này được qui địng bằng những Bit tương ứng trong thanh ghi ADCCON1 va CMCON1 Khi các chân của PortA được sử dụng là ngõ vào Analog thì các Bit của thanh ghi TRISA phải luôn bằng 1
Trang 6Hình 2.2.1.1: PortA và thanh ghi TrisA
Các thanh ghi SFR liên quan đến PORTA bao gồm:
PORTA (địa chỉ 05h) : chứa giá trị các pin trong PORTA
TRISA (địa chỉ 85h) : điều khiển xuất nhập
CMCON (địa chỉ 9Ch) : thanh ghi điều khiển bộ so sánh
CVRCON (địa chỉ 9Dh) : thanh ghi điều khiển bộ so sánh điện áp
ADCON1 (địa chỉ 9Fh) : thanh ghi điều khiển bộ ADC
2.2.1.2 Port B và thanh ghi TRISB
PortB gồm 8 chân từ RB0-RB7 Việc ghi các giá trị vào thanh ghi TRISB sẽ quy định các chân của PortB là Input hay Output Nếu là 0 thì là Output, 1 là Input
Việc đọc thanh ghi PortB sẽ đọc trạng thái các chân PortB Việc ghi giá trị vào thanh ghi PortB sẽ thay đổi trạng thái của các chân PortB
Ba chân của PortB được đa hợp với chức năng In-Circuit Debugger và Low Voltage Programming fuction: RB3/PGM, RB6/PGC và RB7/PGD
Mỗi chân của PortB có một transistor kéo lên Vdd, chức năng này hoạt động khi Bit RPBU được xóa Chứ năng này sẽ tự động tắt khi chân Port đựơc quy địng là Input
Bốn chân của Portb từ RB7-RB4 có chức năng ngắt (Interrupt) khi trạng thái chân Port thay đổi (Khi chân Port được quy định là Ouput thì chức na7ng ngắt không họat động) Giá trị chân Port được so sánh với giá trị được lưu lại trước đó, khi có trạng thái sai lệch giữa 2 giá trị này, ngắt sẽ xảy ra với cờ ngắt RBIF INTCON<0> bật lên Ngắt có thể làm cho Vi điều khiển thoát khỏi trạng thái “SLEEP”
Trang 7Bất cứ một họat động truy xuất nào trên PortB sẽ xóa trạng thái sai lệch, kết thúc ngắt và cho phép xóa cờ RBIF
Hình 2.2.1.2: PortB và thanh ghi TrisB
Các thanh ghi SFR liên quan đến PORTB bao gồm:
PORTB (địa chỉ 06h,106h) : chứa giá trị các pin trong PORTB
TRISB (địa chỉ 86h,186h) : điều khiển xuất nhập
OPTION_REG (địa chỉ 81h,181h) : điều khiển ngắt ngoại vi và bộ Timer0
2.2.1.3 Port C và thanh ghi TRISC
PortC gồm 8 chân từ RC0-RC7 Việc ghi các giá trị vào thanh ghi TRISC sẽ quy định các chân của PortC là Input hay Output Nếu là 0 thì là Output, 1 là Input
Việc đọc thanh ghi PortC sẽ đọc trạng thái các chân PortC Việc ghi giá trị vào thanh ghi PortC sẽ thay đổi trạng thái của các chân PortC
Các chân của PortC được đa gợp với các chức năng ngọai vi
Khi các hàm chức năng ngoại vi được cho phép, ta cần quan tâm chặt chẽ tới giá trị các Bit của thanh ghi TRISC và mặt định các chân này là Ouput, ngoài ra một số chức năng ngoại vi khác sẽ tự động mặt định các chân là ngõ vào
Trang 8Hình 2.2.1.3: PortC và thanh ghi TrisC
Các thanh ghi điều khiển liên quan đến PORTC:
PORTC (địa chỉ 07h) : chứa giá trị các pin trong PORTC
TRISC (địa chỉ 87h) : điều khiển xuất nhập
2.2.1.4 Port D và thanh ghi TRISD
PortD gồm 8 chân từ RD0-RD7 Ngoài việc PortD được cấu trúc là một Port vừa xuất nhập nó còn có thể họat động như một cổng song song bằng cách xét Bit PSPMODE, trong chế độ này Buffer ngõ vào linh kiện TTL
Hình 2.2.1.4: Thanh ghi TrisD
Trang 9Các thanh ghi liên quan đến PORTD bao gồm:
Thanh ghi PORTD(địa chỉ 08h): chứa giá trị các pin trong PORTD
Thanh ghi TRISD(địa chỉ 88h): điều khiển xuất nhập
2.2.1.5 PortE và thanh ghi TRISE
PortE có 3 chân RE0/RD/AN5, RE1/WR/AN6 VÀ RE2/CS/AN7 có thể được cấu hình là các chân xuất nhập
Các chân của PortE có thể trở thành các chân điều khiển cho các cổng của Vi điều khiển khi Bit PSPMODE được xét là 1 Trong chế độ này phải đảm bảo rằng các Bit từ 0 dến 2 cua thanh ghi TRISE phải được xét bằng 1 để các chân này được cấu hình như các chân ngõ vào
Ngoài ra các chân PortE còn được cấu hình như các ngõ vào Analog, tại chế độ này khi đọc trạng thái các chân PortE sẽ cho ta giá trị 0
Thanh ghi TRISE quy định chức năng xuất nhập của các chân PortE ngay cả khi
nó được sử dụng là các ngõ vào Analog
Hình 2.2.1.5: Thanh ghi TrisE
Các thanh ghi liên quan đến PORTE bao gồm:
PORTE(địa chỉ 09h) : chứa giá trị các chân trong PORTE
TRISE(địa chỉ 89h) : điều khiển xuất nhập và xác lập các thông số cho chuẩn giao tiếp PSP
ADCON1(địa chỉ 9Fh) : thanh ghi điều khiển khối ADC
2.2.1.6 Parallel Slave Port
PORTD hoạt động như port phụ song song có độ rộng 8 bit hoặc port vi xử lý khi bit điều khiển PSPMODE (TRISE<4>) được Set Trong chế độ phụ , nó được đọc và ghi không đồng bộ thông qua tín hiệu điều khiển ở ngõ vào RD của chân RE0/RD và tín hiệu điều khiển ở ngõ vào WRcủa chân RE1/WR PSP có thể ghép nối trực tiếp với bus
dữ liệu của vi xử lý 8 bit Bộ vi xử lý bên ngoài có thể đọc hoặc ghi vào chốt PORTD
Trang 10như bộ chốt 8 bit Khi bit PSPMODE được đặt thì chân RE0/RD là ngõ vàoRD, chân RE1/WR là ngõ vào WRvà chân RE2/CS là ngõ vào CS (chọn chip) Trong hoạt động này, những bit dữ liệu trực tiếp tương ứng của thanh ghi TRISE(TRISE<2:0> ) phải được cấu hình như những ngõ vào Những bit cấu hình của bộ A/D là PCFG3:PCFG0 (ADCON1<3:0>) phải được đặt để cấu hình cho những chân RE2:RE0 như I/O số
Thực tế có hai bộ chốt 8 bit : một cho dữ liệu ở ngõ ra và một cho dữ liệu ở ngõ vào Người sử dụng có thể ghi dữ liệu 8 bit vào bộ chốt dữ liệu của PORTD và đọc dữ liệu từ bộ chốt ( chú ý rằng chúng có cùng địa chỉ) Trong chế độ này, thanh ghi TRISE được bỏ qua, khi những thiết bị ngoài đang điều khiển hướng của luồng dữ liệu
Hoạt động ghi vào PSP xuất hiện khi cả CS và WRđược dò thấy ở mức thấp lần đầu tiên Khi cả CSvà WRtrở về mức cao khi đó bit cờ trạng thái IBF ( Input Buffer Full ) ( TRISE<7> ) được bật tại chu kỳ xung clock Q4, chu kỳ kế tiếp là Q2, báo hiệu việc ghi đã hoàn thành Bit cờ ngắt PSPIF ( PIR1<7> ) cũng được bật tại chu kỳ xung clock Q4 IBF chỉ có thể được xóa bằng cách đọc bộ chốt ngõ vào của PORTD Bit cờ trạng thái IBOV ( Input Buffer Overflow) (TRISE<5>) được bật nếu lần ghi thứ hai vào PSP được thực hiện khi byte trước đó chưa được đọc ra khỏi vùng đệm Hoạt động đọc từ PSP xuất hiện khi cả CS và RD được dò thấy ở mức thấp lần đầu tiên bit cờ trạng thái OBF (Output Buffer Full) (TRISE<6> ) bị xóa ngay lập tức báo hiệu rằng bộ chốt của PORTD đang chờ đọc dữ liệu bởi bus ngoại Khi một trong hai chân CS và RD trở về mức cao, bit cờ ngắt PSPIF được bật tại chu kỳ xung clock Q4, chu kỳ kế tiếp là Q2, báo hiệu rằng việc đọc đã hòan thành Bit OBF vẫn được giữ ở mức thấp cho đến khi dữ liệu được ghi vào PORTD bởi vi chương trình của người sử dụng
Khi không hoạt động trong chế độ PSP, những bit IBF và OBF được giữ nguyên Tuy nhiên nếu trước đó bit IBOV đã được bật nó phải được xóa bằng vi chương trình Một ngắt được phát ra và được chốt vào bit cờ PSPIF khi hoạt động đọc hoặc ghi hoàn thành Bit PSPIF phải được xóa bằng vi chương trình của người sử dụng và ngắt không được cho phép bằng cách xóa bit cho phép ngắt PSPIE ( PIE<7>)
Dạng sóng khi ghi lên Parallel Slave Port:
Dạng sóng khi trong quá trình đọc từ Parallel Slave Port
Trang 11Các thanh ghi liên quan đến Parallel Slave Port:
2.2.1.7 OSC1 và OSC2
Pic16F877A có khả năng sử dụng một trong 4 loại oscillator, đó là:
LP: (Low Power Crystal)
XT: (Crystal/ Resonator) thạch anh bình thường
HS: (High Speed Crystal)
RC: (Resistor/Capacitor) dao động do mạch RC tạo ra
Ở chế độ LP, HS, XT thạch anh dao động nối vào 2 chân OSC1 và OSC2 để thiết lập dao động
Hình 2.2.1.7(a):Dao động thạch anh
Trang 12Mode Freq OSC1/C1 OSC2/C2
Bảng 1: Lựa chọn giá trị tụ cho dao động thạch anh
Đối với các ứng dụng không cần các loại Oscillator tốc độ cao, ta có thể sử dụng mạch dao động RC làm nguồn cung cấp xung hoạt động cho vi vi điều khiển Tần số tạo
ra phụ thuộc vào giá trị điện trở R và tụ điện C, bên cạnh đó là sự ảnh hưởng của các yếu
tố như nhiệt độ, chất lượng của các linh kiện
Hình 2.2.1.7(b):Dao động RC
Ngõ vào MCLR( Reset) trên chân số 1 của Vi điều khiển Khi đưa MCLR xuống thấp, các thanh ghi bên trong Vi điều khiển sẽ được tải những giá trị thích hợp để khởi động lại hệ thống
5V
MCLR 1
SW1
Trang 13Bộ nhớ chương trình còn bao gồm một ngăn xếp( Stack) 8 mức
Khi vi điều khiển được reset, bộ đếm chương trình sẽ chỉ đến địa chỉ 0000h (Reset vector) Khi có ngắt xảy ra, bộ đếm chương trình sẽ chỉ đến địa chỉ 0004h (Interrupt vector)
Hình 2.2.2.1: Ngăn xếp và bản đồ bộ nhớ chương trình
2.2.2.2 Tổ chức của bộ nhớ dữ liệu
Bộ nhớ dữ liệu của PIC được chia ra làm nhiều bank Đối với PIC16F877A bộ nhớ
dữ liệu được chia ra làm 4 bank: bank 0, bank 1, bank 2 và bank 3 Mỗi bank có dung lượng 128 byte, bao gồm các thanh ghi có chức năng đặc biệt SFR (Special Function Register) nằm ở các vùng địa chỉ thấp và các thanh ghi mục đích chung GPR (General Purpose Register) nằm ở vùng địa chỉ còn lại trong bank Các thanh ghi SFR thường xuyên được sử dụng (ví dụ như thanh ghi STATUS) sẽ được đặt ở tất cà các bank của bộ nhớ dữ liệu giúp thuận tiện trong quá trình truy xuất và làm giảm bớt lệnh của chương trình
Các bank được lựa chọn bằng bit RP0 và bit RP1 ở thanh ghi Status
Trang 14RP1:RP0 Bank
00 0
01 1
10 2
11 3
Vùng RAM đa mục đích GPR:
Vùng RAM đa mục đích có chiều rộng là 8 bit và được truy xuất trực tiếp hoặc gián tiếp thông qua thanh ghi FSR Đây là các thanh ghi dữ liệu thông thường, người sử dụng có thể tùy theo mục đích chương trình mà có thể dùng các thanh ghi này để chứa các biến số, hằng số, kết quả hoặc các tham số phục vụ cho chương trình
Trang 15
Hình 2.2.2.2: Sơ đồ bộ nhớ dữ liệu PIC16F877A
Vùng thanh ghi chức năng đặc biệt SFR
Đây là các thanh ghi chức năng dặc biệt được sử dụng bởi bộ sử lý trung tâm và các hàm chức năng ngoại vi để điều khiển họat động của các thiết bị Có thể phân thanh ghi SFR làm hai lọai: tloại thứ nhất dùng để thiết lập và điều khiển các khối chức năng
Trang 16bên ngoài (ví dụ như ngắt, so sánh, PWM, …) và loại thứ hai dùng cho các chức năng bên trong của Vi điều khiển( các phép tímh toán số học, truy xuất số liệu,…)
2.2.2.3 Thanh ghi đếm chương trình PC( Program Counter)
Thanh ghi đếm chương trình( PC ) chứa địa chỉ của lệnh được thực hiện kế tiếp
Bộ đếm chương trình (PC) có độ rộng 13 bit Byte thấp là thanh ghi PCL, nó có thể đọc
và ghi Ba bit cao là thanh ghi PCH (PC<12:8>) không cho phép đọc nhưng nó cho phép ghi gián tiếp thông qua thanh ghi PCLATH Khi Reset thì ba bit cao của PC sẽ bị xoá
Ngăn xếp stack:
Stack cho phép 8 lệnh gọi chương trình con và ngắt hoạt động Stack chứa địa chỉ
mà chương trình chính sẽ quay trở về thực hiện từ chương trình con hay ngắt Đối với dòng Pic phổ thông, Stack có độ sâu là 8 lớp, mỗi lớp có độ rộng 13 bit Vị trí của Stack không nằm trong cả bộ nhớ chương trình hoặc bộ nhớ dữ liệu và con trỏ ngăn xếp thì không cho phép đọc hoặc ghi Hoạt động của ngăn xếp giống như vùng đệm vòng Điều này có nghĩa là sau khi ngăn xếp đã cất vào 8 lần, lần cất vào thứ 9 sẽ được ghi chồng lên lần cất vào đầu tiên Lần cất vào thứ mười sẽ được ghi chồng lên lần cất vào thứ hai (và
cứ như thế)
2.2.2.4 Sự phân trang bộ nhớ chương trình
PIC16F877A có khả năng định vị một khối liên tục 8K từ của bộ nhớ chương trình Các lệnh CALL và GOTO chỉ cung cấp 11 bit địa chỉ và chỉ xác định được 2K bộ nhớ chương trình Khi thực hiện lệnh CALL hoặc GOTO, 2 bit cao nhất của địa chỉ được cung cấp bởi PCLATH<4:3> Khi thực hiện lệh CALL hoặc GOTO, người sử dụng phải bảo đảm rằng trang chọn bit phải được lập trình để trang bộ nhớ chương trình được định địa chỉ Nếu lệnh CALL (hoặc ngắt) được thi hành, toàn bộ 13 bit của PC sẽ được cất vào ngăn xếp Vì vậy việc vận dụng các bit PCLATH<3:4> thì không đòi hỏi lệnh Return để lấy địa chỉ từ ngăn xếp
2.2.2.5 Định địa chỉ gián tiếp, các thanh ghi INDF và FSR
Thanh ghi INDF không phải là thanh ghi vật lý Địa chỉ của thanh ghi INDF sẽ được định vị gián tiếp Định vị gián tiếp có thể thực hiện được bằng cách sử dụng thanh ghi INDF Trên thực tế, bất kì lệnh nào sử dụng thanh ghi INDF để truy cập thanh ghi con trỏ bằng thanh ghi FSR (File Select Register) Việc đọc chính thanh ghi INDF, một cách gián tiếp (FSR = ‘0’) sẽ có giá trị 00h Một địa chỉ 9 bit có hiệu quả thu được bằng cách ghép 8 bit của thanh ghi FSR với bit IRP (STATUS<7>), như được chỉ bên dưới Một chương trình mẫu dùng để xoá vùng RAM từ 20h đến 2Fh sử dụng cách định địa chỉ gián tiếp
Trang 17Hình 2.2.2.5: Định địa chỉ gián tiếp
2.2.3 Bộ nhớ dữ liệu và bộ nhớ chương trình
2.2.3.1 Bộ nhớ dữ liệu EEPROM và bộ nhớ chương trình FLASH
Bộ nhớ dữ liệu EEPROM và bộ nhớ chương trình FLASH cho phép đọc hoặc ghi trong suốt hoạt động bình thường trong phạm vi VDD Những thao tác này xảy ra trên một byte đơn cho bộ nhớ dữ liệu EEPROM và trên một từ đơn cho bộ nhớ chương trình FLASH Một thao tác ghi gây ra sự xóa rồi ghi, thao tác này được thực hiện trên một byte hoặc một từ được chỉ định Sự truy cập vào bộ nhớ chương trình phải kể đến sự tính toán checksum Ghi một byte hoặc một word sẽ tự động xóa vùng nhớ và ghi lên giá trị mới (xóa trước khi ghi) Việc ghi vào bộ nhớ dữ liệu EEPROM không ảnh hưởng đến hoạt động của thiết bị Việc ghi vào bộ nhớ chương trình sẽ dừng thực thi các lệnh cho đến khi quá trình ghi hoàn thành Bộ nhớ chương trình không thể được truy cập trong suốt quá trình ghi Trong suốt quá trình ghi, bộ dao động tiếp tục chạy, thiết bị ngoại vi vẫn tiếp tục hoạt động và những sự kiện về ngắt sẽ được phát hiện và đợi cho đến khi quá trình ghi hoàn thành Khi quá trình ghi hoàn thành, lệnh tiếp theo trong hàng đợi lệnh sẽ được thực hiện và một rẽ nhánh đến vectơ ngắt sẽ xảy ra đến ngắt được phép và gây ra trong suốt quá trình ghi Việc đọc và ghi truy cập đến cả hai bộ nhớ xảy ra gián tiếp thông qua việc đặt những thanh ghi mục đích chung (SFR) Có sáu thanh ghi mục đích chung được
sử dụng là:
Thanh ghi EEDATA
Thanh ghi EEDATH
Thanh ghi EEADR
Thanh ghi EEADRH
Thanh ghi EECON1
Thanh ghi EECON2
Bộ nhớ dữ liệu EEPROM cho phép những thao tác đọc và ghi byte không can thiệp đến những thao tác bình thường của bộ vi điều khiển Khi có sự trao đổi với bộ nhớ
dữ liệu EEPROM, thanh ghi EEADR giữ địa chỉ sẽ được truy cập Phụ thuộc vào thao tác, thanh ghi EEDATA giữ dữ liệu được ghi hoặc được đọc tại địa chỉ trong thanh ghi EEADR PIC16F877A có 256 byte cho bộ nhớ dữ liệu EEPROM và do đó nó sử dụng tất
cả 8 bit của EEADR Bộ nhớ chương trình FLASH không cho phép truy cập vào quá
Trang 18trình đọc, nhưng quá trình ghi sẽ dừng thực thi các lệnh cho đến khi quá trình ghi hoàn thành Khi trao đổi với bộ nhớ chương trình cặp thanh ghi EEADRH:EEADR sẽ tạo thành một từ hai byte, và sẽ chứa 13 bit địa chỉ của vùng nhớ được truy cập Sự kết hợp hai thanh ghi EEDATH:EEDATA sẽ chứa dữ liệu 14 bit cho việc ghi, hoặc phản ánh giá trị của bộ nhớ chương trình sau mỗi lần đọc Giống sự truy cập vào bộ nhớ dữ liệu EEPROM, giá trị của những thanh ghi EEADRH:EEADR phải bên trong phạm vi hợp lệ của bộ nhớ chương trình, phụ thuộc vào linh kiện (0000h đến 1FFFh đối với PIC16F873/874) từ 0000h đến 3FFFh đối với PIC16F877A
2.2.3.2 Thanh ghi EECON1 và EECON2
Thanh ghi EECON1 là thanh ghi điều khiển sự cấu hình và sự truy cập Thanh ghi EECON2 không phải là thanh ghi vật lý được bổ sung, nhưng nó được sử dụng để ghi một chuỗi nhớ để ngăn chặn sự ghi vô ý
Một vài bit được sử dụng để điều khiển các thao tác đọc hoặc ghi đến bộ nhớ dữ liệu EEPROM và bộ nhớ chương trình FLASH Bit EEPGD xác định sự truy cập đến bộ nhớ chương trình hoặc bộ nhớ dữ liệu Khi bị xóa, những thao tác tiếp theo sẽ làm việc trên bộ nhớ dữ liệu EEPROM Khi được đặt, tất cả những thao tác tiếp theo sẽ thao tác trên bộ nhớ chương trình
Thao tác đọc sử dụng một bit thêm vào là RD, mà nó bắt đầu cho thao tác đọc từ vùng nhớ mong muốn Mỗi lần bit này được đặt, giá trị của vùng nhớ này sẽ được sẵn sàng trong thanh ghi dữ liệu Bit này không thể xóa bằng vi chương trình Nó sẽ tự động xóa sau khi thao tác đọc kết thúc Khi đọc bộ nhớ dữ liệu EEPROM, dữ liệu sẽ được chuẩn bị sẵn trong thanh ghi EEDATA trong chu kỳ lệnh kế tiếp sau khi bit RD được đặt Khi đọc bộ nhớ chương trình, sau khi bit RD được đặt, dữ liệu sẽ được load vào cặp thanh ghi EEDATH:EEDATA sau lệnh thứ hai
Thao tác ghi có hai bit điều khiển, WR và WREN, và hai bit trạng thái WRERR và EEIF Bit WREN được sử dụng để cho phép hoặc không cho phép ghi Khi bit WREN bị xóa, thao tác ghi sẽ không được cho phép Do đó, bit WREN cần phải được set trước khi thực hiện thao tác ghi Bit WR được sử dụng để bắt đầu cho thao tác ghi Nó sẽ tự động xóa sau khi thao tác ghi kết thúc Cờ ngắt EEIF được sử dụng để xác định việc ghi vào bộ nhớ đã hoàn thành Cờ này cần phải được xóa bằng phần mềm trước khi bit WR được set Đối với bộ nhớ dữ liệu EEPROM, mỗi lần bit WREN và WR đã được set, địa chỉ của vùng nhớ mong muốn trong thanh ghi EEADR sẽ bị xóa, sau đó là việc ghi dữ liệu vào thanh ghi EEDATA Khi thao tác ghi hoàn thành, bit cờ EEIF sẽ được set Đối với bộ nhớ chương trình, mỗi lần bit WREN và WR đã được set, bộ vi điều khiển sẽ ngừng thực hiện các lệnh Vùng nhớ mong muốn được trỏ đến bởi EEADRH:EEADR sẽ bị xóa Sau
đó, giá trị dữ liệu trong EEADTH:EEDATA sẽ được chương trình hóa Khi hòan thành bit cờ EEIF sẽ được set và bộ vi điều khiển sẽ tiếp tục thực hiện
Trang 19Hình 2.23.2: Thanh ghi EECON1(địa chỉ 18Ch)
2.2.3.3 Quá trình đọc bộ nhớ dữ liệu EEPROM
Quá trình đọc bộ nhớ dữ liệu EEPROM chỉ yêu cầu địa chỉ cần truy cập phải được ghi vào thanh ghi EEADR và xóa bit EEPGD Sau khi bit RD được set, dữ liệu sẽ phải sẵn sàng trong thanh ghi EEDATA trong chu kỳ lệnh kế tiếp EEDATA sẽ giữ giá trị này cho đến khi thao tác đọc kế tiếp được bắt đầu hoặc cho đến khi nó được ghi bởi vi chương trình
Các bước trong quá trình đọc bộ nhớ dữ liệu EEPROM là:
1 Ghi địa chỉ cần truy cập vào thanh ghi EEADR và hãy chắc rằng địa chỉ này thì không lớn hơn kích thước bộ nhớ của linh kiện PIC16F877A
2 Xóa bit EEPGD để trỏ đến bộ nhớ dữ liệu EEPROM
3 Set bit RD để bắt đầu thao tác đọc
4 Đọc dữ liệu từ thanh ghi EEDATA
2.2.3.4 Quá trình ghi vào bộ nhớ dữ liệu EEPROM
Quá trình ghi dữ liệu vào bộ nhớ dữ liệu EEPROM được tiến hành qua vài bước
Cả địa chỉ và giá trị dữ liệu cần phải được ghi vào những thanh ghi mục đích chung SFR Bit EEPGD cần phải được xóa, và bit WREN phải được set để cho phép ghi Bit WREN phải bị xóa trong suốt thời gian ngoại trừ trong quá trình ghi vào bộ nhớ dữ liệu
Trang 20EEPROM Bit WR chỉ có thể được set khi bit WREN đã được set trước đó, chúng không thể được set cùng lúc Bit WREN sau đó phải được xóa bằng vi chương trình sau khi ghi
Các bước trong quá trình ghi vào bộ nhớ dữ liệu EEPROM:
1 Nếu bước thứ 10 chưa được thực hiện, hãy kiểm tra bit WR để xem việc ghi có đang tiến hành
2 Ghi địa chỉ cần truy cập vào thanh ghi EEADR và hãy chắc rằng địa chỉ này thì không lớn hơn kích thước bộ nhớ của linh kiện PIC16F877A
3 Ghi giá trị dữ liệu 8 bit được chương trình hóa vào thanh ghi EEDATA
4 Xóa bit EEPGD để trỏ đến bộ nhớ dữ liệu EEPROM
5 Set bit WREN để cho phép những thao tác lập trình
6 Không cho phép những ngắt
7 Thực hiện chuỗi 5 lệnh đặc biệt sau:
Ghi giá trị 55h vào EECON2 qua hai bước (đầu tiên đưa vào W, sau đó mới đưa EECON2)
Ghi giá trị AAh vào EECON2 qua hai bước (đầu tiên đưa vào W, sau đó mới đưa vào EECON2)
Set bit WR
8 Cho phép các ngắt (nếu sử dụng ngắt)
9 Xóa bit WREN để không cho phép các thao tác lập trình
10 Tại thời điểm chu kỳ ghi hoàn thành, bit WR bị xóa và bit cờ ngắt EEIF được set Nếu bước 1 chưa được thực hiện, sau đó vi chương trình sẽ kiểm tra xem EEIF được set hay chưa hoặc bit WR có bị xóa hay không để báo kết thúc chu
kỳ chương trình
2.2.3.5 Quá trình đọc bộ nhớ chương trình FLASH
Quá trình đọc bộ nhớ chương trình FLASH cũng giống với quá trình đọc bộ nhớ
dữ liệu EEPROM, chỉ cần thêm vào hai lệnh NOP sau khi set bit RD Hai chu kỳ lệnh được thực hiện bởi lệnh NOP sẽ được bộ vi điều khiển sử dụng để đọc dữ liệu ra khỏi bộ nhớ chương trình và chèn giá trị đó vào trong cặp thanh ghi EEDATH:EEDATA Dữ liệu
sẽ được sẵn sàng ở lệnh thứ hai EEDATH và EEDATA sẽ giữ giá trị này cho đến khi thao tác đọc tiếp theo được bắt đầu, hoặc cho đến khi chúng được ghi bởi vi chương trình
Các bước trong quá trình đọc bộ nhớ chương trình FLASH:
1 Ghi địa chỉ cần truy cập vào cặp thanh ghi EEADRH: EEADR Hãy chắc rằng địa chỉ đó không lớn hơn kích thước bộ nhớ của linh kiện PIC16F877A
2 Set bit EEPGD để trỏ đến bộ nhớ chương trình FLASH
3 Set bit RD để bắt đầu thao tác đọc
4 Thực hiện hai lệnh NOP để cho phép bộ vi điều khiển đọc dữ liệu ra khỏi bộ nhớ chương trình
5 Đọc dữ liệu từ cặp thanh ghi EEDATH:EEDATA
2.2.3.6 Quá trình ghi dữ liệu vào bộ nhớ chương trình FLASH
Các bước trong quá trình ghi dữ liệu vào bộ nhớ chương trình FLASH:
Trang 211 Ghi địa chỉ cần truy cập vào cặp thanh ghi EEADRH:EEADR Chắc rằng địa chỉ này thì không lớn hơn kích thước bộ nhớ của linh kiện PIC16F877A
2 Ghi giá trị dữ liệu 14 bit đã được chương trình hóa vào cặp thanh ghi EEDATH:EEDATA
3 Set bit EEPGD để trỏ đến bộ nhớ chương trình FLASH
4 Set bit WREN để cho phép những thao tác lập trình
5 Không cho phép ngắt
6 Thực hiện chuỗi 5 lệnh đặc biệt sau:
Ghi giá trị 55h vào EECON2 qua hai bước (đầu tiên đưa vào W, sau đó đưa vào EECON2 )
Ghi giá trị AAh vào EECON2 qua hai bước ( đầu tiên đưa vào W, sau đó đưa vào EECON2)
Set bit WR
7 Thực hiện hai lệnh NOP để cho phép bộ vi điều khiển thiết lập thao tác ghi
8 Cho phép các ngắt (nếu sử dụng ngắt)
9 Xóa bit WREN để không cho phép các thao tác lập trình
Tại thời điểm chu kỳ ghi hoàn thành, bit WR bị xóa và bit cờ ngắt EEIF được set Khi bộ vi điều khiển không thực hiện các lệnh trong suốt chu kỳ ghi, vi chương trình sẽ không nhất thiết phải kiểm tra cả EEIF, hoặc WR, để xác định quá trình ghi đã hoàn thành hay chưa
Vi điều khiển PIC16F877A có hai cơ chế bảo vệ mã, một bit dành cho bộ nhớ dữ liệu EEPROM và hai bit dành cho bộ nhớ chương trình FLASH Dữ liệu có thể được đọc
và ghi vào bộ nhớ dữ liệu EEPROM , bất chấp trạng thái của bit bỏa vệ mã CPD Khi sự bảo vệ mã được cho phép và bit CPD bị xóa thì sự truy cập ngoài thông qua bit ICSP không được cho phép, bất chấp trạng thái của những bit bảo vệ mã bộ nhớ chương trình
Trạng thái của những bit bảo vệ mã bộ nhớ chương trình CP0 và CP1 không ảnh hưởng đến sự thực hiện những lệnh bên ngoài bộ nhớ chương trình PIC16F87X có thể luôn luôn đọc những giá trị trong bộ nhớ chương trình, bất chấp trạng thái của những bit bảo vệ mã Tuy nhiên, trạng thái của những bit bảo vệ mã và bit WRT sẽ có những ảnh hưởng khác nhau đến quá trình ghi vào bộ nhớ chương trình Bit WRT là bit dùng để bảo
vệ quá trình ghi vào bộ nhớ chương trình FLASH Bit này chỉ có thể được truy cập khi PIC16F87X được lập trình qua ICSP Khi sự bảo vệ ghi được cho phép, bất kì lệnh ghi nào đến bộ nhớ chương trình FLASH đều sẽ bị ngăn cản Sự bảo vệ chế độ ghi không ảnh hưởng đến quá trình đọc bộ nhớ chương trình
Bộ chia 8 bit lập trình được bằng phần mềm
Chọn xung clock nội hoặc ngoại
Trang 22Ngắt khi có sự tràn từ FFh đến 00h
Chọn cạnh cho xung clock ngoài
Chế độ định thời (Timer) được chọn bằng cách xóa bit T0CS (OPTION_REG<5>) Trong chế độ định thời, bộ định thời Timer0 sẽ tăng dần sau mỗi chu kỳ lệnh (không có bộ chia ) Nếu thanh ghi TMR0 được ghi thì sự tăng sẽ bị ngăn lại sau hai chu kỳ lệnh
Chế độ đếm (Counter) được chọn bằng cách set bit T0SC (OPTION_REG<5>) Trong chế độ đếm, Timer0 sẽ tăng dần ở mỗi cạnh lên hoặc cạnh xuống của chân RA4/T0CKI Sự tăng cạnh được xác định bởi bit Timer0 Source Edge Select, T0SE (OPTION_REG<4> ) Bộ chia chỉ được dùng chung qua lại giữa bộ định thời Timer0 và
bộ định thời Watchdog Bộ chia không cho phép đọc hoặc ghi
Ngắt Timer0:
Ngắt TMR0 được phát ra khi thanh ghi TMR0 tràn từ FFh đến 00h Sự tràn này sẽ set bit T0IF (INTCON<2>) Ngắt này có thể được giấu đi bằng cách xóa đi bit T0IE (INTCON<5>) Bit T0IF cần phải được xóa trong chương trình bởi thủ tục phục vụ ngắt của bộ định thời Timer0 trước khi ngắt này được cho phép lại
Sử dụng Timer0 với xung clock ngoại:
Khi bộ chia không được sử dụng, clock ngoài đặt vào thì giống như bộ chia ở ngõ
ra Sự đồng bộ của chân T0CKI với clock ngoài được thực hiện bằng cách lấy mẫu bộ chia ở ngõ ra trên chân Q2 và Q4 Vì vậy thưc sự cần thiết để chân T0CKI ở mức cao trong ít nhất 2 chu kỳ máy và ở mức thấp trong ít nhất 2 chu kỳ máy
Bộ chia:
Thiết bị PIC16F87X chỉ có một bộ chia mà được dùng chung bởi bộ định thời 0 và
bộ định thời Watchdog Một khi bộ chia được ấn định cho bộ đinh thời 0 thì không có bộ chia cho bộ định thời Watchdog và ngược lại Bộ chia không được đọc hoặc ghi
Các bit PSA và PS2:PS0 trong thanh ghi OPTION_REG xác đinh bộ chia được ấn định cho bộ định thời nào và tỉ số chia
Trang 23Hình 2.2.4.1: Sơ đồ khối của bộ định thời Timer0 và bộ chia dùng chung với WDT
Các thanh ghi điều khiển liên quan đến Timer0 bao gồm:
TMR0 (địa chỉ 01h, 101h) : chứa giá trị đếm của Timer0
INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): cho phép ngắt hoạt động (GIE và PEIE)
OPTION_REG (địa chỉ 81h, 181h): điều khiển prescaler
2.2.4.2 Bộ định thời Timer 1
Bộ định thời 1 là một bộ định thời/bộ đếm 16 bit gồm hai thanh ghi TMR1H (byte cao) và TMR1L (byte thấp) mà có thể đọc hoặc ghi Cặp thanh ghi này tăng số đếm từ 0000h đến FFFFh và một tràn sẽ xuất hiện khi có sự chuyển số đếm từ FFFFh xuống 0000h Ngắt, nếu được phép có thể phát ra khi có số đếm tràn và được đặt ở bit cờ ngắt TMR1IF Ngắt có thể được phép hoặc cấm bằng cách đặt hoặc xóa bit cho phép ngắt TMR1IE
Bộ định thời Timer1 có thể được cấu hình để hoạt động một trong hai chế độ sau:
Định thời một khoảng thời gian (Timer)
Đếm sự kiện (Counter)
Việc lựa chọn một trong hai chế độ được xác định bằng cách đặt hoặc xóa bit chọn clock TMR1CS Trong chế độ định một khoảng thời gian, bộ định thời tăng số đếm lên sau mỗi chu kỳ lệnh Trong chế độ đếm sự kiện, bộ định thời tăng sau mỗi cạnh lên của clock ngoài đặt vào
Bộ định thời 1 có thể được phép hoặc cấm bằng cách đặt hoặc xóa bit điều khiển TMR1ON
Chế độ Timer:
Trang 24Chế độ Timer được chọn bằng cách xóa bit TMR1CS Trong chế độ này, nguồn clock đặt vào Timer là mạch dao động FOSC/4 Bit điều khiển đồng bộ không bị tác động
vì clock ngoài luôn luôn đồng bộ
Chế độ counter:
Trong chế độ này, bộ định thời tăng số đếm qua nguồn clock ngoài Việc tăng xảy
ra sau mỗi cạnh lên của xung clock ngoài Bộ định thời phải có một cạnh lên trước khi việc đếm bắt đầu
Có 2 chế độ đếm trong Timer 1:
Chế độ đếm đồng bộ:
Chế độ được lựa chọn bởi việc Set bit TMR1CS ( T1CON<1>)và Clear bit T1SYNC Trong chế độ này, giá trị của Timer1 sẽ tăng khi có xung cạnh lên trên chân T1OSI/RC1( nếu bit T1OSCEN được Set) hoặc trên chân T1OSO/RC0( nếu bit T1OSCEN được Clear)
Xung Clock ngoại sẽ được đồng bộ với xung Clock nội, hoạt động đồng bộ được thực hiện ngay sau bộ tiền định tỉ lệ xung(presaler) Trong chế độ ngủ, hoạt động đồng bộ
sẽ bị tắt và do đó ngay cả khi có xung Clock ngoài thì TMR1 cũng sẽ không tăng Điều này có ý nghĩa chế độ đếm đồng bộ sẽ không hoạt động được trong chế độ ngủ(Sleep)
Khi chế độ sử dụng xung Clock ngoài được lựa chọn cho Timer1 ở chế độ đếm đồng, chúng ta phải đảm bảo điều kiện: xung Clock ngoại phải được đồng bộ với xung Clock nội
Chế độ đếm không đồng bộ:
Nếu bit T1SYNC(T1CON<2>) được Set, xung Clock ngoại sẽ không được đồng
bộ hoá Bộ định thời sẽ tiếp tục đếm trong suốt quá trình ngủ của Vi điều khiển và có khả năng tạo một ngắt khi bộ định thời tràn và làm Vi điều khiển thoát khỏi trạng thái ngủ Tuy nhiên cần lưu ý khi đọc và ghi và Timer:
- Việc đọc thanh ghi TMR1H hoặc thanh ghi TMR1L trong khi bộ định thời đang chạy từ một nguồn xung Clock ngoài không đồng bộ sẽ cho một kết quả tức thời (không phải ngưng Timer lại làm mất độ chính xác) Tuy nhiên ta phải luôn nhớ rằng việc đọc một bộ Timer 16 bit sẽ bao gồm 2 lần đọc giá trị 8 bit, do đó có một vấn đề phát sinh là Timer có thể bị tràn giữa 2 lần đọc
- Để ghi vào Timer chúng ta tốt nhất nên dừng Timer lại và ghi giá tri mà ta mong muốn vào Chúng ta cũng có thể ghi giá trị vào Timer khi nó đang chạy nhưng việc này
có thể tạo ra một giá trị không như ta mong muốn
Trang 25Hình 2.2.4.2: Sơ đồ khối bộ định thời Timer1
Bộ dao động riêng của Timer1:
Chúng ta có thể xây dựng một bộ dao động độc lập cho Timer1 (độc lập với bộ dao động của Vi điều khiển) bằng thạch anh vớii tần số tối đa lên đến 200KHz Với bộ dao động này, bộ đếm có thể hoạt động ngay cả khi Vi điều khiển rơi vào trạng thái ngủ
Bảng 2: Lựa chọn tụ lọc cho dao động riêng của Timer1
Ngắt Timer1:
Ngằt trong Timer1 xuất hiện khi giá trị trong thanh ghi TMR1 tràn từ FFFFh xuống 0000h khi xảy ra tràn, cờ TMR1IF bật lên Ngắt có thể được ngăn chận bằng việc xoá bit TMR1IE Cờ TMR1IE phải được xoá bằng phần mềm trước khi thoát khỏi trình phục vụ ngắt và trở về chương trình chính Ngắt của Timer1 trong chế độ định thời và đếm đồng bộ không làm cho Vi điều khiển thoát khỏi trạng thái ngủ, chỉ có chế độ đếm không đồng bộ mới làm cho Vi điều khiển thoát khỏi trạng thái ngủ
Các thanh ghi liên quan đến Timer1 bao gồm:
INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): cho phép ngắt hoạt động (GIE và PEIE)
PIR1 (địa chỉ 0Ch): chứa cờ ngắt Timer1 (TMR1IF)
PIE1( địa chỉ 8Ch): cho phép ngắt Timer1 (TMR1IE)
TMR1L (địa chỉ 0Eh): chứa giá trị 8 bit thấp của bộ đếm Timer1
TMR1H (địa chỉ 0Eh): chứa giá trị 8 bit cao của bộ đếm Timer1
T1CON (địa chỉ 10h): xác lập các thông số cho Timer1
Trang 262.2.4.3 Bộ định thời Timer 2
Môdun Timer2 là 1 bộ định thời 8 bit bao gồm 1 bộ tiền định (prescaler), 1 bộ hậu định tỉ lệ (postcaler) và một thanh ghi chu kỳ viết tắt là PR2 việc kết hợp Timer2 với 2 bộ định tỉ lệ cho phép nó hoạt động như một bộ định thời 16 bit Môdun Timer2 cung cấp thời gian hoạt động cho chế độ điều biến xung PWM nếu môdun CCP được chọn
Nguồn xung Clock của Timer2: Timer2 chỉ có một nguồn xung Clock đó là xung Clock của Vi điều khiển Một bộ tiền định tỉ lệ được lựa chọn bởi các bit T2CKPS1 : T2CKPS0
Thanh ghi TMR2 và PR2: là 2 thanh ghi ghi/đọc được Timer2 sẽ tăng từ giá trị 00h lên tới giá trị nằm trong thanh ghi PR2, sau đó nó sẽ được Reset về 00h cho chu kỳ đếm kế tiếp
Tín hiệu báo trạng thái cân bằng: khi giá trị trong thanh ghi TMR2 bằng với giá trị trong PR2, bô so sánh sẽ tạo ra một xung báo hiệu, xung này có thể được dùng cho bộ hậu định tỉ lệ (postcaler) hoặc được dùng làm xung Clock cho môdun truyền nối tiếp (Shift Clock) Ngoài ra nó còn được dùng làm tín hiệu Reset cho Timer2
Xóa các bộ tỉ lệ:
Các bộ tỉ lệ được xoá khi:
- Ghi một giá trị vào thanh ghi TMR2
- Ghi một giá trị vào thanh ghi T2CON
- Bất cứ một dạng Reset thiết bị nào
Chế độ ngủ: trong chế độ ngủ Timer2 không hoạt động Giá trị của bộ định tỉ lệ
sẽ được lưu lại và phục hồi sau khi thoát khỏi trạng thái ngủ
Sơ đồ khối của bộ định thời Timer 2
Hình 2.2.4.3: Sơ đồ khối bộ định thời Timer2
Trang 27Các thanh ghi liên quan đến Timer2 bao gồm:
INTCON (địa chỉ 0Bh, 8Bh, 10Bh, 18Bh): cho phép toàn bộ các ngắt (GIE và PEIE)
PIR1 (địa chỉ 0Ch): chứa cờ ngắt Timer2 (TMR2IF)
PIE1 (địa chị 8Ch): chứa bit điều khiển Timer2 (TMR2IE)
TMR2 (địa chỉ 11h): chứa giá trị đếm của Timer2
T2CON (địa chỉ 12h): xác lập các thông số cho Timer2
PR2 (địa chỉ 92h): thanh ghi hỗ trợ cho Timer2
2.2.5 Hoạt động của các bô ngoại vi
2.2.5.1 Bộ Capture/Compare/PWM
Họ PIC16F87X có hai bộ CCP, mỗi bộ là một thanh ghi 16 bit mà có thể hoạt động như là :
Thanh ghi Capture 16 bit
Thanh ghi Compare 16 bit
Thanh ghi chu trình làm việc chủ/tớ PWM
Cả hai bộ CCP1 và CCP2 cơ bản hoạt động giống nhau, ngoại trừ trong khi hoạt động với sự kiện trigger đặt biệt
là một trong các yếu tố sau:
Sau mỗi cạnh lên của xung clock
Sau mỗi cạnh xuống của xung clock
Sau mỗi canh lên thứ tư
Sau mỗi cạnh lên thứ 16
Việc lựa chọn sự kiện nào được cấu hình bởi các bit điều khiển CCP1M3:CCP1M0 Nếu một sự kiện mới xảy ra trước khi giá trị trong thanh ghi CCPR1 được đọc, giá trị mới sẽ đè lên giá trị cũ
Trang 28Hình 2.2.5.1(a): Sơ đồ khối của bộ CCP hoạt động trong chế độ Capture
Giữ nguyên không đổi
Việc lựa chọn mức cao, mức thấp hay giữ nguyên không đổi bằng cách nạp giá trị thích hợp vào các bit điều khiển CCP1M3:CCP1M0 Tại một thời điểm, cờ ngắt CCP1IF
có thể được bật
Hình 2.2.5.1(b): Sơ đồ khối của bộ CCP hoạt động trong chế độ Compare
Chế độ PWM ( Điều biến độ rộng xung ) :
Trong chế độ này, một xung vuông 10 bit được tạo ra trên chân CCPx Vì chân này đa hợp với chân chốt của PORTC nên bit TRISC<2> phải được xóa để cấu hình cho chân CCP1 ở trạng thái xuất dữ liệu
Các bước sau được yêu cầu để thiết lập cho bộ CCP hoạt động trong chế độ PWM:
Thiết lập chu kỳ cho PWM bằng cách ghi lên thanh ghi PR2
Thiết lập chu trình họat động bằng cách ghi lên thanh ghi
CCPR1L và bit4 bit5 trong thanh ghi CCP1CON
Cấu hình cho chân CCP1 ở trạng thái xuất dữ liệu
Cấu hình cho bộ CCP1 hoạt động trong chế độ PWM
Trang 29Hình 2.2.5.1(c): Sơ đồ khối của bộ PWM
2.2.5.2 SPI
Chế độ SPI cho phép 8 bit dữ liệu được phát đồng bộ và được thu đồng thời Để truy xuất phần cứng chế độ SPI, các chân sau đây được sử dụng:
SDO (Serial Data Out)
SDI (Serial Data In)
và SS như là các chân port nối tiếp
Trang 30Chế độ Master:
Trong chế độ này, dữ liệu có thể được truyền tại bất kỳ thời điểm nào vì nó điều khiển trực tiếp chân SCK Trong chế độ này, dữ liệu được phát hoặc thu ngay khi thanh ghi SSPBUF được ghi Trong trường hợp bộ SPI thu dữ liệu, chân SDO có thể bị cấm.Thanh ghi SSPSR tiếp tục dịch dữ liệu qua chân SDI với tốc độ đã được lập trình.Với mỗi byte dữ liệu được thu, nó sẽ được nạp lên thanh ghi SSPBUF
Chế độ Slave:
Trong chế độ này, dữ liệu được phát hoặc thu ngay khi có một xung clock ngoài xuất hiện trên chân SCK Khi bit dữ liệu cuối cùng được chốt, cờ ngắt SSPIF được set Nguồn xung clock ngoài cấp trên chân SCK phải có tần số cao
Khi SPI hoạt động trong chế độ Slave, nó có thể làm việc khi thiết bị đang ở trong chế độ nghỉ Khi một byte dữ liệu được thu, thiết bị sẽ cập nhật từ chế độ nghỉ
2.2.5.3 USART
Bộ USART là một trong hai hình thức giao tiếp nối tiếp vào ra.USART cũng được biết như là bộ giao tiếp truyền thông nối tiếp USART có thể được cấu hình như là một hệ thống bất đồng bộ hoạt động song công mà có thể giao tiếp với các thiết bị bên ngoài như
là các thiết bị đầu cuối CRT và các máy tính cá nhân nó cũng có thể được cấu hình như là một hệ thống đồng bộ hoạt động bán công mà có thể giao tiếp với các mạch tích hợp A/D hay D/A, các EEPROM nối tiếp….USART có thể được cấu hình để hoạt động một trong các chế độ sau:
Bất đồng bộ (song công)
Đồng bộ chủ (bán công)
Đồng bộ tớ (bán công)
Máy phát tốc độ baud USART (BRG):
BRG hỗ trợ cả hai chế độ bất đồng bộ và đồng bộ.Trong chế độ bất đồng bộ, bit BRGH điều khiển trực tiếp tốc độ baud trong chế độ đồng bộ, BRGH được bỏ qua Hình bên dưới chỉ ra công thức tính tốc độ baud cho các chế độ USART khác nhau mà chỉ ứng dụng cho chế độ Master
Bằng cách cho trước tốc độ baud và FOSC , giá trị nguyên gần nhất được nạp vào thanh ghi SPBRG có thể được tính dựa trên công thức hình dưới đây
Công thức tính tốc độ Baud
X = giá trị trong thanh ghi SPBRG (từ 0 đến 225 )
Bộ USART hoạt động trong chế độ bất đồng bộ:
Trong chế độ này, USART sử dụng kiểu địng dạng chuẩn NRZ (non–return–zero) gồm một start bit, 8 hoặc 9 bit dữ liệu và một stop bit Dữ liệu thường được định dạng là
8 bit Chế độ bất đồng bộ được chọn bằng cách xóa bit SYNC (TXSTA<4>)
Bộ USART bất đồng bộ bao gồm các thành phần quan trọng sau:
Bộ phát tốc độ baud (BRG)
Trang 31phép bằng cách đặt hoặc xóa bit TXIE ( PIE<4>) Cờ TXIF sẽ được đặt bất chấp trạng thái của bit TXIE và không thể được xóa bởi phần mềm.Nó chỉ có thể được xóa khi
dữ liệu mới được nạp vào thanh ghi TXREG Trong khi bit TXIF chỉ ra trạng thái của thanh ghi TXREG thì bit TRMT lại chỉ ra trạng thái của thanh ghi TSR Bit này chỉ có thể đọc, được đặt khi thanh ghi TSR rỗng
Việc phát dữ liệu được phép bằng cách cho phép bit TXEN Việc phát dữ liệu thực
sư không xảy ra cho đến khi thanh ghi TXREG được nạp dữ liệu và bộ BRG tạo ra một clock dịch.Việc phát dữ liệu cũng có thể được bắt đầu bằng nạp thanh ghi TXREG và cho phép bit TXEN
Để có thể phát 9 bit dữ liệu , bit TX9 được đặt và 9 bit dữ liệu được ghi đến bit TX9D.Bit thứ 9 phải được ghi trước khi ghi 8 bit dữ liệu đến TXREG
Để thiết lập chế độ phát bất đồng bộ, các bước sau được thực hiện:
1) Thiết lập tốc độ Baud cho thanh ghi SPBRG, nếu tốc độ baud được yêu cầu cao, đặt bit BRGH
2) Cho phép port nối tiếp bất đồng bộ bằng cách xóa bit SYNC và bit SPEN 3) Nếu ngắt được yêu cầu, cho phép bit TXIE
4) Nếu cần phát 9 bit dữ liệu , đặt bit TX9
5) Cho phép phát dữ liệu bằng cách đặt bit TXEN
6) Nạp dữ liệu đến thanh ghi TXREG
7) Trường hợp có sử dụng ngắt , phải bảo đảm rằng bit GIE và bit PEIE trong thanh ghi INTCON được đặt
Bộ thu bất đồng bộ USART :
Dữ liệu được thu trên chân RC7/RX/DT.Mỗi khi chế độ bất đồng bộ được chọn, việc thu dữ liệu được cho phép bằng cách đặt bit CREN ( RCSTA<4>) Để thiết lập chế
độ thu bất đồng bộ, các bước sau được yêu cầu :
1) Thiết lập tốc độ baud cho thanh ghi SPBRG Nếu tốc độ cao được yêu cầu, set bit BRGH
2) Cho phép port nối tiếp bất đồng bộ bằng cách xóa bit SYNC và đặt bit SPEN 3) Nếu ngắt được yêu cầu, set bit cho phép ngắt RCIE 4) Nếu cần thu 9 bit dữ liệu, set bit RX9
4) Cho phép việc thu dữ liệu bằng cách set bit CREN
Trang 325) Cờ RCIF sẽ được đặt khi việc thu dữ liệu hòan thành và một ngắt có thể phát ra nếu cho phép ngắt
6) Đọc nội dung thanh ghi RCSTA để nhận bit dữ liệu thứ 9 và xác định các lỗi xảy trong quá trình thu dữ liệu
7) Nhận 8 bit dữ liệu thu được bằng cách đọc nội dung thanh ghi RCREG
8) Nếu có lỗi xảy ra, xóa lỗi bằng xóa bit cho phép CREN
2.2.5.4 Bộ chuyển đổi tương tự sang số A/D
Bộ chuyển đổi tương tự - số có năm ngõ vào đối với thiết bị 28 chân và tám đối với các thiết bị khác Ngõ vào tương tự được lấy mẫu, ngõ ra của mẫu được đặt vào bộ biến đổi Bộ biến đổi phát một giá trị nhị phân tương ứng với ngõ vào tương tự.Giá trị tương tự được bộ biến đổi cho một kết quả số tương ứng với 10 bit nhị phân.Bộ biến đổi
có các thế ngưỡng cao và thấp đặt vào mà phần mềm có thể lựa chọn trên chân RA2 ,RA3
Bộ biến đổi A/D có đặt điểm duy nhất là hoạt động có thể hoạt động trong khi thiết bị đang ở chế độ nghỉ
Bộ biến đổi A/D có 4 thanh ghi , chúng là :
Thanh ghi kết quả cao (ADRESH)
Thanh ghi kết quả thấp (ADRESL)
Thanh ghi điều khiển 0 (ADCON0)
Thanh ghi điều khiển 1 (ADCON1)
Thanh ghi ADCON0 được chỉ ra ở hình 11-1 điều khiển hoạt động của bộ biến đổi Thanh ghi ADCON1 cấu hình chức năng cho các chân port Chân port có thể được cấu hình như là tín hiệu tương tự vào hoặc tín hiệu số vào ra
Trang 33Hình 2.2.4.4: Sơ đồ khối của bộ chuyển đổi A/D
2.2.5.5 Hoạt động ngắt
Các Vi điều khiển họ PIC có rất nhiều nguồn ngắt Cứ mỗi môdun ngoại vi thì có một nguồn ngắt, tuy nhiên một số môdun lại có rất nhiều nguồn ngắt sau đây là một số nguồn ngắt tiêu biểu:
- Ngắt trên chân INT (ngắt ngoài)
Trang 34ngắt.Hoạt động ngắt được điều khiển bởi thanh ghi INTCON (bit GIE) Bên cạnh đó mỗi ngắt còn có một bit điều khiển và cờ ngắt riêng Các cờ ngắt vẫn được set bình thường khi thỏa mãn điều kiện ngắt xảy ra bất chấp trạng thái của bit GIE, tuy nhiên hoạt động ngắt vẫn phụ thuôc vào bit GIE và các bit điều khiển khác Bit điều khiển ngắt RB0/INT
và TMR0 nằm trong thanh ghi INTCON, thanh ghi này còn chứa bit cho phép các ngắt ngoại vi PEIE Bit điều khiển các ngắt nằm trong thanh ghi PIE1 và PIE2 Cờ ngắt của các ngắt nằm trong thanh ghi PIR1 và PIR2
Trong một thời điểm chỉ có một chương trình ngắt được thực thi, chương trình ngắt được kết thúc bằng lệnh RETFIE Khi chương trình ngắt được thực thi, bit GIE tự động được xóa, địa chỉ lệnh tiếp theo của chương trình chính được cất vào trong bộ nhớ Stack và bộ đếm chương trình sẽ chỉ đến địa chỉ 0004h Lệnh RETFIE được dùng để thoát khỏi chương trình ngắt và quay trở về chương trình chính, đồng thời bit GIE cũng
sẽ được set để cho phép các ngắt hoạt động trở lại Các cờ hiệu được dùng để kiểm tra ngắt nào đang xảy ra và phải được xóa bằng chương trình trước khi cho phép ngắt tiếp tục hoạt động trở lại để ta có thể phát hiện được thời điểm tiếp theo mà ngắt xảy ra
Cần chú ý là trong quá trình thực thi ngắt, chỉ có giá trị của bộ đếm chương trình được cất vào trong Stack, trong khi một số thanh ghi quan trọng sẽ không được cất và có thể bị thay đổi giá trị trong quá trình thực thi chương trình ngắt Điều này nên được xử lí bằng chương trình để tránh hiện tượng trên xảy ra
Hình 2.2.5.5: Sơ đồ của tất cả các ngắt trong vi điều khiển PIC16F877A
Trang 353.1.1 Các khai báo biến
int1 số 1 bit có giá trị là 0 hoặc 1
int8 số nguyên 1 byte ( 8 bit) có giá trị từ từ -127 đến 128
int16 số nguyên 16 bit
int32 số nguyên 32 bit
char ký tự 8 bit
float số thực 32 bit
short như kiểu int1
byte như kiểu int8
int như kiểu int8
long như kiểu int16
Khai báo Unsigned ở phía trước để đó là số không dấu.
Ví dụ: Unsigned int8 sẽ có giá trị từ 0 đến 255
3.1.2 Khai báo mãng
3.1.2.1 Khai báo mãng 1 chiều
Đối với việc khai báo mãng 1chiều có 2 cách để khai báo đó là khai báo mãng
tĩnh và mãng động
Khai báo mãng tĩnh: Int8 const a[i]={a0,……., ai}
Nếu khai báo mảng như trên thì ta sẻ có 1 mảng gồm i phần tử
Lưu ý: nếu đánh không đủ số phần tử vào trong ngoặc kép như đã khai báo, các phần tử còn lại sẽ là 0 Truy xuất giá trị vượt quá chỉ số mãng khai báo sẻ làm chương trình chạy vô tận
VD: int8 const a[7]={1,2,3,4,5,6} thì phần tử thứ 7 sẽ mang giá trị là 0
Khai báo mãng động: Int8 const a[]={a0,…….,ai}
Nếu khai báo mảng như trên thì ta sẻ có 1 mảng có kích thước bằng với số phần tử được nhập vào
VD: int8 const a[]={1,2,3,4,5,6,7} thì mãng a[] sẽ có kích thước là 7
3.1.2.2 Khai báo mãng 2 chiều
Int8 const a[i][j]={a00,………….,a0j
………
Trang 38{case (value 1):{lệnh 1;break;}
case (value 2):{lệnh 2;break;}
Cú pháp : #include <tên PIC.h>
Luôn phải có và đăt ở dòng đầu tiên
Cú pháp: #USE DELAY (CLOCK=SPEDD)
Khai báo tần số thạch anh sử dụng
VD: #use delay (clock=4000000)
#USE FAST_IO
Cú pháp: #use fast_io(tên Port)
Trang 393.4.2. Các lệnh delay
Delay_cycles(value)
Value : giá trị từ 0 đến 255 Là số chu kì lệnh 1 chu kì lệnh bằng 4 chu kì máy
Delay_us(time)
Time là thời gian delay đơn vị tính là µs
Nếu Time là hằng số thì Time nằm trong khoảng 0 ≤ Time ≥ 65535
Nếu Time là biến số thì Time nằm trong khoảng 0 ≤ Time ≥ 255
Delay_ms(time)
Time là thời gian delay đơn vị tính là ms
Nếu Time là hằng số thì Time nằm trong khoảng 0 ≤ Time ≥ 65535
Nếu Time là biến số thì Time nằm trong khoảng 0 ≤ Time ≥ 255
ADC_CLOCK_INTERNAL : thời gian lấy mẫu bằng tốc độ xung Clock
ADC_CLOCK_DIV_2 : thời gian lấy mẫu bằng tốc độ xung Clock/2
ADC_CLOCK_DIV_8 : thời gian lấy mẫu bằng tốc độ xung Clock/8 ADC_CLOCK_DIV_32 : thời gian lấy mẫu bằng tốc độ xung Clock/32
Setup_ADC_ports ( value )
Xác định chân lấy tín hiệu Analog và điện thế chuẩn
- ALL_ANALOGS : tất cả các chân đều để đọc Analog : A0 A1 A2 A3 A5 E0 E1 E2 (Vref=Vdd)
- NO_ANALOG : Không dùng Analog các chân sẻ là I/O
- AN0_AN1_AN2_AN4_AN5_AN6_AN7_VSS_VREF : A0 A1 A2 A5 E0 E1 E2 VRefh=A3
- AN0_AN1_AN2_AN3_AN4 : A0 A1 A2 A3 A5
- AN0_AN1_AN3 : A0 A1 A3 , Vref = Vdd
- AN0_AN1_VSS_VREF : A0 A1 VRefh = A3
Trang 40- AN0_AN1_AN4_AN5_AN6_AN7_VREF_VREF : A0 A1 A5 E0 E1 E2 VRefh=A3 , VRefl=A2
- AN0_AN1_AN2_AN3_AN4_AN5 : A0 A1 A2 A3 A5 E0
- AN0_AN1_AN2_AN4_AN5_VSS_VREF : A0 A1 A2 A5 E0 VRefh=A3
- AN0_AN1_AN4_AN5_VREF_VREF : A0 A1 A5 E0 VRefh=A3 VRefl=A2
- AN0_AN1_AN4_VREF_VREF : A0 A1 A5 VRefh=A3 VRefl=A2
- AN0_AN1_VREF_VREF : A0 A1 VRefh=A3 VRefl=A2
Setup_Timer_0 (mode|bộ chia tần)
Hàm này có chức năng là cài đặt bộ timer0
Trong đó mode là:
RTCC_Internal : xung tác động là xung nội
RTCC_EXT_L_TO_H : xung (cạnh lên) tác động từ chân RA4
RTCC_EXT_H_TO_L : xung (cạnh xuống) tác động từ chân RA4