135
Tính năng nổi bật Giao tiếp PC qua cổng USB, không cần cài đặt driver. Hỗ trợ Window XP/ Windows Vista/ Window7 32-bit/64-bit OS Tốc độ nạp/gỡ rối cực nhanh. Chức năng giao tiếp UART và Logic Analyzer Hỗ trợ tt cả các dòng PIC10F, PIC12F, PIC16F, PIC18F, PIC24, dsPIC30, dsPIC33, và PIC32 và một số sản phẩm Serial EEPROM của Microchip. Hỗ trợ nạp cho cả PIC 5V và 3.3V Có khả năng cung cp ngun 5V, 3.3V từ USB và ngun trên board. Tích hợp Socket đa năng có th nạp cho tt cả các dòng PIC 8/14/18/20/28/40 chân. Tự động cập nhật Firmware khi có phiên bản mới Chip mới (New device) có th được bổ sung bằng việc cập nhật phần mềm. Sử dụng phần mềm nạp PICkit 2 Programmer được phát trin bởi Microchip và có th down tại trang web: www.microchip.com Chi tiết sản phẩm 1. Giới thiệu PICKIT 2 STUDENT 5V/3.3V PICKIT 2 STUDENT 5V/3.3V là 1 sản phẩm do AT-COM phát trin từ PICKit 2 Programmer / Debugger của Microchip, đ cung cp giải pháp lập trình cho các dòng vi điều khin 8bit/16bit/32bit của hãng Microchip. PICKIT 2 STUDENT 5V/3.3V với chi phí thp, nhưng hỗ trợ khá đầy đủ các tính năng cho sinh viên, cá nhân nghiên cứu, học tập và lập trình ứng dụng trên dòng vi điều khin PIC của Microchip. Hỗ trợ nạp cho cả các dòng vi điều khin PIC hoạt động ở điện áp 3.3V, 5V. 2. Tính năng của PICKIT 2 STUDENT 5V/3.3V Phn mm nạp PICkit 2 Programmer

Bai Giang Pic Rat Hay Va Day Du

  • Upload
    cuongrm

  • View
    85

  • Download
    7

Embed Size (px)

Citation preview

Page 1: Bai Giang Pic Rat Hay Va Day Du

Tính năng nổi bật

Giao tiếp PC qua cổng USB, không cần cài đặt driver.

Hỗ trợ Window XP/ Windows Vista/ Window7 32-bit/64-bit OS

Tốc độ nạp/gỡ rối cực nhanh.

Chức năng giao tiếp UART và Logic Analyzer

Hỗ trợ tât cả các dòng PIC10F, PIC12F, PIC16F, PIC18F, PIC24, dsPIC30, dsPIC33, và PIC32 và một số sản

phẩm Serial EEPROM của Microchip.

Hỗ trợ nạp cho cả PIC 5V và 3.3V

Có khả năng cung câp nguôn 5V, 3.3V từ USB và nguôn trên board.

Tích hợp Socket đa năng có thê nạp cho tât cả các dòng PIC 8/14/18/20/28/40 chân.

Tự động cập nhật Firmware khi có phiên bản mới

Chip mới (New device) có thê được bổ sung bằng việc cập nhật phần mềm.

Sử dụng phần mềm nạp PICkit 2 Programmer được phát triên bởi Microchip và có thê down tại trang

web: www.microchip.com

Chi tiết sản phẩm1. Giới thiệu   PICKIT 2 STUDENT 5V/3.3V

PICKIT 2 STUDENT 5V/3.3V  là 1 sản phẩm do AT-COM phát triên từ PICKit 2 Programmer / Debugger của

Microchip, đê cung câp giải pháp lập trình cho các dòng vi điều khiên 8bit/16bit/32bit của hãng Microchip.

PICKIT 2 STUDENT 5V/3.3V   với chi phí thâp, nhưng hỗ trợ khá đầy đủ các tính năng cho sinh viên, cá nhân

nghiên cứu, học tập và lập trình ứng dụng trên dòng vi điều khiên PIC của Microchip. Hỗ trợ nạp cho cả các dòng

vi điều khiên PIC hoạt động ở điện áp 3.3V, 5V.

2. Tính năng của   PICKIT 2 STUDENT 5V/3.3V

Phân mêm nạp PICkit 2 Programmer

Page 2: Bai Giang Pic Rat Hay Va Day Du

Phân mêm  PICKIT 2 Logic Tool

Page 3: Bai Giang Pic Rat Hay Va Day Du

3.  Hướng dân sử dụng   PICKIT 2 STUDENT 5V/3.3V

PICKIT 2 STUDENT 5V/3.3V   giao tiếp với thiết bị thông qua chuẩn giao tiếp ICSP, quy định bởi Microchip.

 

Page 4: Bai Giang Pic Rat Hay Va Day Du

 PICKIT 2 STUDENT 5V/3.3V   hỗ trợ nạp cho cả PIC 5V và 3.3V. Đê câu hình mode nạp 5V/3V3. Chúng ta thay

đổi jumper Select_VCC trên board.

PICKIT 2 STUDENT 5V/3.3V   hỗ trợ nạp tât cả các dòng PIC 8/14/18/20 chân và PIC 28/40 chân. Đê chọn

mode nạp cho PIC 8/14/18/20 chân hoặc PIC 28/40 chân. Chúng ta thay đổi jumper Select_PIC trên board.

4.     Hướng dân sử dụng phân mêm     PICkit 2 Programmer

PICKIT 2 STUDENT 5V/3.3V sử dụng phần mềm nạp PICkit 2 Programmer do nhà sản xuât Microchip phát triên

với giao diện như sau:

Page 5: Bai Giang Pic Rat Hay Va Day Du

Kết nôi PICkit 2 với thiết bị

Kết nối PICKIT 2 STUDENT 5V/3.3V thông qua ICSP connector 6 chân.

Sau khi nối dây theo chuẩn ICSP, nhân nút check communication đê kiêm tra kết nối với Chip

Page 6: Bai Giang Pic Rat Hay Va Day Du

Nếu kết nối đúng và không có lỗi, ta sẽ có kết quả như sau :

Nếu PICkit 2 không thê dò ra thiết bị kết nối, ta cũng có thê chọn từ menu Device Family đã nói ở trên.

Các lỗi thường gặp như sau :

Kiêm tra kết nối ICSP có đúng chiều, Kiêm tra thiết bị có bị quá tải hoặc nối tắt, có thê

câp nguôn cho mạch ngoài mà không dùng PICkit 2

Nhập file hex cân nạp:

File>Import HEX

 Sau đó nhân vào nút write đê nạp chương trình, nếu thành công, sẽ hiện ra bảng thông

báo sau :

 

 AT-SKY chuyên cung câp sỉ và lẻ các loại linh kiện điện tử, linh kiện công suât. Nhập khẩu các linh kiện điện tử chính hãng của các nhà sản xuât từ các quốc gia như China, Taiwan, Singapore, Thailand...Thiết kế, lập trình, gia công các mạch điện tử và chuyên giao công nghệ cho các quý công ty theo yêu cầu. AT-SKY luôn cam kết làm việc: “Uy tín – Đảm Bảo – Chất Lượng”. Mọi chi tiết xin liên hệ: [email protected]

Page 7: Bai Giang Pic Rat Hay Va Day Du

Bài 1 : Cài đặt MPLAB IDE 8.36

1.1 Giới thiệuMPLAB IDE là phần mềm được hỗ trợ bởi Microchip, dùng đê soạn thảo code cho các ứng dụng của PIC. Hiện tại, tháng 8/2010 MPLAB IDE đã có phiên bản 8.51. Trong tài liệu này tôi chọn phiên bản 8.36 vì nó có khá nhiều lỗi về câu hình . Các phiên bản khác như 8.43, bạn có thê không chọn câu hình ban đầu nhưng bản thân nó có thê tự động tìm kiếm các thư viện cần thiết trong quá trình biên dịch. Với phiên bản 8.36 chúng ta phải câu hình toàn bộ cho IDE.1.2 Cài đặt MPLAB IDE 8.36Bước 1 : Double Click vào file setup trong thư mục MPLAB IDE 8.36. Màn hình Welcome sẽ hiện ra như sau. Bạn chọn Next đê tiếp tục.

Hình 1.1 : Welcome to MPLAB IDE 8.36

Bước 2 : Chọn I accept the term of the license agreement và chọn Next.

Page 8: Bai Giang Pic Rat Hay Va Day Du

Hình 1.2 : License Agreement

Bước 3 : Đê chế độ mặc định là cài đặt Complete và chọn Next đê tiếp tục.

Hình 1.3 : Chọn cài đặt complete

Bước 4 : Chọn đường dân cài đặt, ta nên đê mặc định là C:\Program Files\Microchip\

Page 9: Bai Giang Pic Rat Hay Va Day Du

Hình 1.4 : Chọn đường dân cài đặt

Bước 5 : Tiếp tục chọn I accept cho Maestro License và C32 License.

Hình 1.5 : Maestro License

Page 10: Bai Giang Pic Rat Hay Va Day Du

Hình 1.6 : C32 License

Bước 6 : Giao diện sau tổng kết lại các lựa chọn của bạn, nhân Next đê tiến hành cài đặt. Nếu muốn hiệu chỉnh bạn nhân Back.

Hình 1.7 : Bắt đầu cài đặt

Page 11: Bai Giang Pic Rat Hay Va Day Du

Hình 1.8 : Chờ cài đặt xong

Bước 7 : Khi cài đặt xong MPLAB IDE sẽ hỏi bạn có cần cài Hi Tech không. Đây là compiler C hỗ trợ cho MPLAB IDE, tuy nhiên ta sẽ không dùng compiler này mà sẽ dùng MPLAB C18. Bạn chọn No nhân Finish đê hoàn tât việc cài đặt MPLAB IDE.

Hình 1.9 : Cài đặt hoàn tât

Thông báo dưới đâu xuât hiện, thống kê các tài liệu hướng dân đi kèm. Các tài liệu này đều nằm trong thư mục cài đặt C:\Program Files\Microchip\

Page 12: Bai Giang Pic Rat Hay Va Day Du

Hình 1.10 : Các tài liệu hướng dân

Bài 2 : Cài đặt compiler MPLAB C18

2.1 Giới thiệuKhi cài đặt xong MPLAB IDE, compiler mặc định cho nó là MPASM, dùng đê dịch project viết bằng ASM sang file HEX. Muốn viết chương trình bằng C, ta cần phải cài đặt thêm 1 compiler khác có hỗ trợ cho chip PIC đang dùng. Trong phần này, tôi thí nghiệm trên vi điều khiên PIC18F4520 và chọn compiler C18 đê hỗ trợ cho lập trình C chuẩn.2.2 Các bước cài đặtBước 1 : Double Click vào file MPLAB C18 V1.0.exe đê tiến hành cài đặt, màn hình welcome của MPLAB C18 sẽ hiện ra như sau :

Hình 2.1 : Welcome MPLAB C18

Bước 2 : Chọn nơi lưu trữ cho các file biên dịch của MPLAB C18, ta có thê đê mặc định là C:\mcc18 .

Page 13: Bai Giang Pic Rat Hay Va Day Du

Hình 2.2 : Chọn đường dân lưu trữ

Bước 3 : Chọn lựa các thành phần của gói MCC18, thông thường ta sẽ chọn hết tât cả các gói trong compier C18.

Hình 2.3 : Chọn các gói cài đặt

Bước 4 : Nhân Next đê tiến hành cài đặt

Page 14: Bai Giang Pic Rat Hay Va Day Du

Hình 2.4 : Cài đặt C18

Chờ cho đến khi cài đặt xong.

Hình 2.5 : Chờ cài đặt C18

Bước 5 : Nhân Finish đê kết thúc cài đặt MPLAB C18.

Page 15: Bai Giang Pic Rat Hay Va Day Du

Hình 2.6 : Kết thúc cài đặt C18

2.3 Cập nhật lên C18 version 3.01Phiên bản mà ta vừa cài đặt là C18 v1.0. Đê cập nhật lên v3.01, ta sẽ double click và file MPLAB-C18-pgrade-doc-v3_01.exe. Màn hình welcome sẽ hiện ra như sau:

Hình 2.7 : Welcome C18 update

Chọn I Accept và nhân Next đê tiếp tục cài đặt.

Page 16: Bai Giang Pic Rat Hay Va Day Du

Hình 2.8 : License Agreement

Các tài liệu hỗ trợ lập trình cho compiler C18 đi kèm.

Hình 2.9 : Các tài liệu hướng dân

Chọn thư mục mặc định cho việc update (giống với thư mục cài đặt C18)

Page 17: Bai Giang Pic Rat Hay Va Day Du

Đê mặc định các thành phần sẽ được cài đặt, không cần phải check thêm.

Hình 2.10 : Các gói cài đặt C18 v3.01

Check chọn thêm các option dưới đây đê MPLAB IDE tự động câu hình các thông số tương thích với phiên bản C18 v3.01

Page 18: Bai Giang Pic Rat Hay Va Day Du

Hình 2.11 : Chọn câu hình update cho MPLAB IDE

Chọn Next đê tiến hành Update

Hình 2.12 : Tiến hành cài đặt

Chờ cho đến khi hoàn tât.

Page 19: Bai Giang Pic Rat Hay Va Day Du

Hình 2.13 : Chờ cho đến khi hoàn tât

Nhân Finish đê kết thúc.

Hình 2.14 : Cài đặt hoàn tât

Bài 3 : Tạo project trên MPLAB 8.36 và C18 3.01

Tạo 1 project lần đầu trên MPLAB khá phức tạp. Người sử dụng cần phải câu hình cho MPLAB khá nhiều. Tuy nhiên hầu hết các thông số câu hình này sẽ được lưu lại cho lần sau, chúng ta chỉ cần phải thiết lập 1 lần. Phần này hướng dân cách tạo 1 project đơn giản trên MPLAB cho chip 18F4520 và mạch nạp PICKit2 trên board BKIT PIC.3.1 Tạo mới projectKích hoạt chương trình MPLAB IDE 8.36 từ biêu tượng Microchip trên màn hình Desktop, cửa sổ sau đây sẽ hiện ra.

Page 20: Bai Giang Pic Rat Hay Va Day Du

Hình 3.1 : Màn hình khởi động của MPLAB IDE 8.36

Chọn menu Project và chọn New

Hình 3.2 : Tạo mới project

Cửa sổ sau đây hiện ra, bạn đặt tên cho project ở khung Project Name và chọn đường dân cho nó ở khung Project Directory.

Page 21: Bai Giang Pic Rat Hay Va Day Du

Hình 3.3 : Đặt tên và chọn thư mục lưu trữ

Cửa sổ làm việc của project sẽ hiện ra ở bên trái như hình dưới đây. Nếu cửa sổ project không hiện ra bạn sẽ chọn menu View và chọn Project.

Hình 3.4 : Cửa sổ project

Chọn compile C18 cho project này bằng cách chọn vào menu Project và chọn Select Language Toolsuite.

Page 22: Bai Giang Pic Rat Hay Va Day Du

Hình 3.5 : Chọn Language ToolSuite (Compiler)

Chọn Active Toolsuite là Microchip C18 Toolsuite. Các đường dân của các chương trình trong gói compiler cho C18 đã được câu hình trong lúc cài đặt C18 upgrade, bạn không cần phải chỉnh lại. Các gói này đều nằm trong thư mục C:\mcc18.

Hình 3.6 : Chọn compiler C183.2 Cấu hình cho chipPhần này có ảnh hưởng đối với quá trình dịch và nạp cho chip. Chọn menu Configure và chọn Select Device… đê chọn chip.

Page 23: Bai Giang Pic Rat Hay Va Day Du

Hình 3.7 : Select Device

Giao diện dưới đây hiện ra và bạn chọn cho đúng chip mà mình đang dùng. Ở đây tôi chọn chip PIC18F4520.

Nhân OK đê đóng cửa sổ này lại. Tiếp theo đó là việc lựa chọn câu hình thạch anh và 1 số câu hình khác. Bạn vào lại menu Configure và chọn Configuration Bits…

Page 24: Bai Giang Pic Rat Hay Va Day Du

Hình 3.8 : Configuration Bits

Màn hình đê bạn câu hình cho chế độ hoạt động của chip dưới đây hiện ra. Check bỏ dâu chọn ở Configuration Bits set in code đê bạn có thê thay đổi các thông số. Thông số đầu tiên là chế độ thạch anh, tùy vào mỗi loại chip và thạch anh mà chọn lựa khác nhau. Ở đây tôi sử dụng thạch anh ngoài 12MHz nên sẽ chọn chế độ thạch anh là HS (High Speed). Các chế độ thạch anh của PIC18F4520 sẽ được đề cập ở các bài sau.PORTB bit 4-0 ở chế độ mặt định là các chân analog. Khi không sử dụng analog bạn cần phải chỉnh sang chế độ Digital khi reset.Disable chức năng Low Voltage Programming (LVP - Nạp điện áp thâp), mạch PICKit2 không hỗ trợ chức năng này.Sau khi hoàn thành bạn check lại Configuration Bits set in code và đóng cửa sổ này lại.

Page 25: Bai Giang Pic Rat Hay Va Day Du

Hình 3.9 : Thiết lập thạch anh, PortB, LVP3.3 Tạo mới file và add thư viện cho projectBước tiếp theo là tạo file source đê viết code. Từ toolbar bạn có thê chọn New File hoặc và menu File và chọn New.

Page 26: Bai Giang Pic Rat Hay Va Day Du

Hình 3.10 : Tạo mới source file

Một file mới được tạo ra với tên mặc định là Untitled như hình dưới đây.

Hình 3.11 : File mới được tạo ra

Bạn nhân và menu File và chọn Save As… đê lưu lại file này. Cửa số dưới đây hiện ra và bạn chọn đường dân đê lưu cho chính xác. Thông thường ta sẽ lưu trong thư mục chứa project hiện tại cho dễ quản lý.

Page 27: Bai Giang Pic Rat Hay Va Day Du

Hình 3.12 : Lưu file trong thư mục chứa project

Nhân Save đê lưu file với tên mới là main.c và đóng cửa sổ trên lại. Bước tiếp theo là add file vừa mới lưu (main.c) và thư mục Source File của project. Click chuột phải vào Source File và chọn Add Files…

Hình 3.13 : Add file vào Source Files

Chọn đường dân đến file main.c và nhân Open.

Page 28: Bai Giang Pic Rat Hay Va Day Du

Hình 3.14 : Browse đường dân đến main.c

File main.c sẽ được add vào mục Source File của project như hình bên dưới.

Hình 3.15 : Add xong main.c cho Source Files

Tiếp theo ta sẽ add các thư viện cho project. Đầu tiên là Header Files. Cũng tương tự như khi add file vào Source File, click chuột phải và chọn Add Files. Browse đường dân đến C:\mcc18\h và chọn file p18f4520.h hoặc gõ tên file này vào mục File name rôi nhân Open.

Page 29: Bai Giang Pic Rat Hay Va Day Du

Hình 3.16 : Add Header File

Add file vào mục Linker Script, browse đường dân đến C:\mcc18\lkr và chọn file 18f4520.lkr.

Hình 3.17 : Add file Linker Script

Add file lib vào mục Library Files, 18f4520.lib tại thư mục C:\mcc18\lib

Page 30: Bai Giang Pic Rat Hay Va Day Du

Hình 3.18 : Add Library File3.4 Cấu hình cho quá trình dịch projectKhi dịch project, compiler cần 1 số file object của nó (chẳng hạn như c018i.o), ta cần phải chỉ đường dân tìm kiếm các file object này cho compiler. Đối với 1 số phiên bản MPLAB, nó tự động tìm đúng các file này. Tuy nhiên đối với phiên bản 8.36 ta cần phải chỉ định đường dân tìm kiếm. Từ menu Project, chọn Build Option và chọn Project.

Giao diện Build Option hiện ra, tại mục Show Directories for bạn chọn Include Search Path, chọn New và Browse đường dân đến C:\mcc18\h.Sau đó chỉnh sang Library Search Path và tạo mới 1 đường dân C:\mcc18\lib

Page 31: Bai Giang Pic Rat Hay Va Day Du

Hình 3.19 : Tạo đường dân cho include file

Page 32: Bai Giang Pic Rat Hay Va Day Du

Hình 3.20 : Tạo đường dân cho Library File

Nhân OK đê hoàn tât việc câu hình của quá trình dịch.3.5 Viết code cho projectDouble Click vào file main.c và bắt đầu viết code cho project. Ta viết 1 đoạn code nhỏ đê làm cho các led nối với PORTB của vi điều khiến sáng xen kẽ (PORTB = 0xAA)

Code:

#include <p18f4520.h>void main(){

TRISB = 0x00;PORTB = 0xAA;while(1);

}

Page 33: Bai Giang Pic Rat Hay Va Day Du

Hình 3.21 : Double Click và main.c và viết code

Đê kiêm tra code viết có lỗi hay không bạn vào menu Project và chọn Build All hoặc nhân tổ hợp phím nóng Ctrl F10. Nếu không có lỗi thông báo BUILD SUCCEEDED sẽ xuât hiện.

Hình 3.22 : Biên dịch thành công3.6 Kết nôi với boardSau khi biên dịch thành công, bạn kết nối máy tính với board đê nạp và chạy thử chương trình. Với mạch BKIT PIC bạn cắm dây USB vào chân mạch nạp, bật công tắt nguôn và gạt tât cả các switch của SW2 lên ON đê kết nối mạch nạp PICKit2.

Page 34: Bai Giang Pic Rat Hay Va Day Du

Hình 3.23 : Kết nối với PICKit2 trên BKIT PIC

Gạt tât cả các switch của SW1 lên ON đê enable nút Reset, Led ở PortB và chân thạch anh ngoài.

Hình 3.24 : Enable Reset, Led và XTAL ngoài3.7 Cấu hình mạch nạpTừ menu Programmer chọn Select Programmer và chọn mạch nạp tương ứng là PICKit2. Muốn chọn mạch nạp khác hoặc kết nối với mạch nạp lỗi bạn phải chọn lại None rôi sau đó mới chọn lại mạch nạp.

Hình 3.25 : Chọn mạch nạp

Đê thuận tiện cho quá trình lập trình, ta nên thiết lập thêm 1 số thông số cho mạch nạp đê có thê tự

Page 35: Bai Giang Pic Rat Hay Va Day Du

động nạp và chạy chương trình khi biên dịch không có lỗi. Đê làm được điều này ta sẽ chọn Programmer và chọn Settings.

Hình 3.26 : Setting cho mạch nạp

Giao diện sau hiện ra và bạn check chọn Program after successful build (Nạp chương trình khi biên dịch thành công) và Run after a successful program (Chạy chương trình khi nạp thành công). Nhân OK đê kết thúc.

Hình 3.27 : Câu hình nạp và chạy chương trình

Bây giờ bạn nhân lại tổ hợp phím Ctrl F10 (Build All), MPLAB sẽ làm 1 loạt các thao tác nếu không có

Page 36: Bai Giang Pic Rat Hay Va Day Du

lỗi : Dịch chương trình – Nạp chương trình – Kéo chân VDD lên mức cao đê thả chân Reset và chương trình bắt đầu chạy trên board.

Hình 3.28 : Dịch - Nạp - Chạy chương trình

Hình ảnh chương trình chạy trên board BKIT PIC như sau :

Hình 3.29 : Chương trình chạy trên BKIT P

Page 37: Bai Giang Pic Rat Hay Va Day Du

ài 4 : Khảo sát các chế độ dao động

1.1 Giới thiệuDòng PIC18F có 10 chế độ dao động khác nhau, kí hiệu và tên gọi của chúng như sau:

1. LP : Low Power Crystal , thạch anh có tần số dao động thâp (khoảng vài chục kHz).2. XT : Crystal/ Resonator, thạch anh/resonator có tần số trung bình (dưới 4MHz).3. HS : High Speed Crystal/Resonator, thạch anh/resonator có tần số cao (trên 4Mhz).4. HSPLL : High Speed Crystal/Resonator with Phase Locked Loop enabled, thạch anh tần số

cao với bộ khuyết đại PLL.5. RC : External Resistor/Capacitor with Fosc/4 output on RA6, dao động RC ngoài,output với

tần số chia 4 ở chân RA6.6. RCIO : External Resistor/Capacitor with I/O on RA6, chân RA6 là I/O.7. INTIO1 : Internal Oscillator with Fosc/4 output on RA6 and I/O on RA7, dao động nội, output

ở chân RA6, input/output ở chân RA7 với tần số Fosc/4 .8. INTIO2 : Internal Oscillator with I/O on RA6 and RA7, dao động nội với RA6, RA7 là I/O.9. EC : External Clock with Fosc/4 output, clock ngoài, RA6 là output tần số Fosc/4.10. ECIO : External Clock with I/O on RA6, clock ngoài, RA6 là chân I/O.

1.2 Crystal và ResonatorĐây là loại dao động đơn giản nhât. Resonator còn có tên gọi khác là Ceramic Resonator. Hình ảnh của Crystal và Resonator như hình bên dưới. Các loại dao động LP, XT, HS, HSPLL sẽ dùng Crystal hoặc Resonator.

 

Ở chế độ hoạt động này, Crystal/Resonator sẽ được kết nối với 2 chân OSC1 và OSC2 của vi điều khiên như hình dưới đây.Khi dùng Crystal, giá trị của tụ điện phụ thuộc vào tần số của Crystal như bảng dưới đây

Bảng 2 1 : Giá trị Capacitor cho Crystal

Page 38: Bai Giang Pic Rat Hay Va Day Du

Giá trị của tụ điện càng cao thì dao động càng ổn định, nhưng bù lại thời giai khởi động sẽ lâu hơn.Khi dùng Resonator, giá trị của tụ điện như sau:

Bảng 2 2 : Giá trị Capacitor cho Resonator

Khi tần số resonator lớn hơn 3.5 MHz ta nên câu hình là HS thay vì XT.1.3 External ClockNguôn dao động clock ngoài được nối vào chân OSC1. Đặc điêm của loại dao động này là vi điều khiên hoạt động ngay khi có nguôn câp (hoặc thức dậy từ chế độ sleep) mà không cần tốn thời gian khởi động (start-up time). Đối với chip PIC18F thì dao động này có 2 loại :

EC : chân RA6 output với tần số Fosc/4 (Fosc là tần số clock đưa vào chân OSC1). Chân output này có thê dùng đê kiêm tra hoặc làm chân clock cho 1 số ứng dụng (như 1 tín hiệu đông bộ). Trong cửa số Configuration Bits, tên gọi của chế độ này là EC-CLKOUT on RA6.

ECIO : chân RA6 truy xuât như 1 I/O bình thường. Trong cửa sổ Configuration Bits, tên gọi của chế độ này là EC-Port on RA6.

1.4 Dao động RCĐối với 1 vài ứng dụng không đòi hỏi độ chính xác về định thời cao thì dao động RC là 1 lựa chọn tiết kiệm. Do tần số dao động tại chân OSC1 phụ thuộc vào điện áp câp, điện trở, tụ điện, nhiệt độ và thậm chí là hãng sản xuât chip, nên tần số dao động RC không được chính xác. Chế độ này cũng có 2 loại là RC (RC-CLKOUT on RA6, Port on RA7) : Clock out với tần số chia 4 ở chân RA6 và RCIO (RC-Port on RA6, Port on RA7) : RA6, RA7 sử dụng như I/O.1.5 Bộ khuếch đại tân sô PLLPLL là 1 mạch tích hợp bên trong chip, có tác dụng nâng tần số input lên nhiều lần, nâng cao tốc độ thực thi chương trình của vi điều khiên. Bộ PLL có thê được dùng kết hợp với nhiều chế độ hoạt động thạch anh của vi điều khiên PIC.

HSPLL : PLL khi dùng với chế độ HS có thê nhân gâp 4 lần tần số input. Khi đó tần số input

Page 39: Bai Giang Pic Rat Hay Va Day Du

tối đa là 10Mhz, tần số khuếch đại đạt 40MHz. Trong cửa sổ Configuration Bits tên gọi của chế độ này là HS-PLL enabled freq = 4xFosc1. Trong chế độ này bit PLLEN không có tác dụng.

PLL và INTOSC : PLL cũng có thê được dùng kết hợp với bộ dao động nội, khi đó tần số khuếch đại có thê đạt 32Mhz. Chế độ này phải được thiết lập bằng phần mềm, không có option chọn lựa trong cửa số Configuration Bits. PLLEN bit dùng đê kích hoạt chế độ này.

1.6 Bộ dao động nộiGần tương tự với bộ dao động External Clock, bộ dao động nội (Internal Oscillator Block) cũng có 2 chế độ, output tần số Fosc/4 ở chân RA6 và chế độ I/O ở chân này. Tần số của bộ dao động nội được lập trình software. Các thanh ghi ảnh hưởng đến tần số này là OSCCON và OSCTUNE.Ở bộ dao động nội có 2 nguôn clock, nguôn clock 8MHz và nguôn clock RC 31kHz. Bộ nguôn clock 8MHz sẽ đi qua 1 bộ chia (Prescaller) và câp clock cho thiết bị hoạt động. Giá trị của bộ chia này được xác định bởi 3 bit IRCF2:IRCF0 trong thanh ghi OSCCON. Khi giá trị các bit đều là 0 thì việc chọn clock source dựa vào bit INTRC trong thanh ghi OSCTUN. Nếu INTRC = 0 thì tần số lây từ clock source thứ 2, 31kHz. Ngược lại tần số sẽ là 8MHz/256 = 31.5kHz (bộ chia là 256 cho clock 8MHz).Khi tần số của bộ dao động nội là 4MHz hoặc 8MHz (OSCCON<6:4> = 110 hoặc 111) thì nó có thê được sử dụng kết hợp với bộ PLL. Đê kích hoạt bộ PLL ta phải set bit PLLEN ở thanh ghi OSCTUNE lên 1.1.7 DemoKit BKIT PIC được thiết kế dùng switch gạt đê kết nối với thạch anh (crystal) 20MHz, nên ta có thê sử dụng chế độ thạch anh ngoài không PLL (PLL chỉ dùng được với thạch anh nhỏ hơn 10MHz) hoặc dùng thạch anh nội kết hợp với PLL.Đê demo tần số cung câp cho chip, ta sẽ viết chương trình cứ 1s tăng giá trị của PORTB lên 1 đơn vị.Một câu lệnh trong PIC chiếm 4 chu kì dao động.1.7.1 Thạch anh ngoài 20MHzTa sẽ dùng 2 vòng lặp for đê tạo hiệu ứng delay. Với chu kì 20MHz ta phải đếm 5 000 000 chu kì lệnh (do 1 chu kì lệnh chiếm 4 chu kì dao động).Khi muốn tính toán chính xác thời gian, ta phải dùng các câu lệnh ASM. Khi viết bằng ngôn ngữ C, ta chỉ có thê ước lượng gần đúng. Câu lệnh (for i=0 ; I < MAX_I ; i++) tốn khoảng 4 chu kì lệnh : i++ tốn 2 chu kì lệnh, i< MAX_I tốn 2 chu kì lệnh, lệnh gán i =0 chỉ thực hiện 1 lần nên ta có thê bỏ qua.Vậy hàm tạo hiệu ứng trì hoãn 1s với tần số 20MHz ta sẽ viết như sau:Code:

void delay1s_20MHz(){

int i,j;for(i=0;i<250;i++){

for(j=0;j<1250;j++){}

}}

Như đã đề cập ở trên, 1 vòng for thực hiện khoảng 4 chu kì lệnh nên tổng số chu kì lệnh của 2 vòng for ở trên là (250 * 4) * (1250 *4) = 5 000 000.Hàm main ta có thê viết như sau:Code:

void main(){TRISB = 0x00; //setup PORTB is outputPORTB = 0x00; //init valuewhile(1){

PORTB++; //increase PORTBDelay1s_20MHz(); //call delay 1s

}

Page 40: Bai Giang Pic Rat Hay Va Day Du

}

Chỉnh chế độ thạch anh trong cửa sổ Configuration Bits là HS, PORTB là Digital (mặc định là analog), Disable chức năng nạp điện áp thâp (LVP), dịch và nạp chương trình ta sẽ thây giá trị PORTB tăng dần sau 1s.Chỉnh chế độ thạch anh sang chế độ LP hoặc XT, dịch và nạp lại chương trình bạn sẽ thây chương trình không chạy hoặc chạy sai. Do với thạch anh 20MHz ta phải chọn là HS như datasheet của PIC18F4520.

1.7.2 Thạch anh nội 8MHzCũng tương tự như trên, ở chế độ thạch anh nội 8MHz ta phải thực hiện 2 000 000 chu kì lệnh.Hàm tạo hiệu ứng trì hoãn 1s với tần số 20MHz ta sẽ viết như sau:Code:

void delay1s_8MHz(){

int i,j;for(i=0;i<250;i++){

for(j=0;j<1250;j++){}

}}

Đê sử dụng được thạch anh nội 8MHz, trước tiên ta phải câu hình là dùng thạch anh nội trong cửa sổ Configuration Bits (chọn INT RC – Port on RA6, Port on RA7), sau đó viết code trong hàm main đê lựa chọn bộ Prescaller cho nguôn clock 8MHz. Ta sẽ set 3 bit <6:4> của thanh ghi OSCCON lên 1. Hàm main sẽ viết như sau:Code:

void main(){TRISB = 0x00; //setup PORTB is outputPORTB = 0x00; //init valueOSCCON |= 0x70 //set bit <6:4> -> freq = 8MHzwhile(1){

PORTB++; //increase PORTBDelay1s_8MHz(); //call delay 1s

}}

1.7.3 Thạch anh nội 8MHz và PLLKhi sử dụng thạch anh nội 8MHz và bộ PLL nhân 4, tần số dao động câp cho chip sẽ là 32MHz, vậy ta phải đếm 8 000 000 chu kì lệnh. Hàm tạo hiệu ứng delay sẽ như sau:Code:

void delay1s_8MHzPLL(){

int i,j;for(i=0;i<500;i++){

for(j=0;j<1000;j++){}

}}

Hàm main ngoài việc chọn Prescaller cho clock nội ta phải set thêm bit PLLEN (bit 6) trong thanh ghi OSCTUNE:

Code:

Page 41: Bai Giang Pic Rat Hay Va Day Du

void main(){

TRISB = 0x00; //setup PORTB is outputPORTB = 0x00; //init valueOSCCON |= 0x70 //set bit <6:4> -> freq = 8MHzOSCTUNE |= 0x40//enable PLLwhile(1){

PORTB++; //increase PORTBDelay1s_8MHzPLL(); //call delay 1s

}}

__________________BS

The Following 2 Users Say Thank You to bs135 For This Useful Post:

InterMilan (12-01-2013), xuanbach05 (11-01-2013)

  #6 (permalink) 14-01-2013, 07:56 PM

bs135 Administrator

Join Date: Sep 2008Posts: 340Thanks: 155Thanked 367 Times in 163 Posts

 Bài 5 : Interrupt và ngắt Timer

Bài 5 : Interrupt và ngắt Timer

2.1 Interrupt trong PICDòng PIC18F4520 (2420, 2520, 4420) có nhiều nguôn ngắt (interrupt source) và 2 mức ưu tiên ngắt (high priority interrupt và low priority interrupt). Vector ngắt có mức ưu tiên cao có địa chỉ 0x08 còn ngắt có mức ưu tiên thâp có địa chỉ 0x18. Khi hàm phục vụ ngắt quãng cho ngắt ưu tiên thâp đang xảy ra, ngắt ưu tiên cao xảy ra sẽ tạm dừng ngắt ưu tiên thâp và phục vụ cho ngắt ưu tiên cao.

Đối với 1 ngắt, thông thường có 3 bit đê điều khiên nó:

Flag bit : Cờ báo hiệu interrupt, khi flag bit được set, ngắt sẽ xảy ra. Enable bit : Cho phép ngắt đối với các ngắt có mặt nạ (maskabled interrupt) Priority bit : Thiết lập ưu tiên ngắt, khi được set ngắt sẽ có mức ưu tiên cao.

Đê có thê thiết lập mức độ ưu tiên cho các nguôn ngắt, ta phải enable chức năng ưu tiên ngắt bằng cách set IPEN bit (Interrupt Priority Enable bit : RCON<7>). 

Khi IPEN = 1 : GIEH bit (INTCON<7>) sẽ enable các ngắt có mức ưu tiên cao, GIEL bit (INTCON<6>) sẽ enable các ngắt có mức ưu tiên thâp. Khi ngắt toàn cục, Flag bit, Enable bit được set, ngắt sẽ được kích hoạt, con trỏ chương trình sẽ nhảy tới địa chỉ 0x08 hoặc 0x18 tùy theo ngắt đó được thiếp lập là ưu tiên cao (Priority bit là 1) hay ưu tiên thâp (Priority bit là 0).

Khi IPEN = 0 : Đây là trường hợp mặc định, disable chức năng ưu tiên ngắt (gọi là chế độ compatibility mode). INTCON<6> lúc này là PEIE bit, enable hay disable các ngắt ngoại vi (peripheral interrupt). INTCON<7> lúc này là GIE bit, enable hay disable tât cả các nguôn ngắt. Ở chế độ compatibility này, tât cả các ngắt sẽ nhảy đến địa chỉ 0x08.

Khi các nguôn ngắt có cùng độ ưu tiên, chúng sẽ cùng nhảy đến 1 địa chỉ ngắt. Hàm phục vụ ngắt quãng cần phải kiêm tra tât cả các cờ đê xác định nguôn ngắt nào đang gây ra ngắt. Cờ ngắt cần được xóa đê tránh hiện tượng ngắt đệ quy (recursive interrupt), vi điều khiên sẽ lặp vô tận trong hàm ngắt cho đến khi tràn stack.

Page 42: Bai Giang Pic Rat Hay Va Day Du

Điêm chú ý quan trọng trong thanh ghi INTCON là khi IPEN = 1 : INTCON<7> = 1 sẽ enable tât cả các ngắt có ưu tiên cao nhưng khi INTCON<7> = 0 nó lại disable tât cả các ngắt, bao gôm cả ngắt ưu tiên thâp. Một ngắt ưu tiên thâp ngoài việc thiết lập GIEL (INTCON<6>) còn phải set luôn cả bit GIEH (INTCON<7>).2.2 Giới thiệu Timer0Timer0 có 2 chế độ 16 bit hoặc 8 bit. Clock câp cho timer 0 có thê là clock nội hoặc clock ngoại (lây từ chân T0CKI). Ngoài ra Timer0 còn có bộ Prescaller đê chia tần số clock.

Hình 2.1 : Thanh ghi điều khiên T0CON

Timer0 được điều khiên bởi thanh ghi T0CON. Ý nghĩa các bit trong thanh ghi này như sau:Bit 7 TMR0ON : Bật tắt Timer 0.1 : Bật Timer 0 .0 : Tắt Timer 0.Bit 6 T08BIT : Chọn câu hình cho Timer 0.1 : Timer 16 bit.0 : Timer 8 bit.Khi hoạt động ở chế độ 16 bit, giá trị của bộ định thời (counter)/ bộ đếm Timer 0 được ghi vào 2 thanh ghi TMR0H và TMR0L. Ngược lại, ở chế độ 8 bit, giá trị đếm được lưu trong thanh ghi TMR0L.Bit 5 T0CS : Chọn nguôn clock cho Timer 0.1 : Clock ngoài từ chân T0CKI.0 : Clock nội (Fosc/4).Bit 4 T0SE : Chọn chế độ kích Timer 0 khi dùng nguôn ngoài.1 : Timer 0 đếm lên khi có tín hiệu từ High sang Low ở chân T0CKI.0 : Timer 0 đếm lên khi có tín hiệu từ Low sang High ở chân T0CKI.Bit 3 PSA : Bật/ Tắt chế độ Prescaller cho Timer 0.1 : Tắt Prescaller.0 : Cho phép Prescaller.Bit 2 : 0 T0PS2 :T0PS0 : Chọn giá trị Prescaller.111 : 1:256 011 : 1:16110 : 1:128 010 : 1:8101 : 1:64 001 : 1:4100 : 1:32 000 : 1:2Khi chọn bộ Prescaller, tần số của Timer 0 sẽ bị chia xuống. Ví dụ thạch anh dùng cho mạch là 20MHz, thì tần số của clock nội là Fosc/4 = 5MHz. Nếu ta chọn Prescaller là 1:2 thì tần số đếm của timer 0 là 2.5MHz.

Khi Timer 0 đếm tràn từ FF :FF (chế độ 16 bit) hoặc FF (chế độ 8 bit) lên 0, cờ TMR0IF sẽ được bật lên 1 và gây ra ngắt nếu các bit cho phép ngắt (ngắt toàn cục, ngắt timer0) được set lên 1.

2.3 Lập trình module Timer02.3.1 Hàm init_timer0Trong phần này, chúng ta sẽ khởi tạo timer0 ở chế độ 16 bit, sử dụng clock nội và prescaller 1:2, ngắt timer0 sẽ được câu hình là ngắt ưu tiên thâp và sau mỗi 1ms sẽ xảy ra ngắt 1 lần.

Timer0 sẽ đếm lên sau mỗi lần tích cực của clock. Trong chế độ 16 bit, khi giá trị trong 2 thanh ghi TMR0H:TMR0L chuyên từ FFFF sang 0000 sẽ xảy ra ngắt, cờ TMR0IF sẽ được bật lên 1.

Mạch BKIT PIC sử dụng thạch anh 20MHz, nên clock nội cho timer0 sẽ là 5MHz (timer0 sẽ đếm 5 000 000 đơn vị trong 1 giây). Đê có được ngắt 1ms ta sẽ nạp cho thanh ghi TMR0H:TMR0L giá trị thâp hơn FFFF 5000 đơn vị.

Vì Timer0 được câu hình sử dụng prescaller 1:2, nên con số này sẽ thâp hơn FFFF 2500 đơn vị : 65535 – 2500 = 63035 = F63B. Việc nạp giá trị này cho thanh ghi TMR0 sẽ được thực hiện trong hàm phục vụ ngắt quãng timer0_isr.

Đê enable ngắt timer 0, ta cần set bit ngắt toàn cục GIE, set bit ngắt thâp GIEL, set bit enable timer

Page 43: Bai Giang Pic Rat Hay Va Day Du

0 TMR0IE và cờ ngắt timer 0 TMR0IF trong thanh ghi INTCON. Câu hình ưu tiên ngắt timer 0 là ngắt thâp bằng cách clear bit TMR0IP trong thanh ghi INTCON2.

Hàm ngắt timer0 sẽ được khởi tạo như sau:Code:

void init_timer0(){

counter0 = 0;//counter for virtual timertimer0_flag = 0;//flag for virtual timer

T0CON = 0x00;//timer0 16bit mode, internal clock, Prescaller 1:2

RCONbits.IPEN = 1;//enable interrupt priorityINTCON2bits.TMR0IP = 0;//low interrupt priority

INTCONbits.GIE = 1;//enable global interruptINTCONbits.GIEL =1;//enable low priority interruptINTCONbits.TMR0IE = 1;//enable timer0 interruptINTCONbits.TMR0IF = 1;//force timer0 interrupt

}

2.3.2 Hàm timer0_isrHàm này được gọi khi ngắt Timer0 xảy ra. Đối với tât cả các ngắt của PIC, ta cần phải xóa cờ ngắt trước tiên vì nó không được tự động xóa bằng phần cứng. Trong hàm phục vụ ngắt quãng Timer0 này ta nên tắt nó đi bằng cách xóa bit TMR0ON, nạp lại giá trị cho 2 thanh ghi đếm Timer0. Ở cuối hàm phục vụ ngắt quãng ta sẽ bật cho Timer0 đếm lên (set bit TMR0ON). Giá trị trong 2 thanh ghi đếm Timer0 sẽ tăng dần theo mỗi xung nhịp của clock, và khi đạt giá trị FFFF nó sẽ xảy ra ngắt lần tiếp theo.

Code:

void timer0_isr(){

INTCONbits.TMR0IF = 0; //clear interrupt flagT0CONbits.TMR0ON = 0; //stop timer 0

TMR0H = 0xF6; //reconfig timer 0TMR0L = 0x3B; //1ms interrupt

//CODE HEREvirtual_timer();//END CODE

T0CONbits.TMR0ON = 1; //start timer 0}

Đê gọi được hàm này, ta phải dùng thêm chỉ thị pragma đê dịch 1 hàm tại địa chỉ nhât định và chỉ thị pragma interrupt đê dịch hàm này là dạng hàm interrupt. Timer0 được câu hình là ngắt ưu tiên mức thâp (low priority interrupt), nên khi ngắt xảy ra, con trỏ chương trình sẽ nhảy tới địa chỉ 0x18. Chương trình hiện thực lệnh gọi hàm timer0_isr được hiện thực ở cuối file main.c

Code:

#pragma code#pragma interrupt low_interrupt_isrvoid low_interrupt_isr(){

if(INTCONbits.TMR0IF == 1)timer0_isr();

}

Page 44: Bai Giang Pic Rat Hay Va Day Du

#pragma code _vector_low = 0x18void _vector_low(void){

low_interrupt_isr();}

#pragma codevoid main(){

while(1){}

}

Với chỉ thị đầu tiên, hàm vecter_low sẽ được dịch tại địa chỉ 0x18, là địa chỉ vector ngắt thâp. Do 2 địa chỉ ngắt của PIC là 0x08 cho ngắt cao và 0x18 cho ngắt thâp cách gần nhau, nên ta sẽ chỉ đặt thật ít lệnh tại 2 địa chỉ này. Trên đây chỉ đặt 1 lệnh gọi hàm low_interrupt_isr tại địa chỉ 0x18. Trong hàm này ta sẽ kiêm tra ngắt đang xảy ra có phải là Timer0 hay không bằng cách xét bit thứ 2 của thanh ghi INTCON (bit TMR0IF) trước khi gọi hàm timer0_isr. Hàm main() bây giờ phải thêm chỉ thị #pragma code đê compiler dịch hàm này ở 1 vùng nhớ khác trong vùng code memory.

Ngoài Timer0, PIC còn có thêm 3 Timer nữa. Về các chức năng cơ bản như Timer0, chúng còn có thêm 1 vài chức năng đặc biệt khác.

2.4 Giới thiệu Timer 1Khác với Timer0 là 1 interrupt, Timer1 là 1 Peripheral Interrupt. Vì vậy đê có thê enable cho ngắt Timer1, ta phải set bit PEIE.

Tương tự với Timer0, Timer1 cũng có chức năng counter từ clock ngoài (ở chân T13CKI) và tăng giá trị lên 1 mỗi khi có clock cạnh lên ở chân T13CKI.

Khi chọn clock ngoài, T1SYNC bit dùng đê chọn chế độ cho counter, là Ansynchronous Counter hoặc Synchronous Counter. Hai loại counter này đều tăng giá trị đếm lên 1 sau mỗi lần tích cực của clock, điêm khác biệt của chúng nằm ở kết nối phần cứng. Synchronous Counter câp clock cho tât cả các flip flop trong khi Ansynchronous Counter chỉ câp clock cho flip flop đầu tiên.

Hình 2.2: Synchronous Counter

Page 45: Bai Giang Pic Rat Hay Va Day Du

Hình 2.3 : Ansynchronous Counter

Bên cạnh đó, Timer1 còn có thê đếm lên nhờ dao động ngoài ở 2 chân T1OSI và T1OSO. Người ta thường dùng thạch anh 32,768kHz và biến Timer1 thành 1 bộ Real Time Clock (đông hô thời gian thực) . Sơ đô kết nối như sau:

Hình 2.4 : Timer1 Osillator

Đê sử dụng được chức năng này ta cần phải set bit T1OSCEN.

Chức năng đặc biệt cuối, Timer1 là ngôn clock cho module CCP. Chi tiết về module này sẽ được trình bày ở Bài 16. Hai timer còn lại thường được dùng tích hợp với các module khác, Timer2 (có thêm bộ Post Scaller) sẽ được dùng cho module PWM ở Bài 14 và Timer3 sẽ được dùng cho module Capture ở Bài 16.2.5. Ngắt Timer1 và Timer2Timer 1:Khi không có interrupt priority : GIE enable all interrupts, PEIE/GIEL enable all peripheral interrupt.

Khi có interrupt priority : GIE enable all high interrupt, nhưng nếu bằng 0 sẽ disable all interrupts. Nên nếu set timer 1 là interrupt mức thâp thì phải set GIEH lên đê enable, sau đó set tiếp GIEL đê enable interrupt ưu tiên thâp. Nếu timer1 mức cao thì phải set GIEH đê enable high interrupt và set PEIE vì timer1 là peripheral interrupt.

Timer 2:

Page 46: Bai Giang Pic Rat Hay Va Day Du

Timer 8 bit, giá trị trong thanh ghi TMR2 khi bằng với PR2 sẽ set cờ TMR2IF và gây ra ngắt.Prescaller là bộ chia tần số input. (1,4,16)PostScaller là bộ chia tần số output. (1-16)Timer 2 là peripheral interrupt.

Code:

void init_timer2(){

T2CON = 0x00;//postscaller 1T2CONbits.T2OUTPS0 = 1;T2CONbits.T2OUTPS1 = 0;T2CONbits.T2OUTPS2 = 0;T2CONbits.T2OUTPS3 = 0;//prescaller 4T2CONbits.T2CKPS0 = 1;T2CONbits.T2CKPS1 = 0;

}void init_timer2_interrupt(){

//enable timer 2 interruptPIE1bits.TMR2IE = 1;//enable interrupt priorityRCONbits.IPEN = 1;//enable timer1 low priority interruptIPR1bits.TMR2IP = 0;

INTCONbits.GIEH = 1;INTCONbits.GIEL = 1;//force into interruptTMR2 = 0x00;PR2 = 200;PIR1bits.TMR2IF = 1;

}#pragma code vector_high = 0x08void _vector_high(void){

_asmgoto timer1_isr_high_endasm

}

#pragma code vector_low = 0x18void _vector_low(void){

_asmbtfsc PIR1, 0, 0goto timer1_isr_lowbtfsc PIR1, 1, 0goto timer2_isr_low_endasm

}#pragma interrupt timer2_isr_lowvoid timer2_isr_low(){

static int counter = 0;counter++;PIR1bits.TMR2IF = 0;

if(counter == 6250){

Page 47: Bai Giang Pic Rat Hay Va Day Du

PORTB++;counter = 0;

}}

2.6. Code mâu

Bài 6 : Ma trận phím

3.1 Khái niệmMa trận phím là cách kết nối các phím theo hàng và cột. Cách kết nối như vậy sẽ tiết kiệm được tài nguyên của vi điều khiên. Ví dụ dưới đây là cách mắc ma trận phím 4x4 :

Hình 3.1 : Ma trận phím 4x4

Ta có 16 phím và 8 tín hiệu điều khiên. Nếu mắc 16 phím này như các phím đơn, ta phải cần đến 16 tín hiệu điều khiên.3.2 Giải mã ma trận phímTa xét 1 ma trận phím 2x2 như hình dưới đây:

Page 48: Bai Giang Pic Rat Hay Va Day Du

Hình 3.2 : Ma trận 2x2

Khi phím A được nhân thì điện áp tại C1 sẽ bằng R1. Như vậy nếu ban đầu tại C1 và C2 là mức cao, R1 là mức thâp và R2 là mức cao, thì khi phím A được nhân, điện áp tại C1 (ban đầu là mức cao) sẽ bị kéo xuống mức thâp. 

Hình 3.3 : Phím A được nhân

Tương tự nếu phím B được nhân thì C2 sẽ bị kéo xuống mức thâp.Đê xác định 2 phím C và D có được nhân hay không, ta sẽ nâng điện áp tại R1 lên mức cao, kéo điện áp tại R2 lên mức cao (chuyên hàng tích cực).

Page 49: Bai Giang Pic Rat Hay Va Day Du

Hình 3.4 : Phím D được nhân

Như vậy, đê xác định vị trí của phím nào được nhân, ta sẽ duyệt qua tât cả các hàng và xét các phím hàng đó. Quy ước tín hiện DEACTIVE là mức 1 và tín hiện ACTIVE là mức 0, từng bước giải mã ma trận phím như sau:

Cho tín hiệu các cột là DEACTIVE Cài đặt tín hiện tại các cột là INPUT Cho tín hiện các hàng là DEACTIVE Cài đặt tín hiệu các hàng là OUTPUT Lặp qua các hàng

o Cho tín hiệu hàng đang xét là ACTIVE.o Xét các cột trong hàng đang cho ACTIVE, cột nào có tín hiệu ACTIVE là phím tương

ứng được nhân. Kết thúc vòng lặp

3.3 Viết chương trình

Chương trình dành cho giải mã ma trận gôm 2 phần : phần đầu dùng đê khởi tạo các chân vi điều khiên, phần 2 là duyệt qua các hàng và cột đê xác định phím nào được nhân. File key_matrix.h định nghĩa các hằng số và 2 hàm dùng trong ma trận phím:

Code:

#define TRIS_BUTTON TRISC#define PORT_BUTTON PORTC#define MAX_COL 4#define MAX_ROW 4extern char key_data[];extern char key_code[];void init_key_matrix();void scan_key_matrix();

key_code là 1 mảng 16 phần tử tương ứng với 16 phím, nếu phím được nhân thì phần tử tương ứng có giá trị là 1.

key_data cũng là 1 mảng 16 phần tử, ta có thê dùng đê lưu thông tin cho phím vị trí thứ nhât, chẳng hạn như data đê hiện thị số 0 (0x3F) trên led 7 đoạn.3.3.1 Khởi tạo ma trận phím

Page 50: Bai Giang Pic Rat Hay Va Day Du

Theo như sơ đô kết nối ma trận phím ở hình 4.1, ta sẽ khởi tạo các hàng là output và các cột là input. Quy định DEACTIVE là mức 1 nên ta sẽ gán giá trị ban đầu của PORTC là 0xFF.Code:

void init_key_matrix(){

TRIS_BUTTON = 0x0F; //C3-C0:input C7-C4:outputPORT_BUTTON = 0xFF;

}

3.3.2 Quét ma trận phímNhư đã đề cập giải thuật ở trên, ta sẽ lần lượt duyệt qua tât cả các hàng bằng cách xuât tín hiệu của hàng đó là ACTIVE (mức 0) rôi xét từng cột.

Code:

void scan_key_matrix(){

int i,j;//loop all rowsfor(i=0;i<MAX_ROW;i++){

//pull down row iPORT_BUTTON &= ~(1<<(7-i));//loop all colsfor(j=0;j<MAX_COL;j++){

//reset key codekey_code[i*MAX_ROW+j] = 0;

//when col j is activatedif((PORT_BUTTON & (1<<j)) == 0){

//set key code key_code[i*MAX_ROW+j] = 1;

}}//pull up row iPORT_BUTTON |= (1<<(7-i));

}}

3.3.3 Hàm mainỜ file main.c, ta sẽ include file key_matrix.h đê có thê gọi được các hàm của nó. Biến key_code được extern ở file key_matrix.h nên ta cũng có thê truy xuât ở file main.c.Code:

#include "KEY_MATRIX\\key_matrix.h"void main(){

int i;TRISB = 0x00; //init PORTB for outputPORTB = 0x00; //initial valueinit_key_matrix();while(1){

scan_key_matrix();for(i=0;i<16;i++){

if(key_code[i] != 0){

PORTB = i;break;

}}

}

Page 51: Bai Giang Pic Rat Hay Va Day Du

}

Code chi tiết của ma trận phím các bạn có thê tham khảo ở Bai7.

Bài 7 : Chông rung cho ma trận phím

4.1 Nguyên lí chông rung

Hình 4.1 : Hiện tượng rung phím

Hình trên minh hoạ mức điện áp của 1 phím nhân tích cực mức 0, ở trạng thái bình thường, điện áp vi điều khiên nhận vào là 5V còn khi nhân là 0V. Tuy nhiên, do độ rung cơ học của phím, tại thời điêm vừa nhân xuống, điện áp sẽ không ổn định trong 1 khoảng thời gian, trước khi ổn định ở mức 0V. Hiệu tượng này gọi là rung phím. 

Mặc dù khoảng thời gian điện áp ở mức 0 trong giai đoạn rung phím là nhỏ nhưng cũng đủ đê vi điều khiên nhận được. Vì vậy khi ta xét nếu điện áp là 0 thì gọi hàm func() thì hàm này sẽ được gọi rât nhiều lần, là điều mà ta không mong muốn. Đê khắc phục hiện tượng rung phím, có 2 hướng giải quyết : dùng phần cứng và phần mềm. 

Về giải pháp phần cứng : thay vì mắc đơn giản như kit thí nghiệm này (xem lại sơ đô ), ta có thê dùng thêm tụ điện đê hạn chế việc thay đổi điện áp đột ngột, sơ đô nguyên lý như sau:

Page 52: Bai Giang Pic Rat Hay Va Day Du

Hình 4.2 : Chống rung bằng phần cứng

Ở sơ đô trên, khi không nhân là mức 1, khi nhân là mức 0. Phím nhân trên tích cực mức 0. Mạch ở trên còn gọi là mạch RC. 

Nếu nút nhân có 2 cực (3 chân), ta có thê chọn giải pháp dùng mạch RS flip flop, đây là mạch phần cứng chống rung tốt nhât, sơ đô nguyên lý như sau: 

Hình 4.3 : Chống rung bằng phần cứng (tt)

Về giải pháp phần mềm : Ta sẽ định kì đọc tín hiệu từ nút nhân, cho đến khi nào chúng trùng nhau n lần thì mới xử lý. Hình dưới đây minh hoạ trong trường hợp 2 lần là 0 thì mới xác nhận là phím được nhân và mới xử lý tác vụ mà ta mong muốn. 

Hình 4.4 : Chống rung bằng phần mềm

Page 53: Bai Giang Pic Rat Hay Va Day Du

Khoảng thời gian giữa 2 lần đọc là khoảng 10ms, ta sẽ hiện thực hàm đọc này và gọi nó trong timer. Giải thuật đơn giản đê xử lý chống rung có thê hiện thực như sau: Code:

previous_key = current_key; current_key = Port_key; If(previous_key == current_key)

effective_key = current_key;

Trong đó :previous_key : biến lưu giá trị phím trước đó. current_key : biến lưu giá trị phím hiện tại. Port_key : Port của vi điều khiên kết nối với phím. Ở đây chúng ta gọi hàm đọc ma trận phím đê trả về giá trị của phím được nhân.effective_key : giá trị phím hợp lệ (giá trị trong giai đoạn ổn định)Đê tăng tính chính xác, ta có thê dùng nhiều biến previous_key đê lưu lại các giá trị và so sánh nhiều lần. Đoạn code trên chỉ so sánh trùng nhau 2 lần.4.2 Kết nôi phân cứngSơ đô nguyên lý của phím trong kit này như sau :

Hình 4.5 : Sơ đô kết nối nút nhân

Phím nhân này tính cực mức 0, được kết nối khá đơn giản, nên ta sẽ dùng phần mềm đê chống rung. Ta sẽ dùng 3 biến đê so sánh 2 lần trùng nhau, 2 lần liên tiếp cách nhau 10ms. 

Trong trường hợp nhân đè 1 phím, ta sẽ dùng biến TimeOutForKeyPress đê xác định thời gian tích cực tiếp theo. Biến này sẽ quan trọng trong trường hợp ta viết 1 ứng dụng chẳng hạn như soạn thảo văn bản. Nếu không có biến này đê quản lý, nếu ta đè thì trong 1s có tới 100 lần tích cực. 4.3 Viết chương trìnhModule này có 2 hàm như sau : void initKey() : Khởi động các thông số ban đầu void getKey() : Hàm này được gọi trong timer0, dùng đê quét phím. void SubKeyProcess() : Hàm này hiện thực tác vụ bạn cần thực hiện khi nhân phím. Ở kit thí nghiệm này, các nút nhân được nối thành dạng ma trận và được nối với PORTC nên ta định nghĩa ở thêm ở đầu file Key.c :Code:

#define KEY_PORT PORTC

4.3.1 Hàm initkey()

Code:

void initKey() { KeyReg0 = 0x00;

Page 54: Bai Giang Pic Rat Hay Va Day Du

KeyReg1 = 0x00; KeyReg2 = 0x00; KeyReg3 = 0x00; }

Trong đó KeyReg0, KeyReg1, KeyReg2 dùng đê lưu 3 lần liên tiếp. Khi 3 biến này bằng nhau, biến KeyReg3 mới được cập nhật. Biến KeyReg3 là giá trị hợp lệ của phím nhân.4.3.2 Hàm getKey()Hàm này được chia làm 2 phần, phần đầu là đê chống rung phím dùng 2 lần so sánh trùng nhau. Phần thứ 2 xử lí khi 1 phím được đè, phải sau 1 khoảng thời gian TimeOutForKeyPress mới được tích cực.

Code:

void getKey(){ KeyReg2 = KeyReg1; KeyReg1 = KeyReg0; KeyReg0 = read_matrix_key();// Cho phep nut nhan nao duoc tich cuc. if ((KeyReg1 == KeyReg0) && (KeyReg1 == KeyReg2)) {

TimeOutForKeyPress --;if (TimeOutForKeyPress == 0) {

KeyReg3 = 0x00; }

if (KeyReg2 != KeyReg3) { KeyReg3 = KeyReg2; if (FlagFirstTimeKeyPress == 1)// Day la lan dau

phim duoc nhan. {

TimeOutForKeyPress = 100; SubKeyProcess(); FlagFirstTimeKeyPress = 0;

} else {

if (KeyReg2 == 0x00) FlagFirstTimeKeyPress = 1;

else {

TimeOutForKeyPress = 100; SubKeyProcess();

} }

} }

}

4.4. Code mâu

Download code mâu tại đây

Bài 8 : LCD 16x2 và bàn phím điện thoại

5.1 Chức năng các chân của LCD

Page 55: Bai Giang Pic Rat Hay Va Day Du

Hình 5.1 : LCD 16x2

LCD thường sử dụng 14 chân, chế độ 16 chân khi cần điều khiên đèn nền. Chức năng của các chân như sau:

Page 56: Bai Giang Pic Rat Hay Va Day Du

5.2 Kết nôi màn hình LCD

Page 57: Bai Giang Pic Rat Hay Va Day Du

Hình 5.2 : Kết nối màn hình LCD

Hình trên mô tả kết nối LCD với chế độ 16 chân, 2 chân K và A dùng đê kết nối với đèn nền.

5.3 Các vùng nhớ của LCD5.3.1 Display Data Ram (DDRAM)Lưu trữ mã ký tự hiên thị ra màn hình. Mã này giống với mã ASCII. Có tât cả 80 ô nhớ DDRAM. Vùng hiên thị tương ứng với cửa sổ gôm 16 ô nhớ hàng đầu tiên và 16 ô nhớ hàng thứ hai. Chúng ta có thê tạo hiệu ứng dịch chữ bằng cách sử dụng lệnh dịch , khi đó cửa sổ hiên thị sẽ dịch đem lại hiệu ứng dịch chữ.

Hình 5.3 : Vùng nhớ DDRAM5.3.2 Character Generator Ram (CGRAM)Lưu trữ tám mâu ký tự do người dùng định nghĩa. Tám mâu ký tự này tương ứng với các mã ký tự D7-D0 = 0000*D2D1D0 (* mang giá trị tùy định 0 hay 1).

Page 58: Bai Giang Pic Rat Hay Va Day Du

Hình 5.4 : Vùng nhớ CGRAM5.3.3 Bộ nhớ CGROMBộ nhớ dùng đê lưu trữ các kí tự hiên thị trên LCD. Các giá trị lưu trong bộ nhớ này như sau: 

Page 59: Bai Giang Pic Rat Hay Va Day Du

Hình 5.5 : Vùng nhớ CGROMChúng ta muốn hiên thị chữ “CE” ở giữa hàng đầu tiên, giả sử cửa sổ hiên thị đang bắt đầu từ vị trí đầu tiên (hàng thứ nhât hiên thị dữ liệu của ô nhớ từ 0x00 đến 0x0f, hàng thứ hai hiên thị dữ liệu của ô nhớ từ 0x40 đến 0x4f, đây là vị trí home). Giá trị của ô nhớ 0x07 là 0x43 (ký tự C), của ô nhớ 0x08 là 0x45 (ký tự E).

Chúng ta muốn hiên thị chữ “®” ở giữ hàng thứ hai, giả sử cử sổ hiên thị đang ở vị trí home. Trong bảng mâu ký tự chúng ta thây không có mâu “®”. Lúc này chúng ta phải định nghĩa mâu “®” 5x8 điêm, gôm có 8 byte, sau đó lưu vào vị trí của mâu ký tự CGRAM thứ nhât. Lúc này giá trị của ô nhớ 0x47 là 0x00 hoặc 0x08 (vị trí của mâu ký tự CGRAM thứ nhât “®”).5.4 Các lệnh cơ bản của LCDĐê truyền lệnh cho LCD thì chân RS = 0, khi đó các tín hiện trên D0-D7 được xem là lệnh. Ý nghĩa của các lệnh điều khiên LCD như sau:

Page 60: Bai Giang Pic Rat Hay Va Day Du

I/D1 = Increment (by 1) 0 = Decrement (by 1)RL1 = Shift right0 = Shift leftS1 = Display shift on 0 = Display shift offDL1 = 8-bit interface0 = 4-bit interfaceD1 = Display on 0 = Display offN1 = Display in two lines0 = Display in one lineU1 = Cursor on 0 = Cursor offF

Page 61: Bai Giang Pic Rat Hay Va Day Du

1 = Character format 5x10 dots0 = Character format 5x7 dotsB1 = Cursor blink on 0 = Cursor blink offD/C

1 = Display shift0 = Cursor shift

5.5 Kết nôi LCD với vi điêu khiểnLCD có 2 chế độ 8 bit và 4 bit. Ở chế độ 8 bit, ta dùng toàn bộ 8 chân D0-D7 đê giao tiếp. Ở chế độ 4 bit, ta chỉ dùng 4 bit cao D4-D7 đê giao tiếp với LCD. Dữ liệu gửi cho LCD ở chế độ này bao gôm 4bit cao gửi trước, sau đó sẽ đến 4bit thâp. Sơ đô kết nối ở 2 chế độ như sau:

Hình 5.6 : Kết nối LCD với vi điều khiên

Nếu muốn tiết kiệm chân, R/W có thê nối xuống GND. Ở chế độ 4bit thì 4 bit thâp của LCD có thê nối xuống GND.5.6 Khởi tạo LCDQuá trình khởi tạo LCD ở chế độ 8 bit như sau:

Page 62: Bai Giang Pic Rat Hay Va Day Du

Hình 5.7 : Khới tạo LCD 8 bit

Quá trình khởi tạo ở chế độ 4 bit như sau:

Page 63: Bai Giang Pic Rat Hay Va Day Du

Hình 5.8 : Khởi tạo LCD 4 bit5.7 Kết nôi phân cứngLCD được kết nối với Port B của vi điều khiên PIC như sau:Quote:

LED_BACKLIGHT = PortB.0PIN_RS : PortB.1PIN_RW : PortB.2PIN_EN : PortB.3D4 : PortB.4D5 : PortB.5D6 : PortB.6

Page 64: Bai Giang Pic Rat Hay Va Day Du

D7 : PortB.7

5.8 Viết chương trình & 5.9 Các hàm cơ bảnĐê quá trình điều khiên LCD hiệu quả, ta định nghĩa 1 số hàm cơ bản như sau:

Hàm delay: trung bình PIC thực hiện 5 lệnh mât 1us với thạch anh 20Mhz.

Code:

void lcd_delay(int time) {

while(--time);}

Hàm ghi dữ liệu ra LCD:

Code:

//Ghi 4 bitvoid lcd_write_4bits(unsigned char dat) {

RW(WRITE); //kéo chân RW xuống 0EN(SET); //set chân Enable lên 1LCD_DATA_OUT(dat & 0xF0); //Gửi data ralcd_delay(10);EN(CLR); //kéo chân Enable xuống 0lcd_delay(10);

}//Ghi 1 byte : ghi 4 bit 2 lầnvoid lcd_write_cmd(unsigned char cmd){

lcd_wait_busy();

RS(CMD);lcd_write_4bits(cmd);lcd_write_4bits(cmd << 4);

}

Một số macro trong file lcd.h, ví dụ như:

Code:

#define RS(x) ( (x) ? ( LCD_PORT |= 0x02 ) : ( LCD_PORT &= 0xFD ) )//Nếu x = 1 thì thực hiện lệnh LCD_PORT |=0x02, x=0 thì thực hiện LCD_PORT &=0xFD.

5.10 Khởi tạo LCD chế độ 4 bitCode:

void init_lcd() {lcd_delay(15000); //1RS(CMD); //2lcd_write_4bits(0x03 << 4); //3lcd_delay(4100); //4lcd_write_4bits(0x03 << 4); //5lcd_delay(100); //6lcd_write_4bits(0x03 << 4); //7lcd_write_4bits(0x02 << 4); //8

Page 65: Bai Giang Pic Rat Hay Va Day Du

lcd_write_cmd(0x28) ; //9lcd_write_cmd(0x0C); //10lcd_write_cmd(0x06); //11

}

Ý nghĩa các lệnh trên như sau:

Lệnh 1 : gọi hàm lcd_delay(15000) đê delay 15ms. Lệnh 2 : kéo chân RS (nối với LCD_PORT tại bit 1) xuống 0. Lệnh này được định nghĩa là 1

macro trong file lcd.h:#define RS(x) ( (x) ? ( LCD_PORT |= 0x02 ) : ( LCD_PORT &= 0xFD ) )

CMD được define là 0 nên lệnh RS(CMD) sẽ có điều kiện (x) là false và sẽ thực hiện phần thứ 2 của lệnh trên : LCD_PORT & 0xFD (kéo bit 1 xuống 0 : 1111 1101).

Lệnh 3 : thực hiện trạng thái đầu tiên sau khi chờ 15ms, ghi D7 D6 D5 D4 = 0011. Các chân này được nối với 4 bit cao của vi điều khiên nên ta phải dịch trái giá trị 0x03 4 bit.

Lệnh 4 : delay khoảng 41ms. Lệnh 5,6,7,8 : Thực hiện các trạng thái 2,3 và 4. Sau lệnh 7 thì LCD đã chuyên sang chế độ 4

bit, và đê gửi 1 byte, ta sẽ gửi 2 lần 4 bit cao trước rôi tới 4 bit thâp. Lệnh 9 : gọi hàm lcd_write_cmd đê ghi 4 bit 2 lần, giá trị 0x28 tương ứng với N = 1 (hiên thị

trên 2 hàng của LCD) và B = 0 (font định dạng 5x7 điêm). Lệnh 10 : thực hiện lệnh display on (xem thêm trong bảng lệnh), D = 1. Lệnh 11 : thực hiện lệnh entry set mode, 0x06 tương ứng với chế độ dịch phải tăng dần.

5.11 Xoá màn hìnhHàm này chỉ đơn giản là gửi lệnh clear màn hình lcd (xem thêm trong bảng lệnh của LCD).Code:

void lcd_clear() {

lcd_write_cmd(0x01);lcd_goto_xy(0, 0);

}

5.12 Thiết lập vị trí con trỏHàm này thiết lập vị trí bắt đầu xuât dữ liệu trên màn hình LCD 2 hàng 16 cột. Đê hiện thực hàm này ta phải tính được địa chỉ tương ứng với toạ độ (row,col) và dùng lệnh SET DDRAM ADDRESS (bit 7 của lệnh này bằng 1).Code:

char lcd_goto_xy(unsigned char row, unsigned char col) {unsigned char addr = 0x00;if(col >= 20 || row >= 4)

return FALSE;if(row < 2) {

addr = (row * 0x40) + col;addr = 0x80 | (addr & 0x7F);

}else {

addr = (row * 0x40) + col;addr = 0x94 | (addr & 0x7F);

}lcd_write_cmd(addr);

current_row = row;current_col = col;return TRUE;

}

5.13 In kí tự ra màn hìnhHàm này nhận thông số là 1 kí tự và hiên thị kí tự đó ra màn hình LCD. Việc hiện thực hàm này khá đơn giản, ta chỉ cần kéo chân RS xuống 0 là LCD sẽ hiêu các bit D7-D4 là dữ liệu.Code:

Page 66: Bai Giang Pic Rat Hay Va Day Du

void lcd_print_char(unsigned char dat) {

lcd_wait_busy();//find next position

if(current_row == 0 && current_col == 16)lcd_goto_xy(1,0);

if(current_row == 1 && current_col ==16)lcd_goto_xy(0,0);

RS(DAT); //RS = 0lcd_write_4bits(dat);lcd_write_4bits(dat << 4);

current_col ++; //update new position}

Từ những hàm cơ bản này, bạn có thê hiện thực thêm các hàm đê xuât 1 string hay 1 giá trị số ra màn hình LCD. Code chi tiết có thê xem thêm ở file đính kèm.5.14 Thiết lập bàn phím điện thoạiTóm tắt : bàn phím 4x4 có đánh các kí tự số (0-9) và chữ (A,B,C,D,*,#) sẽ là các phím chức năng mô phỏng theo bàn phím điện thoại. Các trạng thái cũng như thông tin sẽ được hiên thị trên màn hình LCD. Đê làm được bài này các bạn cần có những hàm về quét ma trận phím (trong thư mục button_matrix) cũng như xuât ra LCD (trong thư mục lcd).

Trước hết bạn cần phải biết qua bài quét ma trận phím. Trong Button.c chúng ta có hàm button_process(void); Hàm này được gọi định kì trong timer đê kiêm tra xem có nút nào được nhân không.Hàm read_matrix_key(void) khi không có nút nào được nhân, nó sẽ trả về giá trị 0. Khi có nút nhân nó sẽ trả về giá trị từ 1-16 tùy theo vị trí của nút nhân. Việc kiêm tra này được thực hiện nhiều lần và chúng ta sẽ chỉ xử lí nó khi có ít nhât 3 lần đọc giá trị giống nhau (theo nguyên lí chống rung, đọc thêm bài chống rung cho phím).

Bài thứ 2 cần biết là bài về xuât lcd. Trong lcd.c đã hỗ trợ cho bạn sẵn các hàm đê ghi lên lcd (Tham khảo thêm trong lcd.h).

Chúng ta bắt đầu bằng việc tạo một project mới với những thiết lập phù hợp. copy thư mục button_matrix, lcd, timer, interrupt vào nơi chứa chương trình đê hoàn chỉnh project mới. Thêm những file .h trong các thư mục này vào main.c. Tạo thư mục Phone và chứa các file phone.c, phone.h . add vào project. Các sự kiện và trạng thái của chiếc điện thoại của chúng ta sẽ được xử lí chính ở trong file phone.c này. Include file .h của button_matrix và lcd.

Định hình: trước hết chúng ta định hình lại vị trí và chức năng của từng nút. Vì đê thực hiện được chức năng nhắn tin cũng như gọi điện nên mỗi nút từ 0-9 đề có thêm các chức năng riêng. Ta khai báo một mảng lưu giữ những giá trị mà ta muốn nút nhân có thê thực hiện.Code:

unsigned char key[16][5] = { '0',' ',0,0,0,'1','.',',',0,0,'2','a','b','c',0,'3','d','e','f',0,'4','g','h','i',0,'5','j','k','l',0,'6','m','n','o',0,'7','p','q','r','s','8','t','u','v',0,'9','w','x','y','z','*',0,0,0,0,'#',0,0,0,0,'A',0,0,0,0,'B',0,0,0,0,'C',0,0,0,0,'D',0,0,0,0};

Page 67: Bai Giang Pic Rat Hay Va Day Du

Ở đây có các nút có nhiều kí tự (7-p-q-r-s) cũng có nút có ít kí tự (1-.) nên đê thuận tiện ta tạo thêm một mảng chứa giá trị là số kí tự được sử dụng của nút đó :Code:

unsigned char limit_key[16]={2,3,4,4,4,4,4,5,4,5,1,1,1,1,1,1};

Bây giờ coi lại trong button.c có hàm quét ma trận phím. Tuy nhiên, giá trị trả về của hàm này là vị trí của các nút trên bàn phím (vd:1=1,2=2,3=3,A=4…). Ta sẽ cần phải chuyên đổi sang một hệ khác đê thuận tiện trong việc lập trình thông qua một mảng sau:Code:

unsigned char convert_key[16]={ 1,2,3,12,4,5,6,13,7,8,9,14,10,0,11,15};

Chương trình chính của chúng ta là hàm Phone() được gọi liện tục trong hàm main(). Hàm này đầu tiên sẽ xét biến ActiveKey xem có nút nhân nào được nhân không . Khi có nút nhân thì sẽ có một chuyên đổi nhỏ Code:

KeyPress = convert_key[ActiveKey-1];

Và biến KeyPress này chính là giá trị chúng ta xử lí chính.

Biến PhoneStatus chứa giá trị của của các trạng thái của điện thoại. Các trạng thái chính là đợi (WAIT_STATUS), gọi điện (ENTERING_NUMBER_STATUS, CALLING_STATUS,ENDCALL_STATUS), nhắn tin (MESS_STATUS, TYPING_MESS_STATUS, SENDING_STATUS, ENDSEND_STATUS). Với mỗi trạng thái ta xử lí nút C là quay lại, D là xóa kí tự, A là enter… tùy theo quy định mỗi người.

Tiếp theo chúng ta xử lí nút nhân tại mỗi trạng thái. Tại trạng thái đợi, nếu nhập vào là số thì sẽ chỉ hiện số key[KeyPress][0]. Còn nếu ở trong chế độ nhắn tin thì nếu như phím được nhân lặp lại trong khoảng thời gian timeout thì coi như sẽ chuyên kí tự ngay tại nút đó:Code:

KeyMessIndex = (KeyMessIndex +1)%(limit_key[KeyPress]);lcd_putChar(key[KeyPress][KeyMessIndex]);

, nếu không thì in kí tự mới.:Code:

KeyMessIndex = 1;lcd_putChar(key[KeyPress][KeyMessIndex]);

Download code mâu

Bài 9 : Quét led 7 đoạn và led ma trận

6.1 Điêu khiển led 7 đoạn và led ma trận.6.1.1 Cấu tạo Led 7 đoạnLED 7 đoạn gôm có 7 đoạn được đánh dâu: a, b, c, d, e, f, g và một điêm dp. Mỗi đoạn là một led, kết hợp tắt/sáng của các led này đê hiên thị số mà chúng ta hiêu được.

Hình 6 1 Led 7 đoạnLED 7 đoạn có hai loại là Common Anode và Common Cathode, tương ứng các LED nối chung Anode hay nối chung Cathode. Mạch thí nghiệm BKIT PIC sử dụng loại Common Anode.

Page 68: Bai Giang Pic Rat Hay Va Day Du

Hình 6.1 : Sơ đô nguyên lý led 7 đoạn6.1.2 Cấu tạo led ma trậnLED ma trận 8x8 hai màu được bố trí thành 8 hàng và 8 cột.

Hình 6 3. Led ma trậnMỗi điêm có hai LED tương ứng với hai màu. Các LED trên cùng một hàng nối chung Anode, các LED cùng màu trên cùng một cột nối chung Cathode.

Hình 6 4 Sơ đô nguyên lý led ma trận6.1.3 Nguyên lý quét LEDĐê hiện thị 1 led 7 đoạn, ta cần 8 đường tín hiệu đê gửi dữ liệu cho nó. Như vậy, với 8 led 7 đoạn, theo kết nối bình thường, ta cần tổng cộng 64 đường tín hiệu đê thắp sáng 8 led cùng lúc. Việc này rât tốn tài nguyên về phần cứng. Đê khắc phục, người ta dùng kĩ thuật quét led. Các đường dữ liệu của các led sẽ được nối với nhau.

Page 69: Bai Giang Pic Rat Hay Va Day Du

Hình 6 5 Kết nối khi quét led 7 đoạnVới kĩ thuật quét led này, tại 1 thời điêm, chỉ có 1 led sáng. Tại thời điêm t1 chỉ có led 1 sáng, tại thời điêm t2 = t1 + t0 chỉ có led 2 sáng, khi t0 rât nhỏ, mắt người không thê nhận biết được độ nhâp nháy giữa 2 lần luân chuyên, và sẽ có cảm giác là 2 đèn sáng cùng lúc. Thường thì t0 này phải nhỏ hơn 1/24 giây, tức là trong một giây sẽ có nhiều hơn 24 lần luân chuyên giữa các led.Bảng mô tả quá trình quét Led 7 đoạn:

Tương tự đối với led ma trận, ta dùng 16 đường tín hiệu đê điều khiên hai màu led và 8 đường tín hiệu đê tích cực dòng (ROW). Tại mỗi thời điêm chỉ có một dòng led ma trận được hiên thị dữ liệu.

Page 70: Bai Giang Pic Rat Hay Va Day Du

Hình 6 6 Nguyên lý quét led ma trận6.2 Sơ đồ kết nôi mạch

Hình 6-7 Sơ đô kết nối led 7 đoạn và led ma trậnMục đích của bài này là đê mọi người làm quen với led 7 đoạn và led ma trận cho nên các led 7 đoạn và led ma trận được kết nối theo kiếu song song, các chân dữ liệu và điều khiên led được gắn trực tiếp với chân vi điều khiên PIC, vì vậy chương trình sẽ đơn giản và dễ thực hiện hơn.

6.3 Xây dựng chương trình6.3.1 Ý tưởng hiện thựcĐê có thê hiện thực giải thuật quét led chúng ta cần sử dụng tới bộ đinh thời(timer) và ngắt quãng đê thiết lập thời gian quét. Ví dụ chúng ta quét 1 led với tần số 50Hz(nghĩa là led sáng 50 lần/giây) như vậy ta cần câu hình cho timer là cứ sau 1000ms/50 = 20ms thì ngắt 1 lần và trong hàm xử lý ngắt ta sẽ đưa dữ liệu ra cho led. Nếu số led nhiều hơn thì ta chỉ cần lây tần số chuẩn cho mỗi led nhân với

Page 71: Bai Giang Pic Rat Hay Va Day Du

số lượng led. Ví dụ nếu quét cùng luc 8 led 7 đoạn với tân số mỗi led là 50Hz thì tần số ngắt của timer là 8*50 = 400Hz.6.3.2 Các hàm phục vụ quét led2.6.3.1 Hàm quét led 7 đoạnCode:

void display_led7(void){

PORTE = 0;PORTD = led7_buffer[index_led7];PORTE = 1 << index_led7;index_led7 = (index_led7 + 1) % 3;

}

Theo sơ đô nguyên lý PORTD là port đưa dữ liệu ra led 7 đoạn và PORTE là port chọn led(ở đây chúng ta có 3 led 7 đoạn).Trước mỗi lần xuât led, ta cần phải tắt tât cả các led đê tránh trường hợp dữ liệu cũ được đưa vào led được chọn tiếp theo,hay ngược lại dữ liệu mới được đưa vào led trước đó.2.6.3.2 Hàm quét led ma trậnCode:

void display_ledmatrix(void){

PORTA = 0;PORTB = green_buffer[index_matrix];PORTC = red_buffer[index_matrix];PORTA = 1 << index_matrix;index_matrix = (index_matrix + 1) % 8;

}

Theo sơ đô nguyên lý, PORTA là port lựa chọn led, PORTB và PORTC tương ứng là các dữ liệu xanh và đỏ của led ma trận, cách quét vân giống với việc quét led 7 đoạn.Đối với việc quét led ta nên tạo ra những mảng buffer đê tiện cho việc xuât dữ liệu và cập nhập chúng, cùng với việc hiện thực 1 số hầm cập nhập buffer như update_led7_buffer(), update_green_bugffer(), update_red_buffer() chương trình của chúng ta trở nên thân thiện, trong sáng, đơn giản hơn rât nhiều và phù hợp với việc phát triên lên thành những bài khó hơn như chạy chữ hay các hiệu ứng led river.

Bài 10 : Giao tiếp nôi tiếp SPI

7.1 Giới thiệu vê SPISPI (Serial Peripheral Interface) là một dạng giao thức truyền nối tiếp được dùng đê giao tiếp với các thiết bị ngoại vi(EEPROM,SDcard…) và các vi điều khiên khác.7.2 Chế độ SPI trong vi điêu khiển PICGiao tiếp SPI được hiện thực qua 4 chân của vi điều khiên:SDI( Serial Data In ): Tín hiệu nối tiếp được đưa vào vi điều khiênSDO( Serial Data Out): Tín hiệu nối tiếp từ vi điều khiên đi raCLK(Clock): xung clock tạo ra bới masterSS(Slave Select): tích cực mức thâp, dùng đê chọn slave đê truyền dữ liệu

Page 72: Bai Giang Pic Rat Hay Va Day Du

Hình 7-1 Sơ đô khối của SPI

7.2.1 Các thanh ghi điều khiển SPIChế độ SPI được điều khiên bằng 4 thanh ghi sau• MSSP Control Register 1 (SSPCON1)• MSSP Status Register (SSPSTAT)• Serial Receive/Transmit Buffer Register(SSPBUF)• MSSP Shift Register(SSPSR) – thanh ghi này không được truy xuât bởi người dùngHai thanh ghi SSPCON1 và SSPSTAT là hai thanh ghi điều khiên, còn than ghi SSPSR là thanh ghi dùng đê dịch dữ liệu ra/vào vi điều khiên, SSPBUF là thanh ghi dùng đê đọc dữ liệu từ ngoài vào hoặc ghi dữ liệu đê truyền ra ngoài. Ở chế độ nhận, 2 thanh SSPBUF và SSPSR là 1 bộ buffer đôi, khi dữ liệu từ ngoài truyền vào được lưu đầy đủ trong SSPSR(8 bits) thì dữ liệu này được truyền tới thanh ghi SSPBUF đê người dùng lây ra. Còn ở chế độ truyền thì khi dữ liệu được ghi vào thanh ghi SSPBUF thì cùng lúc dữ liệu đó cũng được ghi vào thanh ghi SSPSR đê dịch ra ngoài.

2.7.2.1 Thanh ghi SSPSTAT

Bit 7:SMP Sample bitSPI Master mode

Page 73: Bai Giang Pic Rat Hay Va Day Du

1 = dữ liệu vào sẽ được lây ở cuối chu kỳ xung clock0 = dữ liệu vào sẽ được lây ở giữa chu kỳ cung clockSPI Slave modeSMP phải được gán bằng 0Bit 6:CKE SPI Clock Select bitBit 0:BF BuFffer Full Status bit(dành cho quá trình nhận)1 = quá trình nhận hoàn thành, SSPBUF đầy0 = quá trình nhận đang thực hiện, SSPBUF trống2.7.2.1 Thanh ghi SSPCON1

Bit 7:WCOL Write Collision Detect bit(chỉ dùng ở chế độ truyền tín hiệu)1 = thanh ghi SSPBUF được ghi đè dữ liệu trong khi dữ liệu cũ truyền chưa hết0 = không có đụng độBit 6:SSPOV Receive Overflow Indicator bit(dùng ở chế độ nhân tín hiệu)1 = có dữ liệu mới nhận về ghi đè lên thanh ghi SSPBUF trong khi dữ liệu trướcđó chưa được đọc.0 = dữ liệu không bị ghi đèBit 5:SSPEN Synchronous Serial Port Enable bit1 = bật chế độ SPI và các chân SDI, SDO, SCK, SS được câu hình tương ứng.0 = tắt chế độ SPIBit 4:CKP Clock Polarity Select bit1 = thiết lập trạng thái rảnh khi xung clock ở mức cao0 = thiết lập trạng thái rảnh khi xung clock ở mức thâpBit 3-0:SSPM3:SSPM0 Synchronous Serial Port Mode Select bit0101 = chế độ slave, clock = chân SCK, tắt chức năng của chân SS0100 = chế độ slave, clock = chân SCK, bật chức năng của chân SS0011 = chế độ master, clock = tần số của timer 2 /20010 = chế độ master, clock = Fosc / 640001 = chế độ master, clock = Fosc / 160000 = chế độ master, clock = Fosc / 47.2.2 Cấu hình SPIĐê câu hình chế độ SPI cho vi điều khiên PIC ta sử dụng các bit SSPCON1<5:0> và SSPSTAT<7:6>, khi câu hình các bit này SPI của PIC sẽ được câu hình ở chế độ master hoặc slave, cung clock cho SPI, và thiết lập việc nhận dữ liệu xảy ra ở cạnh lên hoặc xuống của xung clock. Thanh ghi SSPSR có chức năng dịch dữ liệu ra và vào vi điều khiên và luôn là bit trọng số cao trước. Ở trong chế độ truyền, thanh ghi SSPBUF sẽ chờ cho đến khi thanh ghi SSPSR sẵn sàng nhận dữ liệu rôi mới ghi dữ liệu lên thanh ghiSSPSR, nếu có hành động ghi dữ liệu vào thanh ghi SSPBUF trong lúc dữ liệu truyền chưa xong thì hành động đó được bỏ qua và bit WCOL được bật lên báo hiệu có xảy ra đụng đô. Ở trong chế độ nhận, sau khi SSPSR nhận đủ 8 bit dữ liệu sẽ được chuyên đến thanh ghi SSPBUF và bit BF được bật lên đê báo hiệu, nếu dữ liệu trước đó được lưu trong thanh ghi SSPBUF chưa được đọc mà lại có thêm dữ liệu mới thì dữ liệu mới sẽ ghi đè lên dữ liệu cũ và bit SSPOV được bật lên.

Page 74: Bai Giang Pic Rat Hay Va Day Du

Hình 7-2 Kết nối SPI master/slave

Hàm câu hình chế độ SPI master cho vi điều khiên PIC

Code:

void init_spi_master(void){SSPSTATbits.CKE = 1; // when CKP = 0,CKE = 0

transmit data on fallingclock,CKE = 1 transmit data on rising clock

// when CKP = 1,CKE = 1 transmit data on rising

clock,CKE = 1 transmit dataon falling clockSSPCON1bits.CKP = 1; // CKP=0 data first,second is

clock; CKP=1 clock first,second is dataSSPCON1bits.SSPEN = 1; // enable SPI masterSSPCON1bits.SSPM0 = 0; //SSPCON1bits.SSPM1 = 0; //SSPCON1bits.SSPM2 = 0; //SSPCON1bits.SSPM3 = 0; // preacaler 1:4

}

__________________

Bài 11 : Điêu khiển led 7 đoạn và mâ trặn bằng SPI

8.1 Kết nôi phân cứng

Page 75: Bai Giang Pic Rat Hay Va Day Du

Hình 8-1 Sơ đô kết nối led 7 và led ma trận

Ở bài này chúng ta sẽ sử dụng mạch rời số1, mạch bao gôm 8 led 7 đoạn và 1 led ma trận được sử dụng giao tiếp với vi điều khiên thông qua giao thức SPI. Trong mạch này vi điều khiên PIC đóng vai trò là master và các IC TPIC595, 74HC595 đóng vai trò là slave với chức năng dịch bit, ngoài chức năng dịch bit IC TPIC595 còn có tác dụng đệm và đảo tín hiệu đầu vào, IC này được sử dụng đê phù hợp với nguyên lý hoạt động của led 7 đoạn và led ma trận. Cách thức hoạt động của mạch là vi điều khiên sẽ dịch dữ liệu cần xuât ra ngoài đến các con IC dịch, và khi nào dịch đủ dữ liệu cần xuât ra ngoài vi điều khiên sẽ khóa dữ liệu lại bằng cách tạo một xung từ thâp lên cao trên chân LATCH của các IC dịch này, lúc này các IC dịch sẽ lây dữ liệu được cât trong bộ đệm trong quá trình dịch dữ liệu của vi điều khiên và xuât ra ngoài.8.2 Xây dựng chương trìnhNgoài hàm câu hình chế độ SPI cho PIC nhu ở bài trên, chúng ta cần hiện thực thêm hàm tạo tín hiệu LATCH, hàm quét led 7 đoạn và led ma trận, hàm xóa led 7 đoạn và led ma trận. Ngoài ra chúng ta cũng cần bổ sung thêm các hàm tiện ích trong việc xuât led 7 đoạn và led ma trận, chi tiết các bạn có thê tham khảo trong thư viện source code.8.2.1 Hàm tạo tín hiệu LATCHCode:

Page 76: Bai Giang Pic Rat Hay Va Day Du

void latch_spi(void){

unsigned char j;LATCH = 0; // create a rising clock to push data into

output registerfor (j = 0; j <10;j++);LATCH = 1;for (j = 0; j< 10; j++);

}

8.2.2 Hàm xuất led 7 đoạn và led ma trậnVới cùng giải thuật quét led như ở bài trên chỉ khác là trong chương trình ngắt của timer ta gọi hàm xuât trực tiếp dữ liệu ra các port của vi điều khiên thì ra gọi hàm dịch dữ liệu từ vi điều khiên ra các IC ngoại vi.Chi tiết hàm dịch như sau:Code:

void scan_led7_matrix(void){

SSPBUF = 0x00; // select column for led matrixwhile (!SSPSTATbits.BF);SSPBUF = 0x00; // green matrix's datawhile (!SSPSTATbits.BF);SSPBUF = 0x00; // red matrix's datawhile (!SSPSTATbits.BF);SSPBUF = column[index]; // select column for led 7

segmentwhile (!SSPSTATbits.BF);SSPBUF = code[buffer[index]]; // led7's datawhile (!SSPSTATbits.BF);latch_spi();index = (index+1) % 8;

}

8.2.3 Hàm xóa dữ liệu trên led 7 đoạn và led ma trậnCode:

void clear_spi(void){

unsigned char i;for (i =0; i< 5; i++){

SSPBUF = 0xff;while (!SSPSTATbits.BF);

}latch_spi();

}

__________________

Bài 12 : Quét 2 led ma trận bằng SPI

9.1 Kết nôi phân cứng

Page 77: Bai Giang Pic Rat Hay Va Day Du

Hình 9 1 Sơ đô kết nối 2 led ma trậnỞ trong bài này chúng ta sử dụng mạch rời có 2 led ma trận. Trong sơ đô này đường dữ liệu(16 bits) được truyền theo giao thức SPI, dịch từng bit dữ liệu ra cho con IC TPIC595; còn đường đê chọn hàng của led ma trận(8 bits) được kết nối trực tiếp với PORTD của vi điều khiên PIC,nên cơ chế truyền ở đây là truyền theo kiêu song song.9.2 Xây dựng chương trìnhTương tự đối với những bài quét led trên, chỉ khác ở đây chúng ta kết hợp cả phương pháp truyền song song và phương pháp truyền nối tiếp SPI.Với mạch rời được thiết kế 2 led ma trận sẽ tạo thêm điều kiện đê thực hiện những hiệu ứng chạy chữ đa dạng đẹp mắt, như những bảng quang báo hay thây ở thực tế.Code:

void scan_2_led_matrix(void){

PORTD = 0;SSPBUF = green_buffer[index]; // high byte green

colorwhile (!SSPSTATbits.BF);SSPBUF = green_buffer[MAX + index]; // low byte green

colorwhile (!SSPSTATbits.BF);SSPBUF = red_buffer[index]; // low byte red colorwhile (!SSPSTATbits.BF);SSPBUF = red_buffer[MAX + index]; // high byte red colorwhile (!SSPSTATbits.BF);latch_spi();

PORTD = 1 << index;index = (index+1) % 8;

}

Trong thư viện source code, chúng tôi co demo mâu hiệu ứng chữ chạy với hai màu xanh và đỏ, các bạn có thê tham khảo trong tài liệu đính kèm.9.3 Code mâu

Page 78: Bai Giang Pic Rat Hay Va Day Du

Bài 13 : Giao tiếp nôi tiếp I2C và DS1307

Mục đích:Tìm hiêu chuẩn giao tiếp I2C và module I2C của PIC18F.Tìm hiêu IC thời gian thực DS1307.Yêu cầu:Viết chương trình hiên thị thông tin ngày giờ lên LCD.10.1 Giới thiệu I2CI2C là 1 chuẩn truyền nối tiếp theo mô hình Master – Slave. Một Master có thê giao tiếp với nhiều Slave. Muốn giao tiếp với slave nào, master phải gửi đúng địa chỉ đê tích cực slave đó rôi mới được phép ghi hoặc đọc dữ liệu từ slave.

Hình 10.1 : I2C interface

Bus I2C gôm 2 dây tín hiệu SCL (Serial Clock Line) và SDA (Serial Data Line) đều được kéo lên nguôn. Dữ liệu được truyền từng bit ở SDA theo từng clock của SCL.

Hình 10.2 : I2C Protocol

Hình 11.2 là giao thức I2C. Trước khi truyền dữ liệu, ta cần khởi động I2C bằng cách kéo lần lượt SDA và SCL xuống mức thâp. Sau đó 8 bit dữ liệu sẽ được ra tuần tự theo từng cạnh xuống ở chân SCL. Clock thứ 9 sẽ dành cho bit ACK. Bit ACK này có thê là do master gửi xuống hoặc do slave gửi về. Khi kết thúc giao tiếp I2C, ta phải stop nó bằng cách kéo 2 chân SCL và SDA lên mức cao.10.2 I2C trong PIC18F4520Module I2C trong PIC18F4520 hỗ trợ mode master và cả slave (7bit địa chỉ và 10bit địa chỉ). Trong tài liệu này chúng tôi chỉ giới thiệu chính mode master của PIC18F4520 đê giao tiếp với IC real time clock DS1307. File i2c.h định nghĩa 1 số hằng số và 4 hàm cơ bản của giao tiếp I2C.Code:

Page 79: Bai Giang Pic Rat Hay Va Day Du

#ifndef __I2C_H#define __I2C_H

/* PIC18 I2C peripheral library header */

/* SSPCON1 REGISTER */#define SSPENB 0x20 // Enable serial I2C port #define SLAVE_7 6 // I2C Slave 7bit mode#define SLAVE_10 7 // I2C Slave 10bit mode#define MASTER 8 // I2C Master mode

/*I2C interface*/void i2c_init(unsigned char sync_mode,unsigned char slew, unsigned char baudrate ); //open I2C portvoid i2c_start(); //start conditionvoid i2c_stop(); //stop conditionvoid i2c_write_byte(unsigned char abyte);unsigned char i2c_read_byte(unsigned char ACK);#endif

10.2.1 Hàm i2c_initĐầu tiên ta phải thiết lập chiều input cho 2 chân SCL và SDA bằng cách thiết lập 2 bit tương ứng trong thanh ghi TRISC là 1.PIC18F4520 sẽ đóng vai trò là master giữ clock, nội dung trong thanh ghi SSPADD sẽ được dùng cho bộ sinh clock. Tần số cho giao tiếp I2C sẽ được tính theo công thức sau đâyCode:

f = Fosc/4*(SSPADD + 1)

Ta sẽ chọn tần số cho SCL là 100kHz và phải nạp vào thanh ghi này giá trị 49 (0x31) cho thạnh anh 20MHz.Tiếp theo đó là chọn mode master cho PIC18F4520, thiết lập SSPM3:SSPM0 = 1000 và enable bit SSPEN trong thanh ghi SSPCON1.Code:

void i2c_init(unsigned char sync_mode,unsigned char baudrate ){SSPSTAT &= 0x3F; // power on state SSPCON1 = 0x00; // power on stateSSPCON2 = 0x00; // power on state SSPCON1 |= sync_mode; // select serial mode DDRCbits.RC3 = 1; //Set SCL to input DDRCbits.RC4 = 1; //Set SDA to input

SSPADD = baudrate;SSPCON1 |= SSPENB;//enable I2C}

10.2.2 Hàm i2c_startĐê khởi động I2C (Start condition) ta chỉ cần set bit Start Enable, SEN (SSPCON2<0>) và chờ cho đến khi quá trình này kết thúc. Quá trình khởi động I2C gôm nhiều gian đoạn, kết thúc mỗi giai đoạn sẽ có các cờ báo hiệu.

Page 80: Bai Giang Pic Rat Hay Va Day Du

Hình 10.3 : Khởi động I2C

Ban đầu 2 chân SDA và SCL ở mức cao. Khi SEN = 1, bộ sinh baudrate bắt đầu đếm và khi hết time out, chân SDA kéo xuống mức thâp, bit S (SSPSTAT<3>) bật lên 1 báo hiệu giai đoạn 1 của quá trình khởi động I2C kết thúc. Sau đó bộ sinh baudrate được load lại và bắt đầu đếm. Khi hết time out, chân SCL sẽ được kéo xuống thâp, kết thúc quá trình khởi động I2C. Lúc này bit SEN được xóa bằng phần cứng và bit SSPIF được bật lên 1.Khi hiện thực code nếu viết kĩ ta có thê chờ từng giai đoạn, tuy nhiên module I2C được tích hợp sẵn trong PIC nên xác suât lỗi cũng rât thâp. Ta có thê làm đơn giản hơn bằng cách set bit SEN lên và chờ cho đến khi SSPIF bật lên 1. Ta cần phải xóa SSPIF cho lần kiêm tra tiếp theo vì bit này không được tự động xóa bằng phần cứng.Code:

void i2c_wait(){

while(PIR1bits.SSPIF != 1){}; //wait SSPIF setPIR1bits.SSPIF = 0; //clear SSPIF

}void i2c_start(){

SSPCON2bits.SEN = 1; //set start enable biti2c_wait(); //wait SSPIF set

}

10.2.3 Hàm i2c_stop

Page 81: Bai Giang Pic Rat Hay Va Day Du

Hình 10.4 : Stop I2C

Quá trình kết thúc I2C được bắt đầu bằng cách set bit PEN (SSPCON2<2>). Cũng giống như quá trình khởi động, quá trình kết thúc gôm 2 giai đoạn chính và ở mỗi giai đoạn đều có bit báo hiệu nhưng ta có thê lập trình đơn giản bằng cách set bit PEN và chờ cho đến khi SSPIF được set lên 1.Code:

void i2c_stop(){

SSPCON2bits.PEN = 1; //set stop enable biti2c_wait(); //wait SSPIF is set

}

10.2.4 Hàm i2c_write_byteViệc gửi 1 byte dữ liệu từ master xuống slave được bắt đầu khi có lệnh gán vào thanh ghi SSPBUF. Ngay lúc này cờ BF (Buffer Full) sẽ bật lên 1. Quá trình gửi dữ liệu bắt đầu theo từng xung clock ở chân SCL. Sau 8 clock, 8 bit dữ liệu trong thanh ghi SSPBUF được shift hết và cờ BF bật xuống 0. Master sẽ thả chân SDA đê slave có thê gửi tín hiệu ACK về master. Nếu nhận được ACK, bit ACKSTAT sẽ được xóa, ngược lại bit này sẽ được bật lên 1. Giá trị ACK được lưu trong bit ACKDT.Quá trình gửi ACK từ slave lên master được thực hiện trong clock thứ 9 của SCL và sau đó bit SSPIF được set lên 1.Người lập trình có thê check qua các cờ BF, ACKSTAT và sau cùng là SSPIF đê kiêm tra lỗi. Đoạn code dưới đây chỉ kiêm tra có nhận được ACK hay không chứ chưa kiêm tra ACK đúng hay sai.Code:

void i2c_write_byte(unsigned char abyte){

SSPBUF = abyte;//wait BF is setwhile(SSPSTATbits.BF != 0){}//wait ACK received, ACKSTAT is set

while(SSPCON2bits.ACKSTAT != 0){}i2c_wait();

Page 82: Bai Giang Pic Rat Hay Va Day Du

}

Tuy nhiên trong 1 vài ứng dụng đơn giản ta có thê viết như sau:Code:

void i2c_write_byte(unsigned char abyte){

SSPBUF = abyte;//byte to sendi2c_wait(); //wait SSPIF is set

}

10.2.5 Hàm i2c_read_byteHàm này dùng đê đọc 1 byte dữ liệu từ slave và. Khi bit RCEN (SSPCON2<3>) được set lên 1, dữ liệu từ slave bắt đầu gửi vào thanh ghi SSPBUF. Sau 8 clock dữ liệu sẽ được shift đủ vào thanh ghi SSPBUF và cờ BF sẽ được bật lên 1. Đông thời cờ SSPIF cũng được set và RCEN được clear bằng phần cứng. Khi đọc xong, cờ SSPIF sẽ được xóa, ta cần set ACKEN lên 1 (SSPCON2<4>) đê gửi ACK về cho slave. Bit ACK là 0 hay 1 được quy định trong bit ACKDT (SSPCON2<5>). Khi gửi xong ACK ở clock thứ 9, cờ SSPIF sẽ được bật lên lại.Code:

unsigned char i2c_read_byte(unsigned char ack){

SSPCON2bits.RCEN = 1; //enable receivei2c_wait(); //wait SSPIF is set

SSPCON2bits.ACKDT = ack; //set ACK valuei2c_wait(); //wait SSPIF is set

SSPCON2bits.ACKEN = 1; //enable ACK feedbackreturn SSPBUF;

}

10.3 Real Time Clock DS1307DS1307 là IC thời gian thực (Real time clock) đếm giờ, phút, giây, tháng, ngày của tháng, ngày của tuần, năm kê cả năm nhuận (đến năm 2100).56 byte Ram đê lưu trữ dữ liệu, nhưng dữ liệu không bị mât khi tắt nguôn.Sử dụng 2 dây tín hiệu đê truyền dữ liệu theo giao thức I2C.Có thê lập trình được đê xuât tín hiệu xung vuông.Tự động phát hiện ra nguôn cung câp bị lỗi (ngắt nguôn) và chuyên qua mạch bảo vệ sử dùng nguôn pin dự trữ.

10.3.1 Nguyên lý hoạt độngDS1307 hoạt động như một slaver trên bus dữ liệu nối tiếp. Đê truy xuât nội dung ta phải thiết lập một điều kiện Start và cung câp mã nhận dạng của IC (Device Identification Code) theo sau bởi thanh ghi địa chỉ. Các thanh ghi theo sau được truy xuât tuần tự cho đến khi gặp tín hiệu Stop.Khi VCC = 1.25Vbat thì DS1307 sẽ kết thúc việc truy xuât và reset lại bộ đếm địa chỉ. Các Input sẽ không được nhận ra tại thời điêm này đê ngăn ngừa một số lượng lớn dữ liệu được ghi tới DS1307 từ hệ thống bên ngoài. Khi VCC < Vbat thì ic này sẽ chuyên sang mode sử dụng pin dự trữ. Khi nguôn chính được bật lên thì IC này sẽ chuyên từ dùng nguôn pin sang dùng nguôn chính. Hình sau mô tả những phần chính của DS1307.

Page 83: Bai Giang Pic Rat Hay Va Day Du

Hình 10.5 : Sơ đô khối DS130710.3.2 Các tín hiệu Input và OutputVCC, GND : Nguôn DC được cung câp cho IC qua những chân này. Khi gắn vào nguôn 5V thì IC này có thê đọc ghi bình thường. Nhưng khi nguôn giảm xuống còn 3V thì việc đọc ghi sẽ không được phép. Tuy nhiên, các chức năng của timer vân tiếp tục với nguôn cung câp thâp. Khi Vcc giảm xuống dưới VBAT thì RAM và timekeeper được chuyên qua sử dụng nguôn cung câp tại VBAT.VBAT : Cung câp nguôn dữ trữ 3V. Đê hoạt động ở chế độ sử dụng nguôn Vbat thì 2.0V < Vbat < 3.5V. Khi VCC gần bằng 1.25VBAT thì chúng ta sẽ không được phép truy xuât vào RTC (Real time clock) và Ram bên trong của IC. 

SCL (Serial Clock Input) : SCL được dùng đê đông bộ dữ liệu trên đường truyền nối tiếp.

SDA (Serial Data Input/Output) : SDA là chân I/O. SDA là chân Open drain nên cần có điện trở kéo lên ở bên ngoài.

SQW/OUT (Square Wave/Output Driver) : Khi được bật lên, thì bit SQWE set lên 1, và chân này sẽ output ra 1 trong 4 tần số sóng vuông là 1hz, 4khz, 8khz, 32khz. Chân này cũng là chân Open drain nên cũng yêu cầu có điện trở kéo lên nguôn ở bên ngoài. SQW/OUT sẽ hoạt động khi có nguôn cung câp vào cho dù đó là nguôn VCC hay là VBAT.

X1, X2 : Kết nối với thạch anh 32.768Khz. Mạch tạo xung bên trong được thiết kế đê hoạt động với thạch anh và tụ CL = 12.5 pF.10.3.3 RTC và sơ đồ địa chỉ RamSơ đô địa chỉ của RTC và các thanh ghi Ram của DS1307 như ở hình dưới. Các thanh ghi RTC được định địa chỉ từ 00h đến 07h. Các thanh ghi Ram được định địa chỉ tiếp theo sau đó và từ 08h đến 3fh. Trong khi truy suât nhiều byte và khi con trỏ địa chỉ chỉ tới ô 3fh, vị trí cuối của vùng nhớ Ram, thì nó sẽ quay lại địa chỉ 00h đê truy xuât tiếp. 

Page 84: Bai Giang Pic Rat Hay Va Day Du

Hình 10.6 : RTC và sơ đô RAM10.3.4 Thông tin thời gian và lịchThông tin thời gian và lịch được chứa trong trong các thanh ghi tương ứng. Các thanh ghi RTC như ở hình trên. Thời gian và lịch được set hoặc khởi tạo bằng cách ghi ra các byte thanh khi tương ứng. Nội dung của các thanh ghi thời gian và lịch được định dạng theo kiêu BCD. Bit 7 của thanh ghi 0 là clock halt bit (CH). Khi bít này được set lên 1 thì mạch dao động sẽ bị ẩn không được sử dụng nữa, khi clear xuống 0 thì mạch dao động sẽ được kích hoạt trở lại.

DS1307 có thê chạy ở chế độ 12h hay 24h. Bít thứ 6 của thanh ghi hours được định nghĩa đê set xem sử dụng IC này ở chế độ nào. Khi bit này bằng 1 thì chế độ 12h được chọn. Trong chế độ 12h thì bit 5 chỉ AM/PM (PM khi bit này là 1). Trong chế độ 24h, thì bít 5 là bít thứ 2 của 10hour (20:23).

Hình 10.7 : Định dạng dữ liệu10.3.5 Ghi dữ liệu vào DS1307

Page 85: Bai Giang Pic Rat Hay Va Day Du

Hình 10.8 : Ghi dữ liệu vào DS1307Đây là quá trình truyền dữ liệu từ master xuống slave. Khi master gửi xong 1 byte, slave sẽ gửi lại bit ACK. Quá trình giao tiếp như sau:

Master gửi tín hiệu Start. Master gửi địa chỉ của DS1307 (1101 000) và bit R/W, trong trường hợp này là 0. Byte đầu

tiên mà master gửi xuống sau khi start là D0. Master gửi địa chỉ pointer dữ liệu cần ghi, chẳng hạn là 0x00 (register pointer, word address) Master gửi các byte data cần ghi. Master gửi tín hiện stop.

Code hiện thực cho quá trình này như sauCode:

void rtc_write(unsigned char *buff){

i2c_start();i2c_write_byte(0xD0); //Address + Write biti2c_write_byte(0x00); //Pointeri2c_write_byte (*(buff+0)); //Secondi2c_write_byte (*(buff+1)); //Minutei2c_write_byte (*(buff+2)); //Houri2c_write_byte (*(buff+3)); //Dayi2c_write_byte (*(buff+4)); //Datei2c_write_byte (*(buff+5)); //Monthi2c_write_byte (*(buff+6)); //Yeari2c_stop();

}

buff là 1 mảng có 7 phần tử, tương ứng với các giá trị giây, phút, giờ, thứ, ngày, tháng và năm.10.3.6 Đọc dữ liệu từ DS1307

Hình 10.9 : Đọc dữ liệu từ DS1307Đây là quá trình truyền dữ liệu từ slave lên master. Như đã trình bày ở phần trước, khi gửi nhận từng byte, sẽ có bit ACK đi kèm ngoại trừ byte cuối cùng trước khi stop. Đê có thê đọc chính xác giá trị mong muốn, thông thường ta phải ghi vào thanh ghi địa con trỏ dữ liệu (register pointer). Quá trình này chính là trình truyền dữ liệu từ master xuống slave nên R/W bit sẽ là 0. Sau khi ghi dữ liệu và register pointer xong, quá trình đọc dữ liệu mới bắt đầu, và bit R/W sẽ là 1.Từng bước đọc dữ liệu từ DS1307 như sau:

Master gửi tín hiệu start. Master gửi địa chỉ DS1307 + R/W = 0 : 0xD0. Master gửi byte ghi vào register pointer : 0x00.

Page 86: Bai Giang Pic Rat Hay Va Day Du

Master gửi tín hiệu start Master gửi địa chỉ DS1307 + R/W = 1 : 0xD1. Master đọc các byte dữ liệu và gửi bit ACK. Byte cuối cùng trước khi stop, master gửi bit

NACK. Master gửi tín hiện stop.

Code hiện thực cho quá trình này như sauCode:

void rtc_read(unsigned char * buff){

//send address to slave and reset pointeri2c_start();i2c_write_byte(0xD0); //Address + Write biti2c_write_byte(0x00); //Pointer

i2c_start(); //Restarti2c_write_byte(0xD0); //Address + Read bit*(buff+0)=i2c_read_byte(ACK); // Second*(buff+1)= i2c_read_byte(ACK); // Minute*(buff+2)= i2c_read_byte(ACK); // Hour*(buff+3)= i2c_read_byte(ACK); // Day*(buff+4)= i2c_read_byte(ACK); // Date*(buff+5)= i2c_read_byte(ACK); // Month*(buff+6)= i2c_read_byte(ACK); // Year

i2c_stop();}

10.4 Xây dựng chương trìnhỞ đây sẽ giới thiệu câu trúc chương trình hiên thị thông tin ngày tháng năm, giờ phút giây của DS1307 lên LCD. Chương trình gôm 3 module 9 là I2C, RTC và LCD.

Hình 10.10 : Câu trúc chương trìnhChi tiết chương trình được hiện thực trong thư mục Bai11_I2C. Đê chạy được chương trình bạn cần bật 2 switch của RTC (SW4) lên ON, bật nguôn của LCD (SW3) và tắt led ở PortB (SW1).

Page 87: Bai Giang Pic Rat Hay Va Day Du

Hình 10.11 : Chương trình DS1307 trên BKIT PIC10.5 Code mâu

Bài 14 : Analog to Digital Converter ADCMục đích:Tìm hiêu module ADC của PIC18F.Yêu cầu:Viết chương trình hiên thị giá trị ADC ở chân AN0 lên LCD.11.1 Giới thiệuVi điều khiên chỉ có thê xử lý được tín hiệu số rời rạc (digital signal), chúng không thê xử lý được các tín hiệu tương tự (analog signal). Bộ chuyên đổi tín hiệu tương tự sang số (analog to digital converter) hay còn gọi là ADC, sẽ chuyên điện áp tương tự (analog voltage hay analog signal) sang dạng số rời rạc (digital number). Vi xử lý sẽ biêu diễn tín hiệu điện áp tương tự thành 1 số nguyên (non-fractional number) và sẽ xử lý trên số nguyên này.

Hình 11.1: Analog to Digital ConverterTheo ví dụ ở trên, điện áp 2.343volt sẽ được chuyên đổi thành số nguyên 87. Người lập trình có thê dùng số 87 này đê biêu diễn cho giá trị điện áp ngõ vào 2.343 volt. Việc vi điều khiên xử lý trên số 87 sẽ đạt hiệu quả cao hơn, vì nó là 1 số nguyên.11.2 Nguyên lý chuyển đổi ADC

Page 88: Bai Giang Pic Rat Hay Va Day Du

Hình 11.2 : Chuyên đổi ADCQuá trình chuyên đổi ADC gôm 3 giai đoạn:

Giai đoạn 1 : Nạp điện cho tụ ở chân ADC (Holding Capacitor). Giai đoạn này tốn 1 khoảng thời gian được gọi là Acquisition time (TACQ). Trong vi điều khiên PIC, thời gian này có thê được câu hình bằng tay hoặc tự động. Khi chọn câu hình bằng tay, người lập trình phải tự tính toán thời gian delay đê có thê nạp đầy tụ trước khi ban hành lệnh chuyên đổi. Khi chọn câu hình tự động, vi điều khiên sẽ đảm bảo là sau khi ban hành lệnh chuyên đổi 1 khoảng TACQ, quá trình chuyên đổi mới bắt đầu. Thời gian này là 1 hằng số và tùy thuộc vào vi điều khiên. Chúng ta cần đọc kĩ datasheet của nó đê xác định cho đúng.

Giai đoạn 2 : Ngắt kết nối với tụ Holding Capacitor bằng 1 lệnh SLEEP. Quá trình này được thực hiện tự động bởi vi điều khiên, người lập trình không cần phải quan tâm. Thời gian chuyên đổi phụ thuộc vào độ phân giải của giá trị ADC (8bit, 10bit hay 13 bit) và clock câp cho module ADC. Khi lập trình, chúng ta thường không quan tâm đến thời gian này vì khi chuyên đổi xong, vi điều khiên sẽ set cờ báo hiệu. Người lập trình chỉ cần polling xét cờ này hoặc sử dụng ngắt đê lây giá trị chuyên đổi.

Giai đoạn 3 : Xả tụ Holding Capacitor. Giai đoạn này chỉ chiếm 1 khoảng thời gian nhỏ và nó được thực hiện tự động bởi vi điều khiên. Giai đoạn này xảy ra sau khi cờ báo hiệu chuyên đổi hoàn tât. 

Đê có thê bắt đầu tiếp việc chuyên đổi lần thứ 2, vi điều khiên sẽ cần phải chờ thêm 1 khoảng thời gian xả tụ và acquisition time. Nếu không chờ đúng thời gian này, quá trình chuyên đổi bắt đầu sớm hơn, kết quả thu được có thê không còn chính xác nữa.

11.3 ADC trong PIC18FĐối với dòng chip PIC 40/44 chân có 13 kênh ADC, dòng 28 chân thì có 10 kênh ADC. Module ADC sẽ chuyên đổi tín hiệu tương tự thành tín hiệu số 10 bit. Module ADC trong PIC có 5 thanh ghi:

ADRESH : Thanh ghi kết quả, chứa phần bit cao. ADRESL: Thanh ghi kết quả, chứa phần bit thâp. ADCON0, ADCON1, ADCON2 : Các thanh ghi điều khiên.

Thanh ghi ADCON0

Hình 11.3 : Thanh ghi ADCON0

Bit 7-6 : Không sử dụng.Bit 5-2 CHS3-CHS0 : Lựa chọn kênh Analog.0000 : Kênh 0 (AN0)0001 : Kênh 1 (AN1)0010 : Kênh 2 (AN2)1101 : Kênh 11 (AN11)1100 : Kênh 12 (AN12)1101,1110,1111 : Không sử dụng.Bit 1 GO/DONE : Bit trạng thái của quá trình chuyên đổi khi ADON = 1.1 : Đang chuyên đổi A/D.0 : Chuyên đổi hoàn tât.Bit 0 ADON : A/D On bit1 : Cho phép chuyên đổi.0 : Tắt chức năng chuyên đổi.Thanh ghi ADCON1

Page 89: Bai Giang Pic Rat Hay Va Day Du

Hình 11.4 : Thanh ghi ADCON1Bit 7 – 6 : Không sử dụng.Bit 5 : VCFG1 Voltage Reference Configuration bit (bit câu hình điện áp tham khảo VREF-)1 : Điện áp tham khảo VREF- là điện áp ở chân AN20 : Điện áp thao khảo VREF- = VSSBit 4 : VCFG0 Voltage Reference Configuration bit (bit cân hình điện áp tham khảo VREF+)1 : Điện áp tham khảo VREF+ là điện áp ở chân AN30 : Điện áp tham khảo VREF+ là VDDBit 3-0 A/D Port Configuration Control bits : Câu hình chân là Analog hay Digital

Thanh ghi ADCON2

Hình 11.5 : Thanh ghi ADCON2Bit 7 ADFM : Định dạng kết quả trong 2 thanh ghi ADRESH và ADRESL1 : Canh phải 

0 : Canh trái

Bit 6 : Không sử dụngBit 5-3 : A/D Acquisition Time Select bit : Bit chọn thời gian nạp cho tụ Holding Capacitor.111 : 20 TAD 110 : 16 TAD 101 : 12 TAD 100 : 8 TAD 011 : 6 TAD 010 : 4 TAD 001 : 2 TAD 000 : 0 TADTAD là thời gian đê chuyên đổi 1 bit ADC, phụ thuộc vào clock được lựa chọn bên dưới. Thời gian đê nạp cho tụ Holding Capacitor cố định là 2.4us, sau khi chọn clock cho module ADC, ta sẽ phải tính toán đê chọn hệ số nhân với TAD

Lưu ý trong trường hợp 000, đây là chế độ lập trình bằng tay cho thời gian Acquisition Time, người lập trình phải tự tạo 1 khoảng thời gian delay cho quá trình nạp tụ Holding Capacitor.Bit 2-0 : A/D Conversion Clock Selection bit : Bit chọn clock cho bộ chuyên đổi A/D111 : FRC 110 : FOSC/64 101 : FOSC/16 100 : FOSC/4011 : FRC 010 : FOSC/32 001 : FOSC/8 000 : FOSC/2Nếu ta chọn là 000 thì TAD = 2 TOSC = 2/FOSC, FOSC là chu kì lệnh, bằng ¼ tần số dao động.11.4 Cấu hình ADC trong PIC18FViệc câu hình module ADC trong PIC18F đi theo trình tự sau:

Câu hình chân A/D (số kênh AD, chiều của chân AD là input), điện áp tham khảo (ADCON1) Chọn kênh A/D (ADCON0) Chọn thời gian acquisition time (ADCON2) Chọn clock. Bật chế độ AD (bit ADON trong ADCON0).

Nếu chọn lựa chế độ acquisition time là tự động, bạn chỉ cần set bit GO_DONE đê bắt đầu quá trình chuyên đổi và polling bit này đê chờ cho đến khi quá trình chuyên đổi hoàn tât. 

Nếu acquisition time được chọn là chế độ chỉnh bằng tay (manual mode), bạn phải tự viết delay đê chờ, sau đó mới được phép set bit GO_DONE.11.5 Hiện thực chương trình

Page 90: Bai Giang Pic Rat Hay Va Day Du

Hình 11.6 : Kiến trúc chương trình ADC

11.5.1 Hàm init_adc()Hàm này dùng đê khởi tạo ban đầu cho module ADC, được hiện thực đúng theo trình tự câu hình ADC trong PIC 18F. Ở mạch BKIT PIC, chỉ có 1 kênh ADC nối với chân AN0, bit 0 của PortA.

Ở thanh ghi ADCON1, ta sẽ lần lượt chọn điện áp tham khảo là VSS và VDD, các bit 5,4 set là 0.

Câu hình chỉ dùng 1 kênh AD ở chân AN0, bit 3:0 PCFG3:PCFG0 = 1110, ADCON1 = 0x0E. Câu hình chiều input cho chân ADC này.

Chọn kênh AD0 đê chuyên đổi bằng cách thiết lập CHS3:CHS0 = 0000, ADCON0 = 0x00.

Chọn clock là FOSC /2 (ADCS2:ADCS0 = 000), lúc đó TAD = 2TOSC = 2/(5MHz) = 2/(510^6) (s).

Thời gian acquisition time là hằng số 2.4us = 2.4 10^-6 (s).Ta phải thỏa mãn được 2.4 10^-6 <= 2k/(510^6) => k >= 1.2 Ta sẽ chọn k = 2 AQCT2:AQCT0 = 001.Như vậy ADCON2 = 0x04.Bật bit ADON ở thanh ghi ADCON0.Code:

void init_adc(){

TRISA = 0x01; //input for analog pinADCON1 = 0x0E; //config ADC pinsADCON0 = 0x00; //select AN0ADCON2 = 0x04; //select acquisition timeADCON0bits.ADON = 1;//enable ADC

}

11.5.2 Hàm get_adc_valueSau khi khởi tạo xong module ADC, ta có thê lây kết quả bât cứ lúc nào. Trước tiên ta sẽ set bit GO_DONE lên 1 đê bắt đầu quá trình chuyên đổi và chờ cho nó xuống 0, việc chuyên đổi hoàn tât, kết quả sẽ được lưu trong 2 thanh ghi ADRESH:ADRESL (chế độ canh trái).Code:

int get_adc_value(){

int result = 0;ADCON0bits.GO_DONE = 1; //start conversionwhile(ADCON0bits.GO_DONE == 1){} //pollingresult = ADRESH;result = (result<<2) + (ADRESL>>6);return result;

}

Nếu người dùng chỉ cần 8 bit thì có thê sử dụng giá trị trong thanh ghi ADRESH là đủ.

Page 91: Bai Giang Pic Rat Hay Va Day Du

Hình 11.7 : Chương trình ADC trên BKIT PIC11.6 Code mâu

Download tại đây__________________

Bài 15 : Điêu chế xung PWM

Mục đích:Tìm hiêu module CCP1 của PIC18F, thiết lập chế độ hoạt động PWM.Yêu cầu:Viết chương trình điều khiên tốc độ động cơ, hiên thị tốc độ ra màn hình LCD.12.1 Khái niệm PWMPWM viết tắt của từ Pulse Width Modulation. PWM được sử dụng nhiều trong hệ thống điều khiên tự động ngày nay. Nó được ứng dụng trong điều khiên tốc độ động cơ, độ sáng tối của led, màn hình LCD, pha màu cho bang quang báo, sử dụng trong các thuật toán điều khiên vận tốc cho Robot như PI, PD, PID …Hiêu đơn giản PWM hoạt động như một công tác đóng mở rât nhiều lần trong 1 giây. Nếu tần số đóng mở càng nhanh thì điện áp câp trung bình càng lớn.

Page 92: Bai Giang Pic Rat Hay Va Day Du

Một số khái niệm cơ bản của PWM :

Tần số (Hz, Khz…). Chu kỳ T, thời gian xung mức cao TH + thời gian xung mức thâp TL. Duty Cycle: tỉ lệ thời gian xung mức và thời gian xung mức thâp.

Như hình trên ta có Duty Cycle lần lượt là 0%, 25%, 50%, 75%, 100%.Một số công thức :

Khi đó nếu TOn = 0 thì VoltOutput = 0 (V) còn TOn = TTotal thì VoltOutput = VoltInput .

12.2 PWM trong PIC18F4520

Page 93: Bai Giang Pic Rat Hay Va Day Du

PIC18F4520 có 2 module CCP. Ở đây chúng tôi giới thiệu module CCP1. Module này ngoài chức năng PWM thông thường, nó còn có chức năng Enhanced PWM dùng đê điều khiên một số loại mạch cầu H thông dụng. Nguyên lý hoạt động chung của các module PWM tích hợp sẵn trong vi điều khiên là nó sẽ sử dụng 1 bộ timer đê đếm. Khi giá trị đếm của timer bằng với Chu kì hoặc Duty Cycle thì ngõ ra sẽ thay đổi. Hình ở dưới đây minh họa cách hoạt động của module PWM trong PIC18F4520, nó sử dụng timer2 cho bộ đếm.

Hình 12.1 : Nguyên lý hoặt động của PWM

Trình tự thiết lập PWM trong PIC18F4520 như sau:

12.2.1 Thiết lập chu kì PWMChu kì của module CCP1 được tính như sau :PWM Period = (PR2 + 1)*4*TOSC*(TMR2 Prescaller)Trong đó TOSC = 1/FOSC, FOSC = 20MHz nếu sử dụng thạch anh ngoài.TMR2 Prescaller được xác định trong thanh ghi T2CON. Ở chế độ mặc định ban đầu, TMR2 Prescaller = 1.

Trên thực tế, người ta dùng thuật ngữ tần số PWM, là nghịch đảo của chu kì :

PWM Frequence = FOSC/ [ (PR2+1) * 4 * (TMR2 Prescaller) ]Tần số đê điều khiên PWM tùy thuộc vào từng loại thiết bị. Đối với động cơ, tần số PWM phải phù hợp với độ đáp ứng của driver điều khiên động cơ.Trong mạch BKIT PIC, chúng tôi chọn tần số là 2 kHz. Giả sử ta chọn TMR2 Prescaller là 16 (T2CKPS1 = 1), thì giá trị của PR2 là PR2 = 20MHz/ (4 * 16 * 2KHz) - 1 ~ 15512.2.2 Thiết lập PWM Duty CycleDuty Cycle của CCP1 được thiết lập trong 2 thanh ghi CCPR1L (8bit) và 2 bit DC1B1:0 trong thanh ghi CCP1CON. Tuy nhiên đối với động cơ nhỏ thì với 8 bit là đủ, ta có thê đê mặc định DC1B1:0 = 00 ngay khi khởi tạo. Giá trị của CCPR1L càng cao thì duty cycle càng lớn, và như vậy điện áp ngõ ra của CCP1 (RC2) càng cao.

Sau khi đã thiết lập xong 2 thông số trên, các bước còn lại là thiết lập chiều output cho chân RC2, cho phép timer2 đếm bằng cách set bit TMR2ON lên 1, và câu hình CCP1CON là chế độ Single PWM.12.3 Xây dựng chương trìnhKiến trúc chương trình gôm có 2 module chính PWM và LCD.

Page 94: Bai Giang Pic Rat Hay Va Day Du

Hình 12.2 : Kiến trúc chương trình PWM

Module PWM gôm có 2 file pwm.h khai báo các interface và pwm.c đê hiện thực các interface đó. Interface trong pwm.h như sau:Code:

#ifndef _PWM_H_#define _PWM_H_#include <P18F4520.h>void init_pwm();void set_DC(unsigned char duty_cycle);#endif

12.3.1 Hàm init_pwmHàm này hiện thực quá trình khởi động cho module PWM. Trước tiên là câu hình prescaller cho timer2, nạp giá trị PWM Period và chọn chế độ PWM trong thanh ghi CCP1CON.Code:

void init_pwm(){

T2CONbits.TMR2ON = 0; //turn off timer2

T2CONbits.T2CKPS0 = 0;T2CONbits.T2CKPS1 = 1; //prescaler 1:16PR2 = 155; //PWM period

CCP1CONbits.DC1B0 = 0; //PWM duty cycleCCP1CONbits.DC1B1 = 0; //2 bits LSB CCPR1L = 0x00; //8bits MSB

CCP1CONbits.P1M0 = 0; //PWM single modeCCP1CONbits.P1M1 = 0;CCP1CONbits.CCP1M0 = 0; //select PWM functionCCP1CONbits.CCP1M1 = 0;CCP1CONbits.CCP1M2 = 1;CCP1CONbits.CCP1M3 = 1;

TRISCbits.TRISC2 = 0; //config RC2 outputT2CONbits.TMR2ON = 1; //start timer2

}

12.3.2 Hàm set_DCHàm này chỉ đơn giản là thiết lập duty cycle trong thanh ghi CCPR1L. Giá trị trong thanh ghi này càng cao thì áp ra ở chân RC2 càng cao, giá trị tối đa là 255 tương ứng với khoảng 5V.Code:

void set_DC(unsigned char duty_cycle){

CCPR1L = duty_cycle;}

Page 95: Bai Giang Pic Rat Hay Va Day Du

Chương trình demo cho phần này được hiện thực trong thư mục Bai13_PWM. Hàm main sẽ tăng dần duty cycle lên và động cơ sẽ quay nhanh dần. Giá trị của duty cycle (hay tốc độ của động cơ) sẽ được hiên thị ra LCD.

12.4 Code mâuDownload tại đây

Bài 16 : Giao tiếp UART RS232

13.1 Nguyên lý giao tiếp UARTUart RS232 là chuẩn giao tiếp khá phổ biến và được hỗ trợ ở hầu hết các dòng vi điều khiên vì khoảng cách xa và chi phí thâp. Dòng 8051 hỗ trợ 1 kênh giao tiếp uart.

Dữ liệu được truyền đi trên chân TX gôm 1 start bit (mức 0), data và 1 stop bit (mức 1).

Tốc độ truyền : đơn vị bit per second (bps) còn gọi là Baud (số lần thay đổi tín hiệu trong 1 giây – thường sử dụng cho modem). Đối với đường truyền thì Baud và bps là như nhau.

UART là phương thức truyền nhận bât đông bộ. nghĩa là bên nhận và bên phát không cần phải có chung tốc độ xung clock (ví dụ : xung clock của vi điều khiên khác xung clock của máy tính) . Khi đó bên truyền muốn truyền dữ liệu sẽ gửi start bit (bit 0) đê báo cho bên thu biết đê bắt đầu nhận dữ liệu và khi truyền xong dữ liệu thì stop bit (bit 1) sẽ được gửi đê báo cho bên thu biết kết thúc quá trình truyền.

Khi có start bit thì cả hai bên sẽ dùng chung 1 xung clock (có thê sai khác một ít) với độ rộng 1 tín hiệu (0 hoặc 1) được quy định bởi baud rate, ví dụ baud rate = 9600bps nghĩa là độ rộng của tín hiệu 0(hoặc 1) là 1/9600 = 104 ms và khi phát thì bên phát sẽ dùng baud rate chính xác (ví dụ 9600bps) còn bên thu có thê dùng baud rate sai lêch 1 ít(9800bps chẳng hạn).Truyền bât đông bộ sẽ truyên theo từng frame và mỗi frame có câu trúc như sau:

Page 96: Bai Giang Pic Rat Hay Va Day Du

Ngoài ra trong frame truyền có thê có thêm bit odd parity (bit lẻ) hoặc even parity (bit chẵn) đê kiêm tra lỗi trong quá trình truyền. Bit parity này có đặc điêm nếu sử dụng odd parity thì số các bit 1 + odd parity bit sẽ ra 1 số lẻ còn nếu sử dụng even parity thì số các bit 1 + even parity bit sẽ ra 1 số chẵn.

13.2 Giao tiếp UART với máy tínhĐê giao tiếp COM giữa vi điều khiên và máy tính, ta kết nối mạch theo sơ đô như sau:

Hình 13.1 : Kết nối máy tính và vi điều khiênDo mức điện áp của tín hiệu logic 1/0 ở cổng COM của máy tính khác với vi điều khiên, nên MAX 232 có tác dụng chuẩn hoá mức điện áp giữa máy tính và điều khiên trong quá trình truyền nhận dữ liệu. Nếu giao tiếp trực tiếp giữa 2 vi điều khiên, ta không cần phải sử dụng MAX 232.

13.3 UART trong PIC18FTrong phần này xin giới thiệu các bước thiết lập việc truyền 1 byte UART, việc câu hình nhận UART cũng tương tự như truyền. Trình tự các bước như sau :

Page 97: Bai Giang Pic Rat Hay Va Day Du

Nạp giá trị vào 2 thanh ghi BRGH: BRG đê thiết lập tốc độ truyền theo công thức Baudrate = Fosc/ (64 * ([BRGH : BRG] + 1)).

Enable serial port bằng cách clear bit SYNC và set bit SPEN Nếu muốn thiết lập interrupt, thì set thêm TXIE, GIE và PEIE. Set bit TXEN đê cho phép truyền. Nạp dữ liệu vào thanh ghi TXREG. Khi truyền xong cờ TXIF sẽ bật lên 1, ta sẽ kiêm tra cờ này trước khi truyền dữ liệu mới.

Hiện thực bằng code như sau :Code:

void init_uart_transmit(){

//step 1 : Select baurateTXSTAbits.BRGH = 0;BAUDCONbits.BRG16 = 1;SPBRGH = 0;SPBRG = 25; //9600

//step 2 : enable ASYNTXSTAbits.SYNC = 0;RCSTAbits.SPEN = 1;

//step 3 : enable uart transmission interruptPIE1bits.TXIE = 1;PIR1bits.TXIF = 0;INTCONbits.GIE = 1;INTCONbits.PEIE = 1;

//step 4 : disable bit 9TXSTAbits.TX9 = 0;

//step 5 : enable transmissionTXSTAbits.TXEN = 1;

}

Sau khi enable việc truyền, ta chỉ cần ghi dữ liệu và thanh ghi TXREG và kiêm tra cờ TXIF bật lên:Code:

void uart_transmit(unsigned char data){

TXREG = data;while(PIR1bits.TXIF == 1){}

}

13.4 Kiểm tra truyên nhận UARTĐê kiêm tra việc truyền nhận uart có đúng hay không ta thường dùng 1 số ứng dụng hyper terminal đê kiêm tra. Lúc này máy tính của chúng ta sẽ là đối tượng dùng đê giao tiếp với BKIT PIC. Trong đĩa CD này có phần mềm hyper terminal khá thông dụng chứa trong thư mục Terminal, bạn chỉ cần double click vào file Terminal.exe là khởi động được chương trình.

Page 98: Bai Giang Pic Rat Hay Va Day Du

Hình 13.2 : Hyper TerminalCông việc còn lại là câu hình cho cổng COM truyền nhận uart cho tương thích với giao thức truyền nhận của board 89. Các thông số thông thường là Baud rate 9600, Data bit 8bit, không có Parity (chọn none) và 1 Stop bit. Nhân nút Connect đê kết nối. Kê từ đây nếu board 89 có gửi dữ liệu lên, dữ liệu này sẽ nằm trong phần Receive. Ngược lại, muốn gửi dữ liệu xuống board 89 ta gõ vào textbox và ân Send.13.5 Download

Code mâu Phần mềm Terminal

Bài 17 : Giao tiếp với bàn phím PS2

13.6 Ngắt ngoài13.6.1 Giới thiệu ngắt ngoàiNgắt ngoài trên vi điều khiên thường là một chân vào có khả năng phát hiện sự thay đổi tín hiệu bên ngoài. Có thê chia ngắt thành hai loại : Ngắt cạnh và ngắt mức.Ngắt cạnh có hai loại: ngắt cạnh lên xảy ra khi có sự chuyên tín hiệu từ mức thâp lên mức cao ở chân ngắt ngoài. Tương tự ngắt cạnh xuống xảy ra khi có sự chuyên tín hiệu từ mức cao xuống mức thâp.Ngắt mức cũng có hai loại: ngắt mức cao và mức thâp. Ngắt mức cao (thâp) xảy ra khi tín hiệu tại chân ngắt ngoài ở mức cao (thâp) trong tối thiêu 1 chu kì. Trong vi điều khiên PIC chí có chế độ ngắt cạnh(lên/xuống) không tôn tại chế độ ngắt mức.13.6.2 Ngắt ngoài trong vi điều khiển PICTrong vi điều khiên PIC, có 3 ngắt ngoài INT0, INT1, INT2 nắm tương ứng với các chân RB0, RB1, RB2. Và trong vi điều khiên PIC chỉ có hai loại ngắt là ngắt cạnh lên và ngắt cạnh xuống. Đối với ngắt ngoài INT1 và INT2 có hai mức ưu tiên ngắt là ngắt có độ ưu tiên cao và độ ưu tiên thâp, còn đối với

Page 99: Bai Giang Pic Rat Hay Va Day Du

ngắt ngoài INT0 thì luôn cố định là ngắt có độ ưu tiên cao. Các chân ngắt ngoài khi sử dụng phải được câu hình ở chế độ input.13.6.3 Các thanh ghi để cấu hình ngắt ngoài cho PICNgắt trong ci điều khiên PIC được câu hình qua các thanh ghi INTCON, INTCON2, INTCON3.

Thanh ghi INTCON

Code:

Bit 7 GIE Global Interrupt EnableNếu IPEN = 01 = cho phép ngắt0 = cấm tất cả các ngắtNếu IPEN = 11 = cho phép ngắt mức cao0 = cấm tất cả các ngắt

Bit 6 PEIE Peripheral Interrupr EnableNếu IPEN = 01 = cho phép ngắt ngoại vi0 = cấm các ngắt ngoại viNếu IPEN = 01 = cho phép ngắt mức thấp0 = cấm ngắt mức thấp

Bit 4 INT0IE External Interrupt 0 Enable1 = cho phép ngắt ngoài 00 = tắt ngắt ngoài 0

Bit 0 INT0IF External Interrupt Flag1 = cờ báo ngắt của ngắt ngoài 00 = không có tín hiệu ngắt ngoài 0

Thanh ghi INTCON2

Code:

Bit 6 INTEDG0 External Interrupr 0 Edge Select1 = ngắt ngoài 0 khi có cạnh lên0 = ngắt ngoài 0 khi có cạnh xuống

Bit 5 INTEDG1 External Interrupr 1 Edge Select1 = ngắt ngoài 1 khi có cạnh lên0 = ngắt ngoài 1 khi có cạnh xuống

Bit 4 INTEDEG2 External Interrupt 2 Edge Select1 = ngắt ngoài 2 khi có cạnh lên0 = ngắt ngoài 2 khi có cạnh xuống

Thanh ghi INTCON3

Code:

Page 100: Bai Giang Pic Rat Hay Va Day Du

Bit 7 INT2IP External Interrupt 2 Priority1 = độ ưu tiên cao0 = độ ưu tiên thấp

Bit 6 INT1IP External Interrupt 1 Priority1 = độ ưu tiên cao0 = độ ưu tiên thấp

Bit 4 INT2IE External Interrupt 2 Enable1 = cho phép ngắt ngoài 20 = tắt ngắt ngoài 2

Bit 3 INT1IE External Interrupt 1 Enable1 = cho phép ngắt ngoài 10 = tắt ngắt ngoài 1

Bit 1 INT2IF External Interrupt 1 Flag1 = cờ báo ngắt của ngắt ngoài 00 = không có tín hiệu ngắt ngoài 0

Bit 0 INT1IF External Interrupt 1 Flag1 = cờ báo ngắt của ngắt ngoài 00 = không có tín hiệu ngắt ngoài 0

Các cờ ngắt ngoài INT0IF, INT1IF, INT2IF phải được xóa bằng chương trình trong hàm xử lý ngắt của chúng.13.7 Giao tiếp PS/2Dữ liệu trong giao tiếp PS/2 được truyền nối tiếp từng bit. Khi một phím được nhân, 11 bit bao gôm Start bit, 8 bit dữ liệu (bit trọng số thâp truyền trước), 1 bit parity và 1 stop bit sẽ được gửi đi:

Hình 14.1 Dạng sóng của giao tiếp PS/2Ta sẽ lây dữ liệu tại cạnh xuống của clock, chân của clock được nối vào chân ngắt ngoài INT0 của vi điều khiên Atmega32 (PD2) như sau:

Page 101: Bai Giang Pic Rat Hay Va Day Du

Hình 14 14.2 Sơ đô kết nối PS/2Khi 1 phím được nhân xuống, mã make_code sẽ được gửi lên. Trong khoảng thời gian phím đó được đè xuống thì mã make_code vân được định kì gửi lên. Khi thả phím ra thì bàn phím gửi lên mã break_code và make_code.Bảng mã make_code và break_code của các phím như sau:

Page 102: Bai Giang Pic Rat Hay Va Day Du

Dễ dàng nhận ra mã break_code của 1 phím gôm 0xF0 và mã make_code của phím đó.13.8 Xây dựng chương trìnhGạt bit 2 của Switch3 lên ON đê gắn điện trở kéo lên cho chân CLOCK và DATA của bàn phím PS/213.8.1 Khởi tạo ngắt ngoàiCode:

void init_ext_int0(void){

INTCONbits.INT0IE = 1; // set external interrupt0INTCONbits.INT0IF = 0; // clear external interrupt0 flagINTCON2bits.INTEDG0 = 0;// interrupt when appear an falling edge on

RB0/INT0

TRISBbits.TRISB0 = 1; // set input for CLOCK pinTRISBbits.TRISB1 = 1; // set input for DATA pin

}

13.8.2 Xử lý ngắtPhần chính của bài thực hành này là lây cho được dữ liệu truyền lên từ bàn phím. Quá trình dịch từng bit đê lây dữ liệu 8 bit trong chuỗi 10 bit được hiện thực trong hàm phục vụ ngắt ngoài INT0.Code:

#pragma code#pragma interrupt high_isrvoid high_isr(void){

if (INTCONbits.INT0IF){

Page 103: Bai Giang Pic Rat Hay Va Day Du

INTCONbits.INT0IF = 0;count_bits ++;if (count_bits == 1)

ps2_scan_code = 0;if (count_bits >1 && count_bits < 10){

ps2_scan_code = ps2_scan_code >> 1;if (PS2_DATA == 1)

ps2_scan_code |= 0x80;parity ^= PS2_DATA;

}if (count_bits == 12){

scan_code = ps2_scan_code;ps2_scan_code = 0;parity = 0;

}}

}

Biến count_bits dùng đê đếm số bit gửi về, khi count_bit_input = 11 ta sẽ có được dữ liệu scan_code từ bàn phím truyền lên. Bạn sẽ phải xử lý đê phân loại đây là mã make_code hay break_code, có được nhân kèm với phím Shift hay Caps Lock hay không đê chuyên sang mã ASCII cho kí tự được nhân.13.9 Download

Code mâu

Bài 18 : Graphics LCD 128x64

14.1 Giới thiệu GLCD 128x64Graphic LCD được sử dụng trên mạch BKIT PIC là loại LCD châm, không màu, có độ phân giải 128x64 tức 8192 châm. GLCD được thiết kế đê điều khiên được từng châm, nên có thê dùng đê hiên thị bât kỳ ký tự hay hình ảnh nào. Với mỗi châm tương ứng một bit dữ liệu, GLCD 128x64 cần 8192 bits RAM hay 1024 bytes RAM đê hiên thị toàn màn hình.Loại GLCD YM12864J sử dụng 2 chip điều khiên KS0108 rât phổ biến của Samsung, mỗi chip có 512 bytes RAM. Do đó, nó tương tự như 2 LCD 64x64 ghép lại với nhau.

Hình 15 1 GLCD 128x64

Page 104: Bai Giang Pic Rat Hay Va Day Du

14.1.1 Chức năng các chân của GLCD 128x64Chức năng các chân:

Các chân từ 4 đến 17 được kết nối trực tiếp đến vi điều khiên. Các chân còn lại được kết nối tùy theo chức năng tương ứng của nó. 

Chân ENKhi thực hiện một quá trình giao tiếp với GLCD, ban đầu, chân EN được kéo xuống thâp. Trong khi đó, các chân điều khiên khác được thiết lập. Sau khi thiết lập xong, chân EN được kích lên mức cao đê cho phép tín hiệu. Sau khoảng thời gian cần thiết cho quá trình hoàn tât, chân EN lại được kéo xuống thâp đê sẵn sàng cho một quá trình khác.Chân RS và RWHai chân này được kết hợp đê thiết lập cho các thanh ghi của GLCD theo bảng sau:

Chân CS1 và CS2Chọn chip điều khiên GLCD – KS0108 đê giao tiếp, tích cực mức cao.14.1.2 Tổ chức bộ nhớ RAMChip điều khiên GLCD KS0108 chỉ có một loại bộ nhớ là RAM, không có bộ nhớ chứa bộ font CGROM hay chứa mã font tự tạo CGRAM như của Text LCD. Dữ liệu ghi vào RAM sẽ được hiên thị trực tiếp trên GLCD. Mỗi chip KS0108 có 512 bytes RAM tương ứng với 4096 châm trên một nửa (64x64) LCD. RAM của KS0108 được truy cập theo từng byte, nghĩa là mỗi lần viết một giá trị vào một byte nào đó trên RAM của GLCD, sẽ có 8 châm bị tác động, 8 châm này nằm trên cùng 1 cột. Do đó, 64 dòng GLCD được chia thành 8 pages, mỗi page có độ cao 8 bit và rộng 128 cột (tính cả 2 chip).Sơ đô bố trí RAM:

Page 105: Bai Giang Pic Rat Hay Va Day Du

Hình 15 2 Sơ đô bố trí RAM của GLCD 128x64Với mỗi chip KS0108, RAM chia thành 8 page, mỗi page bao gôm 64 cột, mỗi cột bao gôm 8 châm. Các page được gọi là địa chỉ X, mang giá trị từ 0 đến 7, X = 0 tương ứng với page 0 và tương tự. Các cột được gọi là địa chỉ Y, cột đầu tiên có giá trị Y = 0 và cột cuối cùng có giá trị Y = 63. Mỗi cột là một byte RAM, D0 đến D7, với D0 tương ứng điêm trên cao và D7 tương ứng điêm bên dưới. Các lệnh di chuyên được hỗ trợ theo cặp địa chỉ X, Y.Minh họa hiên thị ký tự “a” trên GLCD:

Hình 15 3 Ký tự "a" trên GLCDNhư hình trên, ký tự “a” được xác định bằng cách ghi dữ liệu vào X = 0 và Y = 0...7 theo bảng sau:

Page 106: Bai Giang Pic Rat Hay Va Day Du

Hình 15 4 Dữ liệu RAM cho ký tự "a"Giá trị Data là các giá trị cần nạp cho vùng RAM tương ứng.14.1.3 Các lệnh của GLCD 128x64Bảng lệnh

1. Lệnh hiển thị ON/OFFDữ liệu được hiên thị lên màn hình khi bit D (DB0) bằng 1 và ngược lại khi D bằng 0. Khi D bằng 0, dữ liệu vân tôn tại trong DDRAM. Lập trình:• RW = 0• RS = 0• Opcode = 0x3E + D (D = 0:1)2. Hiển thị Start LineChọn một dòng nào đó của RAM đê làm dòng đầu tiên được hiên thị lên, nghĩa là “cuộn” hình ảnh trong RAM lên một khoảng LOffset, với LOffset có giá trị từ 0 đến 63. Phần bị che khuât khi cuộn sẽ được hiên thị tiếp ngay bên dưới. Ví dụ với LOffset = 20:

Page 107: Bai Giang Pic Rat Hay Va Day Du

Hình 15 5 Cuộn lên 20 dòngLập trình:• RS = 0• RW = 0• Opcode = 0xC0 + LOffset3. Thiết lập trang (địa chỉ X)Thiết lập địa chỉ X đê truy xuât RAM.Lập trình:• RS = 0• RW = 0• Opcode = 0xB8 + X4. Thiết lập địa chỉ YThiết lập địa chỉ Y đê truy xuât RAM.Lập trình:• RS = 0• RW = 0• Opcode = 0x40 + Y5. Đọc trạng tháiĐọc trạng thái của GLCD, chủ yếu kiêm tra bit BUSY (bit 7).Lập trình:• RS = 0• RW = 16. Ghi dữ liệu hiển thịGhi dữ liệu vào RAM tại địa chỉ X, Y. Sau khi ghi xong, giá trị Y sẽ tự động được tăng lên 1 đơn vị, chuyên sang cột tiếp theo hoặc trở về cột đầu tiên, tức Y = 0.Lập trình:• RS = 1• RW = 07. Đọc dữ liệu hiển thịĐọc dữ liệu từ RAM tại địa chỉ X, Y. Sau khi đọc xong, giá trị Y sẽ tự động được tăng lên 1 đơn vị, chuyên sang cột tiếp theo hoặc trở về cột đầu tiên, tức Y = 0.Lập trình:• RS = 1• RW = 1

14.2 Xây dựng chương trình14.2.1 Khởi tạo graphic LCDQuá trình khởi tạo được thực hiện như sau:

Khởi tạo các chân liên kết với glcd(thiết lập input/output). Chọn chip điều khiên thứ nhât. Thiết lập chân RS ở chế độ ghi lệnh. Gửi lệnh bât màn hình (0x3F). Gửi lệnh đê thiết lập địa chỉ Y (0x40 + Y). Gửi lệnh đê thiết lập địa chỉ X (địa chỉ trang) (0xB8 + X). Gửi lênh chọn dòng nào trong RAM đê hiên thị lên. Làm tương từ bước thứ 2 cho chip thứ 2.

Page 108: Bai Giang Pic Rat Hay Va Day Du

Tương ứng với từng lệnh trên trong chương trình như sau:Code:

glcd_write_byte(GLCD_ON_DISPLAY);glcd_write_byte(GLCD_SET_Y_ADDR);glcd_write_byte(GLCD_SET_PAGE);glcd_write_byte(GLCD_START_LINE);

Với các tham số truyền vào có giá trị như sau:Code:

#define GLCD_ON_DISPLAY 0x3F // DB0: turn display on#define GLCD_START_LINE 0xC0 // 11XXXXXX: set lcd start line#define GLCD_SET_PAGE 0xB8 // 10111XXX: set lcd page (X) address#define GLCD_SET_Y_ADDR 0x40 // 01YYYYYY: set lcd Y address

14.2.2 Ghi dữ liêu lên GLCDHàm ghi dữ liêu(một byte) có thê viết như sau:Code:

GLCD_CTRL_PORTbits.GLCD_CTRL_RW = 0;// chế độ ghi GLCD_DATA_PORT = abyte; // ghi dữ liệuGLCD_CTRL_PORTbits.GLCD_CTRL_E = 1;// sau khi ghi bật chân EN lên 1

để cho phép tín hiệu _nop();_nop();_nop();GLCD_CTRL_PORTbits.GLCD_CTRL_E = 0;// cho chân EN xuống 0 lại để

chuẩn bị cho lần thiết lập tiếp theo_nop();_nop();_nop();

Chi tiết cụ thê về quá trình xuât dữ liệu lên GLCD các bạn có thê tham khảo chương trình mâu kèm theo.14.3 DownloadCode mâu

Bài 19 : Giao tiếp SD Card bằng SPI

15.1 Giới thiệu tổng quan vê Sdcard15.1.1 Sơ lược về SD card

Page 109: Bai Giang Pic Rat Hay Va Day Du

Hình 18 18.1 Các loại SD CardSecure Digital (SD) Card là bộ nhớ flash tích hợp cao với khả năng truy xuât tuần tự và ngâu nhiên. Với tốc độ truyền nhận dữ liệu nhanh và ổn định, kích thước nhỏ gọn, khả năng lưu trữ cao từ 4MB đến 2GB, SD thích hợp cho các thiết bị kỹ thuật số cầm tay như máy nghe nhạc, điện thoại di động, PDA, máy quay phim, chụp ảnh…15.1.2 Sơ đồ khối của SD card

Hình 18 18.2 Sơ đô khối của SD Card15.1.3 Sơ đồ chân

Page 110: Bai Giang Pic Rat Hay Va Day Du

15.1.4 Các thanh ghi bên trong

15.1.5 Chuẩn giao tiếp với SD cardSD Card hỗ trợ 2 chế độ giao tiếp là chế độ SD Card và SPI. Host (hệ thống chủ - vi điều khiên) có thê chọn một trong hai chế độ này đê thực hiện giao tiếp với SD Card. Chế độ SD Card hỗ trợ 2 chế độ con là 1-bit và 4-bit, tốc độ truyền dữ liệu nhanh. Chế độ SPI tuy có tốc độ thâp hơn nhưng dễ sử dụng và được hỗ trợ trong hầu hết các hệ thống – vi điều khiên. Trong tài liệu này, chúng ta sẽ sử dụng SPI đê giao tiếp với SD Card.

15.2 Giới thiệu vê FAT15.2.1 Tổng quan FATFAT (File Allocation Table – Bảng câp phát tập tin) là kiến trúc hệ thống tập tin được sử dụng cho máy tính và hầu hết các loại thẻ nhớ. Được phát triên bởi Microsoft từ năm 1976. 

FAT quản lý bộ nhớ bằng cách chia nhỏ bộ nhớ (sector, cluster) và đánh dâu các khối nhỏ đó bằng các bit địa chỉ. Một sector chứa 512 byte bộ nhớ. Một cluster chứa nhiều sector. Số sector trong một cluster là cố định và do người dùng chọn lúc định dạng bộ nhớ. 

Ở chế độ mặc định một cluster chứa 8 sector. Khi lưu trữ một file, FAT câp phát một hoặc nhiều cluster có tổng kích thước không nhỏ hơn kích thước file đó. Ví dụ file có kích thước 5kB sẽ được câp phát 2 cluster (8 sector/cluster) đê lưu trữ. Nếu số sector trong mỗi cluster càng lớn sẽ gây nhiều lãng phí bộ nhớ, ngược lại nếu số này càng nhỏ thì hệ thống hoạt động càng chậm. 

Các phiên bản FAT là FAT12, FAT16, FAT32. Điêm khác nhau cơ bản giữa các phiên bản là về giới hạn quản lý bộ nhớ. FAT12 dùng 12 bit đê đánh dâu địa chỉ các cluster, nên có thê quản lý gần 212 cluster (trừ một số địa chỉ đê đánh dâu các vùng đặc biệt). Tương tự FAT16 dùng 16 bit, FAT32 dùng 28 bit đê đánh dâu địa chỉ.15.2.2 Cấu trúc phân vùng FAT

Page 111: Bai Giang Pic Rat Hay Va Day Du

Một hệ thống file FAT gôm 4 phần:

1. Reserved sectors: Nằm ở vị trí đầu tiên (sector 0) là Boot sector (tên đầy đủ là Partition Boot Record). Sector này chứa một vùng gọi là BIOS Parameter Block (với một số thông tin của hệ thống file, chi tiết về kiêu file, và con trỏ tới các phần khác) và thường chứa boot loader code của hệ điều hành. Tổng số Reverved sector cũng được lưu trong một trường của Boot sector. Những thông tin quan trọng của Boot sector một câu trúc gọi là Drive Parameter Block trong DOC và OS/2. Riêng FAT32 có thêm một File System Information Sector (sector 1) và một Backup Boot Sector (sector 6).

2. FAT Region: Gôm hai bảng, là bản đô của vùng Data Region, cho biết những cluster nào đã được dùng.

3. Root Directory Region: Đây là Directory Table, chứa thông tin về file và thư mục trong thư mục gốc (root directory), chỉ có trên FAT12 và FAT16.

4. Data Region: Đây là nơi thực sự file và thư mục được lưu trữ và chiếm hầu hết dung lượng của phân vùng ổ đĩa. FAT32 lây cluster đầu tiên của Data Region làm Root Directory Table.

15.2.3 Bảng cấp phát tập tinPhân vùng bộ nhớ được chia nhỏ thành những phần nhỏ kề nhau, có kích thước bằng nhau gọi là cluster. Kích thước của cluster thường từ 2kB đến 32kB, phụ thuộc vào kiêu FAT, kích thước phân vùng bộ nhớ và lựa chọn của người dùng. Mỗi file chiếm một hoặc nhiều cluster tùy thuộc vào kích thước của file đó; như vậy, một file được chứa bởi một dãy các cluster tạo thành một danh sách liên kết. Các cluster của một file không nhât thiết phải liền kề nhau, điều này thường gây ra tình trạng phân mảnh (fragmented). 

Bảng câp phát tập tin FAT là một danh sách các mục (entry) vẽ nên bản đô của từng cluster trên phân vùng ổ đĩa. Mỗi entry chứa các thông tin:

số của cluster tiếp theo trong dãy các cluster entry đánh kết thúc của dãy cluster (end of clusterchain – EOC) entry đặc biệt đánh dâu một cluster lỗi (bad cluster) entry đặc biệt đánh dâu cluster không dùng cờ zero đánh dâu cluster chưa dùng

Kích thước FAT entry khác nhau ở mỗi phiên bản. FAT12 và FAT16 dùng 12 và 16 bit cho mỗi entry. Trong FAT32, mỗi entry là 32 bit, nhưng thực sự chỉ dùng 28 bit, 4 bit cao dự trữ (không dùng, thường là 0).15.2.4 Directory tableMỗi file/directory (cũng hiêu là một folder) khi lưu trữ được biêu thị là một entry 32-byte trong bảng Directory Table. Mỗi entry ghi: tên, thuộc tính (attributes: archive, directory, hidden, read-only, system and volume), ngày tạo lập, địa chỉ của cluster dữ liệu đầu tiên, và kích thước của file/directory. Tât cả các Directory Table đều được chứa trong vùng Data Region (trừ ở FAT12 và FAT16, Root Directory Table chiếm một vùng riêng gọi là vùng Root Directory Region). Mô tả một Directory entry (cả Root Directory và subdirectory):

15.3 Giới thiệu bộ thư viện MDDSD card giao tiếp thông qua SPI, chúng ta có thê làm tât cả các bước từ câu hình SPI cho PIC, sau đó gửi lệnh từ vi điều khiên xuống SD card rôi chờ tín hiệu trả về, đọc master boot record, boot sector, đọc ghi FAT …Với cách làm này đòi hỏi bạn tốn nhiều thời gian hơn đê xây dựng các hàm API giao tiếp với SDcard nhưng bạn sẽ nắm được nhiều kiến thức hơn về SDcard. Ngoài ra còn một cách khác nữa đê làm là sử dụng thư viện các hàm có sẵn ở trên mạng đê sử dụng như vậy chúng ta sẽ tốn ít thời gian hơn cho việc viết các hàm giao tiếp thẻ nhớ và tập trung hơn vào xây dựng ứng dụng sử dụng SD card.

MDD là thư viện chứa các hàm và thiết lập đê giao tiếp với SD card,nằm trong bộ thư viện đầy đủ hỗ trợ các chức năng gôm SD card, mTouch, GraphicLCD, USB, audio… do Microchip cung câp và được đặt tên là Microchip solutions. Ở đây chúng tôi tập trung vào cách sử dụng thư viện MDD vào giao tiếp với SD card bằng SPI.15.3.1 Hướng dẫn sử dụng MDDĐây là một bộ thư viện của Microchip cung câp có thê chạy trên các dòng PIC 8 bit (PIC18F), PIC 16bit (PIC24F, PIC24H, dsPIC30) và PIC 32bit (dsPIC33) nên thư viện cũng khá lớn, đòi hỏi bộ chương trình của vi điều khiên sử dụng cũng phải nhiều, cụ thê nếu sử dụng thư viện và chỉ có thê đọc file từ SDcard thì cần gần 22000 bytes bộ nhớ chương trình đê lưu trữ(chứ tính không gian lưu

Page 112: Bai Giang Pic Rat Hay Va Day Du

trữ cho code chương trình ứng dụng tự viết) và đê sử dụng toàn bộ chức năng của thư viện (có thê đọc ghi file, format thẻ nhớ, tìm kiếm file, tạo xóa quản lý thư mục, sử dụng các hàm mở rộng pgm, sử dụng được hàm Fsfprintf, hỗ trợ thẻ nhớ định dạng FAT32) thì cần gần 35000 bytes bộ nhớ chương trình. Đó là thông tin do Microchip cung câp nhưng thực thế sử dụng thì với vi điều khiên chỉ có 32KB bộ nhớ chương trình thì hoàn toàn không thế sử dụng được bộ thư viện(trừ chế độ chỉ đọc file) mà vi điều khiên PIC18F4520 chỉ có 32KB bộ nhớ chương trình nên chúng tôi chọn một chip khác cùng dòng với vi điều khiên là vi điều khiên PIC18F4620 với bộ nhớ chương trình là 64KB, nhưng vân còn một vài chức năng phụ mà chúng tôi đã bỏ không sử dụng đê thu gọn chương trình sau khi biên dịch, nên nếu bạn muốn sử dụng toàn bộ chức năng của thư viện thì nên chọn vi điều khiên có bộ nhớ chương trình 96KB trở lên.

Hình 18-3 Chi tiết sử dụng bộ nhớ chương trình cho thư viện MDD

Hình 18-4 Các tính năng được lựa chọn của thư viện

Muốn bỏ bớt chức năng nào của thư viện chúng ta cần phải tìm và khóa tât cả các dòng code define cho tính năng đó(vd #ifdef ALLOWS_DIRS … #endif).Bước 1: Tạo 1 project mới, sau đó vào trang của Microchip download xuống thư viện Microchip Solutions(hoặc có sẵn trong đĩa CD kèm theo) , trong đó bao gôm luôn cả thư viện MDD. Vào thư mục Microchip Solutions chép thư mục MDD File System và thư mục Microchip vào thư mục chứa project. Sau đó vào thư mục MDD File System xóa hết những file không cần thiết trừ thư mục PIC18F, tương tự trong thư mục Microchip chúng ta chỉ đê lại thư mục PIC18 salloc và thư mục Include, trong thư mục Include chúng ta cũng xóa hết và chỉ đê lại những file .h ở trong thư mục này và thư mục PIC18 salloc,MDD File System. Tiếp theo chúng ta include những file sau vào project với đường dân ./ là thư mục mà chứa project.

.\Microchip\MDD File System\FSIO.c .\Microchip\MDD File System\SD-SPI.c

Page 113: Bai Giang Pic Rat Hay Va Day Du

.\Microchip\PIC18 salloc\salloc.c .\MDD File System-SD Card\PIC18F\Fsconfig.h .\MDD File System-SD Card\PIC18F\HardwareProfile.h .\Microchip\Include\MDD File System\FSIO.h .\Microchip\Include\MDD File System\SD-SPI.h .\Microchip\Include\MDD File System\FSDefs.h .\Microchip\Include\PIC18 salloc\salloc.h .\Microchip\Include\Compiler.h .\Microchip\Include\GenericTypeDefs.h

Hình 18-5 Project sau khi thêm các file headerFile tmp.c là file chứa hàm main do chúng ta tự viết.Sau đó vào tab Project →Build Options → Project, chọn Include Search Path, chọn New sau đó thêm vào các đường dân như trên.

Page 114: Bai Giang Pic Rat Hay Va Day Du

Hình 18-6 Thêm đường dân cho project

Bước 2: Thiết lập buffer đọc và ghi, buffer cho FATMở file linker tương ứng với vi điều khiên PIC đang sử dụng(ở đây là file 18f4620.lkr ), rôi chỉnh sửa lại với nội dung như sau

Page 115: Bai Giang Pic Rat Hay Va Day Du

Hình 18-7 Chỉnh sửa file linker cho project

Bước 3: Thiết lập bộ nhớ cache và xung clockThiết lập bộ nhớ cacheTrong file Fsconfig.h đã câu hình sẵn bộ nhớ cache sử dụng là 512bytes thông qua câu lệnh định nghĩaCode:

#define MEDIA_SECTOR_SIZE 512

Nếu bạn muốn thay đổi bộ nhớ của cache thì chỉ cần chỉnh sửa trong câu lệnh này nhưng nhớ là bộ nhớ cache là bội số của 512.Ngoài ra còn một số thiết lập chức năng khác như bật/tắt chức năng ghi, tìm file… đều có trong file FSconfig.h các bạn có thê tự đọc đê tìm hiêu thêm.Thiết lập xung clockĐê câu hình xung clock bạn mở file HardwareProfile.h tìm đến dòng lệnh define sauCode:

#define GetSystemClock() 20000000 // System clock frequency (Hz)

Ở đây vi điều khiên đang được câu hình sử dụng xung tần số 20MHz, và tùy vào nhu cầu sử dụng các bạn có thê thay đổi con số này.Bước 4: Thiết lập các chân giao tiếp và các thanh ghi của chế độ SPITrong thư viện này của Microchip chỉ hỗ trợ cho một số con PIC18F (PIC18F87J50, PIC18F8722, PIC18F46J50), toàn bộ PIC24F,PIC32F và dsPIC.Cho nên đê sử dụng cho những con PIC khác(ví dụ là PIC18F4620) thì cần phải chỉnh sửa thêm một số file sau.

Page 116: Bai Giang Pic Rat Hay Va Day Du

Trong file HardwareProfile.h bạn thêm vào ở trong mục define dành cho PIC18F những dòng định nghĩa sauCode:

#elif defined PIC18F4520_PIM #define USE_PIC18 #define USE_SD_INTERFACE_WITH_SPI #define INPUT_PIN 1 #define OUTPUT_PIN 0

#define USE_SD_INTERFACE_WITH_SPI #define TRIS_CARD_DETECT TRISBbits.TRISB4 // Input #define CARD_DETECT PORTBbits.RB4 #define TRIS_WRITE_DETECT TRISDbits.TRISD7 // Input #define WRITE_DETECT PORTDbits.RD7 // Chip Select Signal #define SD_CS PORTAbits.RA5 #define SD_CS_TRIS TRISAbits.TRISA5 // Card detect signal #define SD_CD PORTBbits.RB4 #define SD_CD_TRIS TRISBbits.TRISB4 // Write protect signal #define SD_WE PORTDbits.RD7 #define SD_WE_TRIS TRISDbits.TRISD7 // TRIS pins for the SCK/SDI/SDO lines #define SPICLOCK TRISCbits.TRISC3 #define SPIIN TRISCbits.TRISC4 #define SPIOUT TRISCbits.TRISC5 // Latch pins for SCK/SDI/SDO lines #define SPICLOCKLAT LATCbits.LATC3 #define SPIINLAT LATCbits.LATC4 #define SPIOUTLAT LATCbits.LATC5 // Port pins for SCK/SDI/SDO lines #define SPICLOCKPORT PORTCbits.RC3 #define SPIINPORT PORTCbits.RC4 #define SPIOUTPORT PORTCbits.RC5 // Registers for the SPI module you want to use #define SPICON1 SSPCON1 #define SPISTAT SSPSTAT #define SPIBUF SSPBUF #define SPISTAT_RBF SSPSTATbits.BF #define SPICON1bits SSPCON1bits #define SPISTATbits SSPSTATbits #define SPI_INTERRUPT_FLAG PIR1bits.SSPIF #define SPIENABLE SSPCON1bits.SSPEN // Will generate an error if the clock speed is too low to interface to the card #if (GetSystemClock() < 400000) #error System clock speed must exceed 400 kHz #endif

Page 117: Bai Giang Pic Rat Hay Va Day Du

Và trước đó bạn cần phải định nghĩa các nhãn PIC18F4520_PIM bằng cách ở phần định nghĩa nhãn cho các con PIC khác bạn thêm vào đoạn code sauCode:

#elif defined(__18F4620)#define DEMO_BOARD PIC18F4620_PIM#define PIC18F4620_PIM

Bước 5: Câu hình bộ nhớTrong MPLAB IDE, chọn Project → Build Options → Project, chọn thẻ MPLAB C18 rôi chọn Memory Model trong Categories và thiết lập như sau:

Code model : Small code model Data model : Large code model Stack model : Multibank model

Hình 18-8 Câu hình Memory ModelCác bước thiết lập đê sử dụng đã hoàn tât, bây giờ các bạn có thê tạo 1 file source của mình và sử dụng các hàm có sẵn trong thư viện đê giao tiếp với SDcard.

Page 118: Bai Giang Pic Rat Hay Va Day Du

Hình 18-9 Chương trình mâu15.3.2 Các hàm trong thư viện

FSInit Initializes the card,loads the master boot record(partition information),loads the boot sector and updates the parameters passed into it with its information

FSfclose Updates the file information, writes the remaining entry in and frees the RAM from the heap that was used to hold the information about the file.This also updates the time-stamp information for thr file.

FSfeof Verifies if the end of the file has been reached FSfopen Allocates space in the heap for file information.If the file being opened already exist,

Fsfopen can open it so that the data would be appended at the end of the line, erase it and create a new file qith the same name to be written to,or simply open it for reading.If the file does nont exist, Fsfopen can creat it. This function then returns a pointer to the tructure in the heap that contains information for this file

FSfread Reads information from an open file to a buffer. The number of bytes written can be specified by its parameters. If Fsfread is called consecutively on the same open file, the read will continue from the place it stopped after the previous read. This function returns the number of data objects read

Fsfseek Changes the position in a file. When a user calls FSfseek, they specify the base address to set, which can either be at the beginning or end of the file, or at the current position in the file. The user also specifies an offset to add to the base (note that if the base address is at the end of the file, the offset will be subtracted). Hence, if FSfseek is called with the base set to the beginning of the file and a specified offset of ë0í, the position would be changed to the first byte of the file.

Fsftell Returns the current position in the file. The first position in the file is the first byte in the first sector of the first cluster, which has the value ë0í. Hence, if a file was created and 2000 bytes were written to it, FSftell would return the number 1999 if it was called.

Fsfwrite Writes information from a buffer to an open file. The algorithm it uses reads a sector from the data region of the disk to SRAM, modifies the relevant bytes and then writes the sector back to the disk. Because each FSfwrite call reads the data first, the ability to open multiple files at a time is supported. This also means that writing data in larger blocks takes less time than writing the same data in smaller blocks as fewer sector reads and writes will be needed.

Page 119: Bai Giang Pic Rat Hay Va Day Du

Fsremove Searches for a file based on a filename parameter passed into it. If the file is found, its directory entry is marked as deleted and its FAT entry is erased.

Fsremovepgm Deletes the file identified by a given filename. If the file is opened with FSfopen, it must be closed before calling FSremovepgm. The filename must be specified in ROM. This function is necessary only on the PIC18 architecture.

Fsfopenpgm Opens a file on the SD card and associates an FSFILE structure (stream) with it using arguments specified in ROM. This function is necessary only on the PIC18 architecture.

FSrename Changes the name of a file or directory. If the pointer passed into this function is NULL, the name of the current working directory will be changed.

Fsrewind Resets the position of the file to the beginning of the file. Fsmkdir Creates a new subdirectory in the current working directory. Fschdir Changes the current working directory to the one specified by the user. FSrmdir Deletes the specified directory. The user may also choose to specify whether

subdirectories and files contained within the deleted directory are removed. If the user does not permit the function to delete subdirectories, it fails if the user attempts to delete a non-empty directory.

Fsgetcwd Returns the name of the current working directory to the user. FindFirst Locates files in the current working directory that meet the name and attribute

criteria. A SearchRec Structure Pointer will be passed into the function. Once a file is located, the file-name, file size, create time and date stamp, and attributes fields in the SearchRec structure will be updated with the correct file information.

FindFirstpgm Operates in the same manner as the FindFirst function, except the name criteria for the file to be found will be passed into the function in ROM. This function is necessary only on the PIC18 architecture.

FindNext Locates the next file in the current working directory that matches the criteria specified in the last call of FindFirst or FindFirstpgm. It will then update the SearchRec structure provided by the user with the file information.

Fsformat Erases the root directory and file allocation table of a card. The user may also call the function in a mode that causes it to create a new boot sector based on the information in the master boot record.

Fsfprintf Writes a formatted string to a file. It automatically replaces any format specifiers in the string with dynamic values from variables passed into the function. Integer promotion must be enabled in the build options menu when using this function with the PIC18 architecture.

SetClockVars Used in user-defined Clock mode to manually set the current date and time. This date and time would be applied to files as they are created or modified.

15.4 Xây dựng chương trình15.4.1 Kết nối phần cứng

Hình 18-10 Sơ đô kết nối SDcardVì SDcard hoạt động ở điện áp 3V3 mà tín hiệu ra của vi điều khiên là 5V nên các chân SDI,SDO,SS,SCK được gắn thông qua các điện trở đê chia áp xuống 3V3 cho phù hợp với giao tiếp SDcard.15.4.2 Chương trình mẫuCode:

1 #include <p18f4520.h>2 #include <FSIO.H>

3 void blocking(void)4 {5 while (1);6 }

7 void main(void)8 {9 FSFILE *file1;10 unsigned char txt[] = "Giao tiep SDcard!!";11 while (!MDD_MediaDetect());

Page 120: Bai Giang Pic Rat Hay Va Day Du

12 while(!FSInit());13 file1 = FSfopenpgm("file_test_1.txt","w+");14 if (file1 == NULL)15 blocking();16 if (FSfwrite((void*)txt,1,18,file1) != 18)17 blocking();18 if (FSfclose(file1) != 0)19 blocking();20 while (1);21 }

Giải thích các lệnh:

Dòng 2: include file header chính của thư viện. Dòng 3→6: tạo hàm blocking hệ thống nếu có lỗi. Dòng 9: khai báo con trỏ sẽ trỏ đến file cần xử lý. Dòng 10: khai báo chuỗi sẽ được ghi vào file. Dòng 11: đợi tín hiệu báo có thẻ nhớ thông qua chân card dectec. Dòng 12: khởi tạo thẻ nhớ đê bắt đầu giao tiếp với thẻ nhớ. Dòng 13: khởi tạo cho file, đặt tên file , truyền vào đối số cho phép ghi lên file. Dòng 14→15: kiêm tra có khởi tạo được file hay không. Dòng 16→17: ghi chuỗi vào file. Dòng 18→19: đóng file

Hình 18-11 Kết quả của chương trình15.5 Download

Code mâu