PHẦN MỀM KEIL C

PHẦN I GIỚI THIỆU PHẦN MỀM KEIL C

   Kiến thức về VĐK sẽ rất hữu ích trong vấn đề sửa chữa xe nâng điện, khi quý khách có nhu cầu sửa chữa, phụ tùng, hay thuê xe nâng hãy liên hệ với chúng tôi.

    Hiện nay có khá nhiều trình biên dịch ngôn ngữ C cho 8051 như Mikro C, IAR, SDCC, Reads 51 … µVision là môi trường phát triển tích hợp (IDE: Integrated Development Environment)  (trình soạn thảo ngôn ngữ C, trình biên dịch và debug) của công ty Keil Software, và thường được gọi là Keil C.

   Keil C là môi trường phát triển khá mạnh và được sử dụng rộng rãi hiện nay. Nó hỗ trợ ta viết chương trình cho các chip vi điều khiển lõi 8051 và ARM của tất cả các hãng trên thế giới

1.1.     Màn hình làm việc của Keil C

Màn hình làm việc của Keil C bao gồm các thanh công cụ ở phía trên cùng và 3 vùng chính như trong hình 1.1

Vùng 1: Là vị trí của các cửa sổ Project, cho phép ta quản lý các tập tin trong dự án, và cửa sổ Function, cho phép ta quản lý các chương trình con.

Vùng 2: Vùng soạn thảo. Đây là nơi ta sẽ soạn thảo chương trình.

Vùng 3: Cửa sổ Build Output. Hiển thị các thông tin trong quá trình biên dịch chương trình

1.2.     Các bước tạo một dự án mới

Bước 1: Để thuận tiện trong việc quản lý các dự án, ta nên tạo từng thư mục riêng cho mỗi dự án, với tên thư mục là tên dự án kèm theo ngày lập dự án đó. Kèm theo đó, ta nên thêm một file text, có nội dung ghi lại những thay đổi của dự án, vào thư mục của dự án đó.

Bước 2: Vào menu Project\New uVision Project để tạo project mới. Nhập đường dẫn và tên project vào hộp thoại. Nhấn OK.

Bước 3: Chọn loại vi điều khiển cần sử dụng trong hộp thoại Select device … (Hình 1.2). Nhấn OK. Sau đó, chọn Yes trong hộp thoại “Copy Standard 8051 …” xuất hiện tiếp theo.

Bước 4: Tạo một file mới : File\New và lưu lại với định dạng *.c hoặc *.h.

Bước 5: Add file vừa tạo vào project:

• Right click vào mục Source Group 1 và chọn Add file to Group ‘Source Group 1’ … (hình 1.3)

  • Chọn file vừa tạo. Nhấn Add rồi nhấn Close. Lúc này, trong cửa sổ Project, ở phía trái màn hình, sẽ xuất hiện thêm tập tin mà ta vừa add.

Bước 6: Thiết lập cho Keil C xuất ra file .hex, ta mở hộp thoại Option for Group 1 (Hình 1.4). Click chọn vào checkbox Create HEX file trong tab Output (Hình 1.5). Nhấn OK

Đến đây, ta đã hoàn tất các bước thiết lập cho một dự án mới. Các bước trên chỉ cần thực hiện một lần khi tạo dự án mới.

                

                      

1.3.     Debug chương trình

Sau khi soạn thảo chương trình xong, ta biên dịch chương trình bằng cách vào menu Project\Build  target hoặc nhấn nút Build trên thanh công cụ (hình 1.6) hoặc ta cũng có thể nhấn phím F7

Sau khi chương trình tiến hành biên dịch chương trình, nếu không có lỗi xảy ra, ta sẽ nhận được thông báo 0 Error(s), 0 Warning(s) trong cửa sổ Buid Output sau khi quá trình biên dịch hoàn tất (hình 1.7)

Trong quá trình phát triển một chương trình, sẽ có hai loại lỗi có thể xảy ra:

  • Lỗi cú pháp (Syntax error): Lỗi này là các sai sót trong cấu trúc câu lệnh như thiếu tham số, sai từ khóa … Các lỗi này sẽ được trình biên dịch tự động phát hiện trong quá trình biên dịch.
  • Lỗi luận lý (Lỗi Logic): Lỗi này là các sai sót trong giải thuật chương trình, làm cho chương trình chạy không đúng ý đồ ban đầu của lập trình viên. Lỗi này chỉ có thể do chính lập trình viên phát hiện và sửa chữa. Các IDE không thể trực tiếp phát hiện các lỗi logic, nó chỉ cung cấp cho người dùng các công cụ hỗ trợ cho quá trình phát hiện và sửa chữa loại lỗi này.

Keil C ngoài việc hỗ trợ ta soạn thảo và biên dịch chương trình, nó còn hỗ trợ ta một công cụ gỡ rối (Debug) chương trình hết sức hiệu quả.

Để chạy debug một chương trình sau khi đã biên dịch thành công, ta nhấn có thể kích hoạt chức năng debug bằng một trong các cách sau:

  • Nhấn nút Debug trên thanh công cụ (Hình 1.8)
  • Nhấn tổ hợp phím Ctrl + F5.

• Mở menu Debug-Start/Stop Debug Session

Muốn tắt chức năng Debug, ta làm lại thao tác trên một lần nữa.

Sau khi kích hoạt chức năng Debug, cửa sổ Keil C có dạng như hình 1.9. Nếu có cửa sổ nào không xuất hiện, ta có thể vào menu View để bật cửa sổ đó lên.

Trong cửa sổ này, có 4 vùng chính:

  • 1: Cửa sổ thể hiện các thanh ghi của vi điều khiển
  • 2: Cửa sổ lệnh soạn thảo, chứa chương trình đang được debug
  • 3: Cho phép ta theo dõi giá trị của một biến nào đó bằng cách nhập tên biến
  • 4: Cửa sổ Watches cho phép ta theo dõi giá trị của tất cả các biến chứa trong chương trình. Muốn biết giá trị của biến nào, ta chọn cửa sổ này và nhấn phím F2, sau đó nhập tên của biến cần theo dõi. Lúc này, của sổ sẽ hiển thị tên biến cũng như giá trị hiện tại của biến đó.

Ngoài ra, ta còn có thể kích hoạt thêm một số cửa sổ như:

  • Cửa sổ Disassembly (Hình 1.10) : Cho ta biết chính xác một lệnh Keil C được viết bằng hợp ngữ như thế nào. Kích hoạt cửa sổ này bằng cách vào menu View/Disassembly.
  • Cửa sổ Memory (Hình 1.11): Kích hoạt bằng menu View/Memory. Cho phép xem nội dung bộ nhớ chương trình và bộ nhớ dữ liệu:
    • Muốn xem bộ nhớ chương trình bắt đầu từ một địa chỉ nào đó, ta nhập C: Địa chỉ vào ô Address.
    • Muốn xem bộ nhớ RAM bắt đầu từ một địa chỉ nào đó, ta nhập D: Địa chỉ vào ô
  • Cửa sổ Registers: Cho phép ta quan sát giá trị các thanh ghi của vi điều khiển như các thanh ghi R0-R7, PSW, DPTR …

 

 Ta có thể biết được một đoạn chương trình đã thực hiện mất bao nhiêu thời gian bằng cách quan sát mục sec trong cửa sổ Registers hoặc trên thanh status bar (Hình 1.12). Tuy nhiên, để có thời gian tương ứng chương trình debug và trên mạch thực tế, ta phải thực hiện một số bước hiệu chỉnh như sau:

  • Mở hộp thoại Options for Target (Hình 1.4)
  • Chọn thẻ Target.
  • Nhập tần số thạch anh mà ta muốn sử dụng trên mạch thực tế vào ô Xtal (MHz) (Hình 1.13)

Tiện ích cho phép quan sát thời gian chạy chương trình này cho phép ta xác định chính xác thời gian của một hàm delay mà ta định sử dụng, và nó cũng giúp ích cho chúng ta khi lập trình với những bài toán có liên quan đến thời gian thực, để chúng ta có thể tìm ra được một giải thuật ngắn nhất và nhanh nhất.

Ta cũng có thể quan sát trạng thái các Port, các Timer, ngắt bằng cách vào menu Peripherals, chọn các đối tượng cần quan sát (Hình 1.14).

Keil C cũng hỗ trợ ta quan sát các ngõ ra dưới dạng xung. Để kích hoạt chức năng này, chúng ta chọn biểu tượng Analysis Window (Hình 1.15). Tiếp theo chúng ta chọn mục Setup > cửa sổ Setup Logic Analyzer xuất hiện > chọn mục New (Insert) và nhập Port cần quan sát (VD: P0.0, P1.2…). Ngoài ra ta có thể chọn màu hiển thị tại mục Color. Sau khi đã thiết đặt đầy đủ các chân cũng như màu sắc, ta chọn Close để kết thúc phần Setup. Khi không cần quan sát một tín hiệu nào đó, ta có thể chọn tín hiệu đó trong hộp thoại Setup này và nhấn nút Delete, hoặc nhấn nút Kill All để loại bỏ tất cả tín hiệu đã được chọn trước đó.

 

 

Sau khi đã kích hoạt đầy đủ các cửa sổ cần thiết, ta bắt đầu cho chạy debug bằng cách chọn một trong các nút trên thanh công cụ Debug (Hình 1.17):

  • Nút Reset: Reset chương trình về trạng thái ban đầu
  • Run (F5): Thực thi chương trình
  • Step (F11): Thực thi từng dòng lệnh, có nhảy vào hàm con.
  • Step over (F10): thực thi từng dòng lệnh, không nhảy vào hàm con.
  • Step out (Ctrl + F11): Nhảy ra khỏi hàm con
  • Run to Cursor line (Ctrl + F10): Thực thi chương trình từ đầu cho đến vị trí con trỏ

PHẦN II GIỚI THIỆU THIẾT BỊ

2.1.     SƠ ĐỒ NGUYÊN LÝ KIT NGHIỆM

2.2.     CÁC KHỐI CHỨC NĂNG TRÊN KIT THÍ NGHIỆM

2.2.1. Khối nguồn

Khối này nhận điện áp 12Vac, nắn, lọc thành điện một chiều. Sau đó đưa qua 7805 để ổn định điện áp ngõ ra ở 5Vdc. Điện áp này được cung cấp cho các khối khác trên kit.

2.2.2. Khối nạp chương trình :

 

Đây là sơ đồ mạch nạp đi kèm với phần mền SPI Programmer 3.7 ,cho phép ta nạp chương trình cho các chip 89Sxx của hãng Atmel. Chương trình được nạp nối tiếp thông qua các chân MOSI, MISO, SCK và RESET của chip.

             

2.2.3. Khối MCU :

Khối này bao gồm vi điều khiển AT89S52 và các khối phụ trợ, giúp cho vi điều khiển hoạt động được:

  • Khối Auto Reset bao gồm R28, C3: giúp tự động reset vi điều khiển khi vừa bật nguồn.
  • Khối Manual Reset bao gồm SW1, R27: cho phép reset vi điều khiển bằng tay. Khối này không bắt buộc phải có mặt nếu không có nhu cầu reset vi điều khiển bằng tay.
  • Khối dao động bao gồm: Y1, C4, C5: Kết hợp với các khối khác ở bên trong vi điều khiển tạo ra xung nhịp cho vi điều khiển hoạt động.
  • Điện trở kéo lên R18: Do các chân trên port 0 của vi điều khiển là các chân có cực thu để hở nên khi muốn giao tiếp vi điều khiển với các IC số khác, ta cần có một điện trở kéo lên để xác lập mức điện áp.

2.2.4. Khối led đơn

 

Các ngõ điều khiển được kết nối trực tiếp với port 1 của vi điều khiển. Muốn led sáng, ta sẽ phải xuất mức thấp ra chân vi điều khiển.

2.2.5. Khối led 7 đoạn

Khối này bao gồm bốn led 7 đoạn được thiết kế theo phương pháp đa hợp (phương pháp điều khiển quét led). Tất cả các đoạn (kathod) của các LED được nối chung vào nhau vào một port điều khiển còn anode của tất các led được nối vào một port điều khiển khác và được cấp tín hiệu quét led một các tuần tự (tại một thời điểm chỉ có một led được cấp nguồn). Lưu đồ giải thuật quét led được thể hiện trong hình 2.7, trong đó N_max là tổng số led 7 đoạn cần được quét.

             

 

2.2.6. Khối hiển thị LCD

LCD được thiết kế trên kit là loại LCD 2 dòng, 16 cột. Module này được thiết kế cho mục đích thí nghiệm điều khiển LCD. J5 là ngõ vào nhận dữ liệu (DATA) hoặc lệnh (COMMAND) của LCD. J6 là ngõ vào điều khiển LCD

2.2.7. Khối nút nhấn

Khối này được thiết kế cho các bài thí nghiệm nút nhấn đơn. Bao gồm ba nút được kết nối vào các chân P2.0,P2.1,P2.2 và tích cực ở mức thấp

             

2.2.8. Khối Standby LED/Interrupt input

Stand_by LED được kết nối vào chân P3.3, đồng thời đây cũng là ngõ vào ngắt ngoài 1 và tích cực ở mức thấp.

2.2.9. Khối thu hồng ngoại

 

Ngõ ra của bộ thu tín hiệu hồng ngoại được kết nối vào chân P3.2. Tín hiệu hồng ngoại từ Remote khi qua bộ thu sẽ bị đảo mức tích cực .

2.2.10. Khối Buzzer

Buzzer là một loa nhỏ, dùng để tạo âm thanh. Trong kit thí nghiệm này, buzzer được điều khiển thông qua transistor A1013 và được kết nối vào chân P3.4.

2.2.11. Khối Opto Triac

Khối Opto Triac dùng để điều khiển thiết bị 220V AC bên ngoài thông qua mạch mở rộng, chân điều khiển được kết nối vào chân P3.5 và tích cực ở mức thấp.

2.2.12. Khối giao tiếp UART

Khối giao tiếp UART dùng để giao tiếp nối tiếp với các thiết bị ngoại vi hoặc với các MCU khác thông qua port nối tiếp (TxD, RxD) hoặc kết nối thêm mạch ngoài để giao tiếp theo chuẩn RS232.

             

 

PHẦN III THỰC HÀNH

 

3.1.  ĐIỀU KHIỂN KHỐI LED ĐƠN

3.1.1. Mục đích, yêu cầu:

Giúp cho sinh viên làm quen với việc điều khiển LED đơn như tắt, mở, dịch LED sang trái, dịch LED sang phải, sáng dồn, nhấp nháy.

Sinh viên phải biết sử dụng Timer để tạo Delay và biết cách sử dụng các toán tử liên quan như toán tử thao tác bit, toán tử logic …

3.1.2. Chương trình tham khảo

#include <p89v51rx2.h>

// khai bao prototype void delay (unsigned int time); void nhap_nhay (void); void dem_nhi_phan (void); void dich_trai (void);

//chuong trinh chinh void main (void)

{

                     while (1)

                     {

                          nhap_nhay();        

                          delay(500);      

                          dem_nhi_phan();     

                          delay(500);      

                          dich_trai(); 

                          delay(500);

                     }

}

//cac chuong trinh con

void nhap_nhay (void)

     {

                     unsigned char i;

                     for (i = 0; i < 10; i ++)

                            {

                               P1 = 0;      

                               delay (500);      

                               P1 = 0xff;

                               delay (500);

                           }

      } 

void dem_nhi_phan (void)

     {   

       unsigned char i;

       for (i = 0; i < 255; i ++)

             {

                P1 = ~i;          

                delay (300);

              }

      } 

void dich_trai (void)

     {

        unsigned char i, j;

        for (j = 0; j < 5; j ++)

              {

                   for (i = 0x01; i > 0; i <<= 1)

                          {

                              P1 = ~i;             delay (300);

                          }

               }

       } 

void delay (unsigned int time)

       {    while (time–)

                     {

                          TMOD = 0x01; //timer0 che do 16 bit

                          TH0 = 0xFF; //nap gia tri cho timer

                          TL0 = 0x00;

                          TR0 = 1; //khoi dong bo dinh thoi  

                          while (!TF0); //cho co TF = 1   TF0 = 0 ; //xoa co TF

                          TR0 = 0; //dung bo dinh thoi

                     }

         }                

3.1.3. Bài tập mở rộng

  1. Viết chương trình dịch một led qua phải
  2. Viết chương trình 8 led sáng dồn.
  3. Sử dụng ngắt timer để viết chương trình điều khiển sao cho 8 LED đơn mỗi LED chớp với một tần số khác nhau.

3.2.ĐIỀU KHIỂN KHỐI BUZZER 

3.2.1. Mục đích, yêu cầu

Giúp sinh viên làm quen với việc điều khiển Buzzer để tạo ra chuỗi âm “beep” với các tần số khác nhau cho các ứng dụng như nhận phím, báo thức …

3.2.2. Chương trình tham khảo

#include <p89v51rx.h>

#define BUZZER P3_4 //khai bao chan dieu khien Buzzer

// khai bao prototype

void delay (unsigned int time); void beep (void);

//chuong trinh chinh

void main (void)

       { 

           while (1)

                     {

                          beep();

                          delay (1000);

                     }

        }

// cac chuong trinh con

void beep (void)

      {

           unsigned char i;

           for (i = 0; i < 20; i ++)

                  {

                      BUZZER = 0;       delay (1);

                      BUZZER = 1;  delay (1);

                  }

         } 

void delay(unsigned int time)

        {   

            while(time–)

                     {

                          TMOD = 0x01;

                          TH0 = 0xFF;

                          TL0 = 0xBA;  

                          TR0 = 1;  

                          while(!TF0);  

                          TF0 = 0 ;

                          TR0 = 0;

                      }

          }

3.2.3. Bài tập mở rộng

  1. Viết chương trình điều khiển Buzzer phát âm thanh cho đồng hồ báo thức.
  2. Viết chương trình điều khiển Buzzer giả lập âm thanh của còi xe cứu hỏa

3.3. GIAO TIẾP VỚI NÚT NHẤN ĐƠN

3.3.1. Mục đích, yêu cầu

Giúp sinh viên làm quen với thao  tác kiểm tra nút nhấn đơn trong các ứng dụng nhập dữ liệu, hiệu chỉnh thông số,cài đặt …  

3.3.2. Chương trình tham khảo

Chương trình kiểm tra lần lượt ba nút UP, MODE, DOWN, nếu một trong ba nút được nhấn thì điều khiển phát âm “beep” để thông báo phím đã được nhấn, đồng điều khiển tắt hoặc mở LED tương ứng.

#include <p89v51rx2.h>

//khai bao cac chan dieu khien

#define BTN_UP P2_2
#define BTN_DOWN P2_0
#define BTN_MODE

 

P2_1
#define LED0  P1_0
#define LED1  P1_1
#define LED2 

 

P1_2
#define BUZZER P3_4 //chan dieu khien Buzzer

 

// khai bao prototype void delay (unsigned char time); void beep (void);

//chuong trinh chinh

void main (void)

{

while (1)
{
if (BTN_UP == 0)
{
     delay (200); //delay chong doi
     if (BTN_UP == 0)
     {
          beep();
 UP             while (BTN_UP == 0); //cho nha nut
          LED0 = ~LED0;
     }
 

 

}
    if (!BTN_DOWN)
{
     delay (200); //delay chong doi
     if (!BTN_DOWN)
     {
          beep();
 DOWN               while (!BTN_DOWN); //cho nha nut
          LED1 = ~LED1;
     }
 

 

}
    if (!BTN_MODE)
{
     delay (200); //delay chong doi
     if (!BTN_MODE)
     {
          beep();
 MODE               while (!BTN_MODE); //cho nha nut
          LED2 = ~LED2;
     }
}

}

}

//cac chuong trinh con

void beep (void)

       {

            unsigned char i;

             for (i = 0; i < 20; i ++)

                   {

                      BUZZER = 0;      

                      delay (1);         

                      BUZZER = 1;

                      delay (1);

                   }

          } 

void delay(unsigned char time)

         {

              while (time–)

                     {

                          TMOD = 0x01; //timer0 che do 16 bit

                          TH0 = 0xFF; //nap gia tri cho timer

                          TL0 = 0xBA;

                          TR0 = 1; //khoi dong bo dinh thoi  

                          while(!TF0); //cho co TF = 1

                          TF0 = 0 ; //xoa co TF

                          TR0 = 0; //dung bo dinh thoi

                     }

          }

3.3.3. Bài tập mở rộng

Viết chương trình điều khiển sao cho nếu nút Up nhấn 8 LED đơn sẽ dịch từ trái sang phải, nút Down nhấn dịch từ phải sang trái, nút Mode nhấn thì nhấp nháy cả 8 LED, mỗi kiểu sáng lập lại 5 lần. Sau đó chương trình trở lại kiểm tra 3 nút như ban đầu.

3.4. ĐIỀU KHIỂN KHỐI HIỂN THỊ LED 7 ĐOẠN

3.4.1. Mục đích, yêu cầu

Giúp sinh viên làm quen với việc điều khiển hiển thị dữ liệu trên LED 7 đoạn trong các ứng dụng như đếm sản phẩm, đèn giao thông, đồng hồ báo giờ…

Sinh viên phải nắm được kỹ thuật quét LED, kỹ thuật sử dụng ngắt timer, biết cách kết nối phần cứng (kết nối header Data LED / D0 … D7 (P0), LCD control / LED control ở khối MCU với header Data LED và LED control ở khối hiển thị LED 7 đoạn ).

3.4.2. Chương trình tham khảo

Chương trình sau đếm từ 0 – 100 hiển thị ra led 7 đoạn

#include <at89x52.h>

#define BTN_PRESSED  1

#define BTN_NOT_PRESSED 0

#define btnUp        P2_0
#define btnDown        P2_1
#define buzz        

 

P3_4
#define ledUnits  P2_3
#define ledTens        P2_4
#define ledHundress       P2_5

 

unsigned char code code_7seg [] = {0x81, 0xed, 0x43,

0x49, 0x2d, 0x19, 0x11, 0xcd, 0x01, 0x09}; unsigned char code code_scan [] = {0xf7, 0xef, 0xdf};

unsigned char scrBuffer[3]; unsigned char count = 0; unsigned char pos = 0; bit on = 0;

void init (void);

void delay (unsigned int time); void decode (unsigned char tmpCount);

void main (void)

        {

            init();

             while(1)

                     {

                           count ++;

                           if (count > 100) count = 0;         

                           decode(count);       

                           delay(200);

                     }

           } 

void delay (unsigned int time) //chuong trinh delay

           { 

                unsigned int i,j; 

                for(i = 0; i < time; i ++)

                for(j = 0; j < 100; j ++); 

            } 

void decode (unsigned char tmpCount)

           {

              scrBuffer[0] = code_7seg[tmpCount % 10];     

              tmpCount /= 10;

              scrBuffer[1] = code_7seg[tmpCount % 10];     

              tmpCount /= 10;

              scrBuffer[2] = code_7seg[tmpCount % 10];

            } 

void init (void) // khoi tao timer0

            {

                     TH0 = 0x94;

                     TL0 = 0x00;

                     TF0 = 0;

                     TR0 = 1; // cho phep dem

                     ET0 = 1; // cho phep ngat

                     EA = 1;

                     decode(count);

             } 

void isrTmr0 (void) interrupt 1

{
TH0 = 0x94; 
 

 

TL0 = 0x00;
if (on == 0)
{
     P2 = 0xff; //turn off all led
     P0 = 0xff; //clear data
     on = 1;
}
else
{
     P0 = scrBuffer[pos]; // output data
on       P2 = code_scan[pos]; // turn appropriate led
     if (++ pos == 3) pos = 0;
     on = 0;
 

}

}
   

3.4.3. Bài tập mở rộng

  1. Viết chương trình hiển thị chữ HELLO chạy từ phải qua trái trên màn hình led.
  2. Viết chương trình điều khiển ban đầu hiển thị số 0, nếu nút UP được nhấn thì tăng giá trị hiển thị lên một đơn vị, nếu nút DOWN được nhấn thì giảm một đơn vị, nút MODE được nhấn thì mạch tự động đếm lên từ giá trị hiện hành đến 100 rồi trở về 0 và tiếp tục đếm lên, nếu nhấn nút MODE lần nữa thì dừng lại, lập lại quá tình kiểm tra ba nút như ban đầu.Có âm nhận phím, trong quá trình tăng tự động hai nút UP và DOWN vẫn có tác dụng.

3.5. ĐIỀU KHIỂN KHỐI HIỂN THỊ LCD

3.5.1. Mục đích, yêu cầu

Giúp sinh viên làm quen với việc điều khiển hiển thị dữ liệu trên màn hình LCD trong các ứng dụng như đếm sản phẩm, đồng hồ báo giờ, hiển thị chuỗi thong báo…

Sinh viên phải nắm được cấu tạo và cách thức điều khiển hiển thị trên màn hình LCD.

3.5.2. Chương trình tham khảo

Chương trình điều khiển hiển thị hai dòng Text ra màn hình LCD sau đó di chuyển hai dòng text qua trái, qua phải.

#include <AT89x52.h>

 

//khai bao macro

#define LCD_DATA_PORT P0

                #define LCD_E           P2_5

                #define LCD_RW          P2_4

                #define LCD_RS          P2_3

 

#define lcd_char(chr) lcd_send_byte(1, chr)

#define lcd_cmd(cmd) lcd_send_byte(0, cmd)

 

//khai bao prototype

void lcd_waitms (unsigned int time); void lcd_send_byte (bit cmd, unsigned char byte); void lcd_init (void);

void lcd_string(unsigned char *str);

 

//chuong trinh chinh void main (void)

{

                     unsigned char i, j;

 

lcd_init();

                     lcd_string (“Dai hoc Lac Hong”);

 lcd_cmd(0xC0); //di chuyen con tro ve dong thu 2  lcd_string (“Welcome !!!”);  while (1)

                     {

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

                          {

                               lcd_send_byte(0,0×18);

                               lcd_waitms(1000);

                          }          

 

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

                          {

                               lcd_send_byte(0,0x1C);

                               lcd_waitms(1000);

                          }          

 

                     }

}

 

//chuong trinh con

void lcd_send_byte(bit cmd, unsigned char byte)

{

                     LCD_RW = 0;             //write mode

                     LCD_RS = cmd;      // cmd = 0 send command, cmd =

1 send data

                     LCD_DATA_PORT = byte;

     LCD_E = 1;    LCD_E = 0;

                     lcd_waitms(1);

void lcd_string(unsigned char *str)

{

                        while(*str != ‘\0’) // lap lai cho den khi ket

thuc chuoi

                     {

                          lcd_char(*str); // ghi ky tu len man hinh

                          str ++; // ky tu tiep theo

                     }

void lcd_init(void)

{

     lcd_waitms(15);    //wait for about 15ms lcd_cmd(0x38);      // two line, size of char

5×7 dot

     lcd_cmd(0x01);          // clear lcd       lcd_cmd(0x06);      // move cursor to right

                     lcd_cmd(0x0C);          // lcd on, cursor off

void lcd_waitms (unsigned int time)

{

     unsigned int x, y;     for (x = 0; x <= time; x ++)

                     {

                          for (y = 0; y <= 121; y ++);

                     }

}

3.5.3. Bài tập mở rộng

Viết chương trình điều khiển hiển thị dòng text ra màn hình LCD kết hợp với nút nhấn và Buzzer. Nếu nút được nhấn thì Buzzer phát ra âm “Beep” báo nhận phím, và màn hình hiển thị dòng text thứ nhất, tương tự nếu tiếp tục nhấn thì dòng text khác sẽ xuất hiện trên màn hình LCD.

3.6.  TRUY XUẤT IC DS12887

3.6.1. Mục đích, yêu cầu

Giúp sinh viên làm quen với việc truy xuất dữ liệu thời gian từ IC real time cho các ứng dụng yêu cầu thời gian thực như đồng hồ báo giờ… Sau bài tập này, sinh viên phải nắm được các điểm sau:

  • Cách khai báo đường dẫn đến thư viện.
  • Cách truy xuất bộ nhớ ngoài bằng Keil C
  • Sử dụng được IC DS12887 cho các ứng dụng cần có thời gian thực

3.6.2. Chương trình tham khảo

Chương trình đồng hồ báo giờ, phút, giây bằng cách truy xuất dữ liệu thời gian từ DS12887, cho phép khởi tạo lại DS12887.

#include <AT89x52.h> #include “lcd_lib.h”

 unsigned char code my_signature[] = “plain”; unsigned char code strDOW[7][4] =

{

“SUN”, “MON”, “TUE”, “WED”, “THU”, “FRI”, “SAT”

};

//———location of date/time data—————

unsigned char xdata sec     _at_ 0x0000;
unsigned char xdata sec_alarm _at_ 0x0001;
unsigned char xdata min     _at_ 0x0002;
unsigned char xdata min_alarm _at_ 0x0003;
unsigned char xdata hour  _at_ 0x0004;

unsigned char xdata hour_alarm  _at_ 0x0005;

unsigned char xdata DOW     _at_ 0x0006;
unsigned char xdata date  _at_ 0x0007;
unsigned char xdata month  _at_ 0x0008;
unsigned char xdata year  _at_ 0x0009;
unsigned char xdata century  _at_ 0x0032;

//————————————————–

 

//——-location of control register—————

unsigned char xdata reg_A _at_ 0x000A;
unsigned char xdata reg_B _at_ 0x000B;
unsigned char xdata reg_C _at_ 0x000C;
unsigned char xdata reg_D _at_ 0x000D;

//————————————————–

 

//——–location of signature——————— unsigned char xdata signature[5] _at_ 0x000E; //————————————————–

 bit check_DS12C887 (void); void init_DS12C887 (void); void main (void)

{    if (check_DS12C887()) init_DS12C887();  lcd_init();

 

                     while (1)

                     {

          lcd_1st_line;        lcd_string(strDOW[0]);           lcd_char(‘,’);       lcd_write_dec(date);       lcd_char(‘/’);       lcd_write_dec(month);       lcd_char(‘/’);       lcd_write_dec(year);

 

          lcd_2nd_line;           lcd_write_dec(hour);       lcd_char(‘:’);          lcd_write_dec(min);      lcd_char(‘:’);          lcd_write_dec(sec);

                     }

bit check_DS12C887 (void)

unsigned char i;  for (i = 0; i < 5; i ++){   if (signature[i] != my_signature[i])        return 1; // new installed IC or

battery was empty

                     }

                     return 0; // IC’s working properly

void init_DS12C887 (void)

{    unsigned char i;

 

 // write signature into Dalas  for (i = 0; i < 5; i ++){   signature[i] = my_signature[i];

                     }

 // init the registers  reg_A = 0x20;  reg_B = 0x86; // SET bit = 1

 

 // init the time  hour = 3;  min = 9;

      

                     reg_B = 0x06; // SET bit = 0

}

3.6.3. Bài tập mở rộng

Viết chương trình đồng hồ hiển thị giờ bằng màn hình LCD, cho phép người sử dụng chỉnh thời gian bằng ba nút MODE, UP, DOWN.

Viết chương trình đồng hồ báo thức.

 

 

 

PHẦN IV BÀI TẬP MỞ RỘNG

 

Bài 1:  Viết chương trình điều khiển đèn giao thông sử dụng khối LED đơn và khối LED 7 đoạn. Cho phép thay đổi giá trị thời gian bằng cách sử dụng khối nút nhấn, kết hợp với khối Buzzer phát âm nhận phím.

Bài 2:  Viết chương trình chuông đố vui để học cho 3 đội chơi, sử dụng khối LED đơn, khối nút nhấn và Buzzer.

Bài 3:  Viết chương trình giải mã tín hiệu Remote TV Philips hoặc TV Sony, bằng cách sử dụng khối Infrared Reciver và khối LED 7 đoạn. Hiển thị giá trị phím nhận được 0-9 ra LED 7 đoạn.

Bài 4:  Viết chương trình đồng hồ hiển thị bằng màn hình LCD cho phép người sử dụng hiệu chỉnh thời gian và cài đặt thời gian đỗ chuông. Hiệu chỉnh bằng khối nút nhấn và báo chuông bằng khối Buzzer.

Bài 5:  Viết chương trình đồng hồ hiển thị bằng màn hình LCD cho phép người sử dụng hiệu chỉnh thời gian và cài đặt thời gian đổ chuông. Hiệu chỉnh bằng Remote TV và báo chuông bằng khối Buzzer.

Bài 6:  Viết chương trình kết hợp Remote TV với khối hiển thị LCD cho phép người sử dụng nhập đoạn text vào bằng các phím trên Remote sau đó cho phép tạo ra các hiệu ứng di chuyển đoạn text bằng các nút điều khiển trên Remote TV.