SlideShare una empresa de Scribd logo
1 de 83
Descargar para leer sin conexión
Đề cương ứng dụng lập trình C cho vi điều khiển 8051

Bài 1: Ngôn ngữ C – Trình dịch Keil C
I. Ngôn ngữ C cho vi điều khiển
1, Giới thiệu ngôn ngữ C
        Trong kỹ thuật lập trình vi điều khiển nói chung, ngôn ngữ lập trình được sử dụng
thường chia làm 2 loại: Ngôn ngữ bậc thấp và Ngôn ngữ bậc cao.




                                                 t
                                               ne
       Ngôn ngữ bậc cao là các ngôn ngữ gần vơi ngôn ngữ con người hơn, do đó việc lập
trình bằng các ngôn ngữ này trở nên dễ dàng và đơn giản hơn. Có thể kể đến một số ngôn
ngữ lập trình bậc cao như C, Basic, Pascal… trong dó C là ngôn




                                            u.
ngữ thông dụng hơn cả trong kỹ thuật vi điều khiển. Về bản chất, sử dụng các ngôn ngữ này
thay cho ngôn ngữ bậc thấp là giảm tải cho lập trình viên trong việc nghiên cứu các tập lệnh
và xây dựng các cấu trúc giải thuật. Chương trình viết bằng ngôn ngữ bậc cao cũng sẽ được
                                   ct
một phần mềm trên máy tính gọi là trình biên dịch (Compiler) chuyển sang dạng hợp ngữ
trước khi chuyển sang mã máy.
                          c
       Khi sử dụng ngôn ngữ C người lập trình không cần hiểu sâu sắc về cấu trúc của bộ vi
                       ni

điều khiển. Có nghĩa là với một người chưa quen với một vi điểu khiển cho trước sẽ xây
dựng được chương trình một cách nhanh chóng hơn, do không phải mất thời gian tìm hiểu
           tro


kiến trúc của vi điều khiển đó. Và việc sử dụng lại các chương trình đã xây dựng trước đó
cũng dễ dàng hơn, có thể sử dụng toàn bộ hoặc sửa chữa một phần.
ec




2. Ngôn ngữ C


2.1 Kiểu dữ liệu
el




2.1.1 Kiểu dữ liệu trong C


  Kiểu                 Số Byte    Khoảng giá trị
  Char                       1    -128 – +127
  Unsigned char              1    0 – 255
  Int                        2    -32768 - +32767
  Unsigned int               2    0 - 65535
  Long                       4    -2147483648 - +2147483647
Unsigned long           4       0 – 4294697295
  Float                   4


      * Khai báo biến:
- Cú pháp: Kiểu_dữ_liệu Vùng_nhớ Tên_biến _at_ Đia_chỉ;
   Ví dụ:
     Unsigned char data x;




                                                 t
                                               ne
- Khi khai báo biến có thể gán luôn cho biến giá trị ban đầu.
   Ví dụ:
      Thay vì: unsigned char x;




                                            u.
                x = 0;
      Ta chỉ cần: unsigned char x = 0;
- Có thể khai báo nhiều biến cùng một kiểu một lúc.
                                   ct
    Ví dụ: unsigned int x,y,z,t;
- Chỉ định vùng nhớ: từ khoá “Vùng_nhớ” cho phép người dùng có thể chỉ ra vùng nhớ sử
                            c
dụng để lưu trữ các biến sử dụng trong chương trình. Các vùng nhớ có thể sử dụng là:
                         ni

CODE, DATA, DATAB, IDATA, PDATA, XDTA. Khi không khai báo vùng nhớ trình
dịch Keil C sẽ mặc định đó là vùng nhớ DATA.
            tro


 Vùng nhớ Ý nghĩa
 CODE       Bộ nhớ mã nguồn chương trình
ec




 DATA       Bộ nhớ dữ liệu gồm 128 Byte thấp của RAM trong vi điều khiển
 BDATA      Bộ nhớ dữ liệu có thê định địa chỉ bit, nằm trong vùng nhớ DATA
 IDATA      Bộ nhớ dữ liệu gồm 128 Byte cao của RAM trong vi điều khiển chỉ có ở một
el




            số dòng vi điều khiển sau này
 PDATA      Bố nhớ dữ liệu ngoài gồm 256 Byte, được truy cập bởi địa chỉ đặt trên P0
 XDATA      Bộ nhớ dữ liệu ngoài có dung lượng có thể lên đến 64 KB, được truy cập bởi
            địa chỉ đặt trên P0 và P2


      * Định nghĩa lại kiểu
- Cú pháp: typedef Kiễu_dữ_liệu Tên_biến;
- Ten_biến sau này sẽ được sử dụng như một kiểu dữ liệu mới và có thể dùng để khai báo
các biến khác
Ví dụ: typedef int m5[5];
       Dùng tên m5 khai báo hai biến tên a và b có kiểu dữ liệu là mảng 1 chiểu 5 phần tử:
              m5 a,b;
2.1.2 Kiểu dữ liệu trong Keil C


         Kiểu                 Số bit
         Bit                  1




                                                    t
                                                  ne
         Sbit                 1
         Sfr                  8
         Sfr16                16




                                               u.
       - bit : dùng để khai báo các biến có giá trị 0 hoặc một hay các biến logic trên vùng
RAM của vi điều khiển. Khi khai báo biến kiểu bit trình dịc Keil C sẽ mặc định vùng nhớ
sử dụng là BDATA.
                                       ct
`     - sbit, sfr, sfr16: dùng để định nghĩa các cho các thanh ghi chức năng hoặc các cổng
trên vi điều khiển dùng để truy nhập các đoạn dữ liệu 1 bit, 8 bit, 16 bit
                             c
2.1.3 Mảng
                          ni

       Mảng là một tập hợp nhiều phần tử cùng một kiểu giá trị và chung một tên. Các phần
tử của mảng phân biệt với nhau bởi chỉ số hay số thứ tự của phần tử trong dãy phẩn tử. Mỗi
           tro


phần tử có vai trò như một biến và lưu trữ được một giá trị độc lập với các phần tử khác của
mảng.
       Mảng có thể là mảng một chiều hoặc mảng nhiều chiều
ec




       Khai báo:
- Cú pháp: Tên_kiểu Vùng_nhớ Tên_mảng[số_phần_tử_mảng];
       Khi bỏ trống số phần tử mảng ta sẽ có mảng có số phần tử bất kì.
el




       Ví dụ:
                 Unsigned int data a[5],b[2] [3];
       Với khai báo trên ta sẽ có: mảng a là mảng một chiều 5 phần tử. Mảng b là mảng hai
chiều, tổng số phần tử là 6.
       Chỉ số của mảng bắt đầu từ số 0. Mảng có bao nhiêu chiều phải cung cấp đầy đủ bấy
nhiêu chỉ sô
       Ví du: phần tử mảng b[0] [1] là đúng
              Khi viết b[0] là sai
2.1.4. Con trỏ
Khi ta khai báo một biến, biến đó sẽ được cấp phát một khoảng nhớ bao gồm một số
byte nhất định dùng để lưu trữ giá trị. Địa chỉ đầu tiên của khoảng nhớ đó chính là địa chỉ
của biến được khai báo.
       Con trỏ là một biến dùng để chứa địa chỉ mà không chứa giá trị, hay giá trị của con
trỏ chính là địa chỉ khoảng nhớ mà nó trỏ tới.
       Với các vùng nhớ cụ thể con trỏ tới vùng nhớ đó chiếm dung lượng phụ thuộc vào
độ lớn của vùng nhớ đó. Con trỏ tổng quát khi không xác định trước vùng nhớ sẽ có dung




                                                   t
                                                 ne
lượng lớn nhất vì vậy tốt nhất nên sử dụng con trỏ cụ thể.
                              Loại con trỏ        Kích thước
                              Con trỏ tổng quát   3 byte




                                              u.
                              Con trỏ XDATA       2 byte
                              Con trỏ CODE        2 byte
                              Con trỏ DATA        1 byte
                                      ct
                              Con trỏ IDATA       1 byte
                              Con trỏ PDATA       1 byte
                          c
                       ni

       Khai báo biến con trỏ:
- Cú pháp: Kiểu_Dữ_liệu Vùng_nhớ *Tên_biến;
           tro


- Ví dụ:
       int *int_ptr;
       long data *long_ptr;
ec




- khi không chỉ rõ vùng nhớ con trỏ sẽ được coi là con trỏ tổng quát.
2.1.5 Kiểu dữ liệu cấu trúc
       Kiểu dữ liệu cấu trúc là một tập hợp các biến, các mảng và cả các kiểu cấu trúc khác
el




được biểu thị bởi một tên duy nhất. kiểu dữ liệu cấu trúc dùng để lưu trữ các giá trị, thông
tin có liên quan đến nhau.
       Định nghĩa và khai báo biến cấu trúc:
- Định nghĩa: typedef struct {
                                     Khai báo các biến thành phần;
                              } Tên_kiểu_cấu_trúc;
- Khai báo: Tên_kiểu_cấu_trúc Vùng_nhớ Tên_biến;
      Ví dụ: typedef struct {
                                     char day;
char month;
                                   int year;
                             } Date_type;
                Date_type date,date_arr[5];
2.2 Phép toán
       Phép gán kí hiệu: “=”.
- Cú pháp: Biến_1 = Biến_2;




                                                    t
                                                  ne
       Trong đó Biến_2 có thể là giá trị xác định cũng có thể là biến.
2.2.1 Phép toán số học
    Phép toán               ý nghĩa                            Ví dụ




                                               u.
        +                 Phép cộng                           X=a+b
          -                Phép trừ                           X=a-b
        *                Phép nhân                            X=a*b
                                      ct
          /           Phép chia lấy phần                      X=a/b
                           nguyên                       (a=9, b=2 → X=4)
                           c
        %           Phép chia lấy phần dư                      a%b
                        ni

                                                        (a=9, b=2 → X=1)
              tro


2.2.2 Phép toán Logic

 AND: &&
ec




 OR: ||
 NOT: !
el




2.2.3 Các phép toán so sánh:
Phép                                  ý nghĩa                     Ví dụ
     toán
       >                            So sánh lớn hơn                   a>b
                                                                 4>5 các giá trị
                                                                           0




                                                   t
      >=                       So sánh lớn hơn hoặc bằng               a>=b




                                                 ne
                                                                  6>=2 các giá
                                                                       trị 1
       <                           So sánh nhỏ hơn                    a<b




                                              u.
                                                                 6<7 các giá trị
                                                                           1
                                    ct
      <=                       So sánh nhỏ hơn hoặc bằng               a<=b
                           c
                                                                  8<=5 các giá
                        ni

                                                                     trị 0
      ==                          So sánh bằng nhau                    a==b
            tro


                                                                  6==6 các giá
                                                                       trị 1
      !=                          So sánh khác nhau                    a!=b
ec




                                                                 9!=9 các giá trị
                                                                       0
el




2.2.4 Phép toán thao tác Bit
            Phép toán          Ý nghĩa                        Ví dụ
                &              Phép và (AND)               Bit_1 & Bit_2
                 |             Phép hoặc (OR)              Bit_1 | Bit_2
                 !             Phép đảo (NOT)                 !Bit_1
                ^              Phép hoặc loại trừ (XOR)    Bit_1 ^ Bit_2
                <<             Dịch trái                       a<<3
                >>             Dịch phải                       a>>4
                ~              Lấy bù theo bit                  ~a
2.2.5 Phép toán kết hợp
     Phép toán    Ví dụ
         +=       a+=5 <=> a=a+5
         -=       a-=5 <=> a=a-5
         *=       a*=5 <=> a=a*5
         /=       a/=5 <=> a=a/5




                                                   t
                                                 ne
        %=        a%=5 <=> a=a%5


2.3 Cấu trúc chương trình C




                                              u.
2.3.1 Cấu trúc chương trình
      * Cấu trúc
                                    ct
             1. Khai báo chỉ thị tiền xử lý
              2. Khai báo các biến toàn cục
              3. Khai báo nguyên mẫu các hàm
                          c
              4. Xây dựng các hàm và chương trình chính
                       ni

      * Ví dụ:
              #include<regx51.h>
          tro


                                              Khai báo chỉ thị tiền xử lý
              #include<string.h>
              #define Led1 P1_0
ec




              Unsigned char code Led_arr[3];
              Unsigned char data dem;                   Khai báo biến toàn cục
              Unsigned int xdata X;
el




              Void delay(unsigned int n);
              bit kiemtra(unsigned int a);       Khai báo nguyên mẫu hàm


              void delay(unsigned int n)
              {
                     Khai báo biến cục bộ;
                     Mã chương trình trễ;
              }
Void main()
                                                          Xây dựng các hàm và chương
              {                                           trình chính
                     Khai báo biến cụ bộ;
                     Mã chương trình chính;
              }
              Bit kiemtra(unsigned int a)
              {




                                                    t
                                                  ne
                     Khai báo biến cục bô;
                     Mã chương trình kiểm tra biến a;
              }




                                               u.
       Chú ý: Hàm không khai báo nguyên mẫu phải được xây dựng trước hàm có lời gọi
hàm đó. Ở ví dụ trên do hàm “bit kiemtra(unsigned int a)” đã được khai báo nguyên mẫu
hàm ở trên nên có thể xây dựng hàm ở bất kì vị trí nào trong chương trình.
                                    ct
2.3.2 Chỉ thị tiền xử lý
                          c
       Các chỉ thị tiền sử lý không phải là các lệnh của ngôn ngữ C mà là các lệnh giúp cho
                       ni

việc soạn thảo chương trình nguồn C trước khi biên dịch. Khi dịch một chương trình C thì
không phải chính bản chương trình nguồn mà ta soạn thảo được dịch. Trước khi dịch, các
           tro


lệnh tiền xử lý sẽ chỉnh lý bản gốc, sau đó bản chỉnh lý này sẽ được dịch. Có ba cách chỉnh
lý được dùng là:
       + Phép thay thế #define
ec




       + Phép chèn tệp #include
       + Phép lựa chọn biên dịch #ifdef
       Các chỉ thị tiền xử lý giúp ta viết chương trình ngắn gọn hơn và tổ chức biên dịch,
el




gỡ rối chương trình linh hoạt, hiệu quả hơn.
       * Chỉ thị #define
      Chỉ thị #define cho phép tạo các macro thay thế đơn giản
- Cú pháp: #define Tên_thay_thế dãy_kí_tự
       Một Tên_thay_thế có thể được định nghĩa lại nhiều lần, nhưng trước khi định nghĩa
lại phải giải phóng định nghĩa bằng chỉ thị:
                     #undef Tên_thay_thế
- Ví dụ:      #define N 100
       * Chỉ thị #include
Chỉ thị #include báo cho trình biên dịch nhận nội dung của tệp khác và chèn vào tệp
chương trình nguồn mà ta soạn thảo.
 - Cú pháp:
      Cách 1: #include<tên_tệp>
      Cách 2: #include“tên_tệp”
- Ví dụ:
      Cách 1: #include<regx51.h>




                                                   t
                                                 ne
               Ở cách này tệp regx51.h sẽ được tìm trong thư mục INC để chèn vào chương
trình nguồn.
      Cách 2: #include“regx51.h”




                                              u.
               Ở cách này tệp regx51.h sẽ được tìm trong thư mục chứa chương trình nguồn
nếu không có mới tìm trong thư mục INC
      Khi muốn chèn tệp ngoài thư viện hoặc ngoài thư mục chứa chương trình nguồn thì
                                     ct
tên_tệp sẽ bao gồm cả đường dẫn thư mục chứa tệp.
                            c
      * Chỉ thị #ifdef
                         ni

      Chỉ thị #ifdef này thường dùng để biên dịch các tệp thư viện.
- Cú pháp:
           tro


      Cách 1: #ifdef ten_macro
                   Đoạn chương trình
              #endif
ec




      Cách 2: #ifdef ten_macro
                        Đoạn chương trình 1
                #else
el




                        Đoạn chương trình 2
                #endif
      Ở cách 1 nếu tên_macro đã được định nghĩa “Đoạn chương trình” sẽ được dịch
ngược lại “Đoạn chương trình” sẽ bị bỏ qua.


      * Chỉ thị #ifndef
      Chỉ thị #ifndef này thường dùng để biên dịch các tệp thư viện.
- Cú pháp:
      Cách 1: #ifndef ten_macro
Đoạn chương trình
               #endif
       Cách 2: #ifndef ten_macro
                       Đoạn chương trình 1
               #else
                       Đoạn chương trình 2
               #endif




                                                  t
                                                ne
      Ở cách 1 nếu tên_macro chưa được định nghĩa “Đoạn chương trình” sẽ được dịch
ngược lại “Đoạn chương trình” sẽ bị bỏ qua.




                                             u.
2.3.3 Chú thích trong chương trình
       Việc viết chú thích trong trình nhằm mục đích giải thích ý nghĩa của câu lệnh, đoạn
chương trình hoặc hàm hoạt động như thế nào và làm gì. Viết chú thích sẽ giúp cho người
                                     ct
đọc có thể hiểu được chương trình dễ dàng và nhanh chóng hơn, sửa lỗi đơn giản hơn hoặc
giúp cho ta xem lại chương trình cũ mà ta đã làm trở lên nhanh hơn.
                              c
       Chú thích trong chương trình sẽ không ảnh hưởng đến chương trình mà ta soạn thảo
                           ni

vì trình dịch sẽ bỏ qua tất cả lời chú thích khi biên dịch chương trình sang mã máy.
       Lời giải thích được đặt sau dấu “//” nếu chú thích chỉ viết trên một dòng hoặc trong
           tro


cặp dấu “*” và “*”.
3 Các lệnh cơ bản trong C
 + Câu lệnh rẽ nhánh if:
ec




     - Cấu trúc: if(dieu_kien)
                {
                    // Đoạn chương trình
el




                }


       Giải thích: nếu dieu_kien đúng thì xư lí các câu lệnh bên trong còn sai thì nhảy qua.
       - Cấu trúc: if(dieu_kien)
                       {
                             // Đoạn chương trình 1
                       }
                    else
                       {
// Đoạn chương trình 2
                    }
      Giải thích: nếu dieu_kien đúng thì xử lí “Đoạn chương trình 1” bên trong còn sai thì
x ử l ý “Đoạn chương trình 1”


 + Câu lệnh lựa chọn:
   Cấu trúc:       switch(bien)




                                                      t
                                                    ne
                       {
                           case gia_tri_1: {//các câu lệnh break;}
                           case gia_tri_2: {//các câu lệnh break;}




                                                 u.
                           case gia_tri_3: {//các câu lệnh break;}
                           ……………………………………...
                           case gia_tri_n: {//các câu lệnh break;}
                                         ct
                       }
   Giải thích: tuỳ vào biến có gia_tri_1 thì thực hiện các câu lệnh tương ứng rồi sau đó
                               c
thoát khỏi cấu trúc nhờ câu lệnh break.
                            ni

         Biến có gia_tri_2 thì thực hiện câu lệnh tương ứng rồi thoát.
         …………………….
           tro


       Biến có gia_tri_n thì thực hiện các câu lệnh tương ứng rồi thoát.
 + Vòng lặp xác định:
    Cấu trúc: for(n=m;n<l;n++)
ec




                {
                       // các câu lệnh xử lí
                   }
el




    Giải thích:
                  m,l là giá trị(m>l), còn n là biến.
             thực hiện lặp các câu lệnh (l-m) lần.
 + Vòng lặp không xác định while:
    Cấu trúc: while(dieu_kien)
                   {
                       // các câu lệnh
                   }
Giả thích: thực hiện lặp các câu lệnh khi điều kiện đúng nếu điều kiện sai thì thoát
khỏi vòng lặp.
 + Vòng lặp không xác định do while:
    Cấu trúc: do
                   {
                       // các câu lệnh
                   } while(dieu_kien);




                                                t
                                              ne
      Giả thích: thực hiện lặp các câu lệnh sau đó kiểm tra điều kiện nếu đúng, nếu sai thì
thoát khỏi vòng lặp.




                                           u.
II. Trình biên dịch Keil C (compiler)
2.1. Khởi tạo cho Project.               ct
                             c
                          ni
           tro
ec
el




      Để tạo 1 project mới chọn project → New project như sau:
t
                                            ne
                                         u.
                        c        ct
                     ni

Hộp thoại create new project hiện ra như sau:
         tro
ec
el
Đánh tên và chuyển đến thư mục bạn lưu project.bạn nên tạo mỗi một thư mục cho 1
project. rồi chọn save.
 Hộp thoại sau hiện ra:




                                                t
                                              ne
                                           u.
                         c         ct
                      ni
           tro
ec




 Trong này có 1 loạt các hãng điện tử sản xuất 8051. bạn lập trình cho con nào thì chọn con
đấy, kích chuột vào dấu + để mở rộng các con IC của các hang. ở đây ta lập trình cho
AT89C51 của hang ATMEN nên ta chọn như trên.
el




Khi chọn chip thì ngay lập tức 1 bảng hiện ra 1 số tính năng của chip các bạn có thể nhìn
thấy: 8051 based fully static 24Mhz …. nhập OK, chọ câu trả lời NO khi được hỏi “copy
standard 8051 startup code to project and addfile to project” vì nếu chon YES chỉ làm cho
file lập trình của bạn thêm nặng.
Để tạo một file code các bạn chọ file→new hoặc ấn ctrl+N. như sau:




                                              t
                                            ne
                                         u.
                         c        ct
                      ni
          tro
ec




 Cửa sổ text1 hiện ra. Tiếp theo bạn chọn File → save As hoặc Ctrl+S, để lưu File mặc dù
chưa có gì như sau:
el
t
                                           ne
                                        u.
                        c        ct
                     ni

 Được cửa sổ sau:
         tro
ec
el




Các bạn nhập tên vào text box file name.chú ý tên gì cũng được nhưng không được thiếu
đuôi mở rộng .C, và nhấn SAVE.
Trong ô bên trái màn hình, cửa sổ PROJECT WORKSPACE, các bạn mở rộng cái target 1
ra như sau:




                                              t
                                            ne
                                         u.
                        c         ct
                     ni

Nhấp chuột phải nên SOURCE GROUP, chọn Add file to Group “Source Group 1” hộp
thoại hiện ra chọn file .C mà các bạn vừa SAVE rồi nhấn Add 1lấn rồi nhấn Close. nếu bạn
          tro


nhấn Add 2 lần nó sẽ thong báo là file đã add bạn chỉ việc OK rồi nhấn Close. Được như
sau:
ec
el
t
                                             ne
                                          u.
                                  ct
Bây giờ trong hình nhìn thấy trong Source Group 1 có file VIDU.C. các bạn nhấp chuột
phải vào vùng soạn thảo file VIDU.C để thêm file thư viện. Chon Insert
                         c
“#include<REGX51.H>”.
                      ni
          tro
ec
el
t
                                                ne
                                             u.
                            c        ct
                         ni
           tro



Phần cuối cùng của công việc khởi tạo là các bạn viết lời giải thích cho dự án của mình.
phần này rất cần thiết vì nó để người khác hiểu mình làm gì trong project này và khi mình
ec




cần sử dụng lại code đọc lại còn biết nó là cái gì.
el




2.2. Soạn thảo chương trình.
Các bạn viết thử 1 chương trình làm ví dụ. khi viết xong mỗi dòng lệnh nên giải thích dòng
lệnh đó làm gì. Ví dụ:
t
                                      ne
                                   u.
                        c          ct
                     ni
          tro
ec
el




2.3. Biên dịch một chương trình.
Sau khi soạn thảo xong nhấn Ctrl+S để nhớ. Nhớ xong các bạn biên dịch chương trình
bắng cách ấn phím F7 hoặc chọn Build target là biểu tượng ngay trên cửa sổ Workspace,
như trên hình:




                                              t
                                            ne
                                         u.
                        c         ct
                     ni
          tro
ec
el
Để biên dịch chương trình thành file HEX các bạn chọn: Project→option for ‘target 1’
như hình vẽ:




                                              t
                                            ne
                                         u.
                        c        ct
                     ni
          tro
ec
el
Trong hộp thoại hiện ra, hãy check vào Creat HEX File như chỉ dẫn:
chọn thẻ táp target nhập lại tần số thạch anh là 12Mhz.




                                                t
                                              ne
                                           u.
                         c         ct
                      ni

Để mô phỏng các bạn chon Debug→Start/stop debug session hoặc ấn Ctrl+F5, hoặc nhấn
          tro


vào Icon chữ D màu đỏ trong cái kính lúp trên thanh công cụ.
ec
el
t
                                             ne
                                          u.
                        c         ct
Để hiển thi các cổng, các thanh ghi các bạn chon trong peripherals.
                     ni
          tro
ec
el
t
                                              ne
                                           u.
                         c         ct
                      ni
           tro


Các bạn thấy 1 cửa sổ nhỏ Parallel Port xuất hiện đó là cái để mô phỏng cho 1 cổng của
AT89C51. dấu tick tương đương chân ở mức cao (5V), không tick chân ở mức thấp
0V.trong menu peripherals còn có các ngoại vi khác như timer, interrupt, serial.
ec
el
t
                                            ne
                                         u.
                        c         ct
                     ni
          tro


Để chạy chương trình các bạn ấn chuột phải vào màn hình soạn thảo, rồi ấn F11.mỗi làn ấn
sẽ chạy 1 lệnh.khi debug nếu các bạn chờ hàm delay lâu quá 1000 lần lặp các bạn nhấn
ctrl+F11 để bỏ qua hàm.
ec




hoặc ấn F10 để chạy từng dòng lệnh
el
Bài 2: Điều khiển Led đơn, Led 7 thanh và nút nhấn

I. Hiển thị Led đơn
   Bài toán:Ghép nối LED dơn với chân P1.0 của vi điều khiển, viết chương trình điều
khiển LED nhấp nháy với thời gian trễ là 1s.




                                                t
                                              ne
                                           u.
                         c        ct
                      ni
          tro



+ Lưu đồ thuật toán của bài LED nháy:
ec




                                  START


                             Khởi tạo hệ thống
el




                                 Sáng Led

                                  Trễ 1S

                                  Tắt Led

                                  Trễ 1S
+ Chương trình điều khiển:
         */==================Bo tien xu li===================*/
         #include<AT89x51.h> // Dinh kem file thu vien
         #define bat 1              // Dinh nghia gia tri bat den Led
         #define tat 0    // Dinh nghia gia tri tat den Led
         /*==================khai bao bien==================*/




                                                   t
         sbit Led = P1^0; // Khai bao bien Led kieu bit chan P1.0




                                                 ne
         /*================= Khai bao hàm==================*/
         /*------------------------------ham tre -------------------------------------*/



                                              u.
         void delay(long time)
          {
               while(time--);
                                     ct
          }
                             c
         /*--------------------------------ham chinh--------------------------------*/
                          ni

         void main(void)
           {
               while(1)
          tro


                {
                     Led = bat; // bat Led
                     delay(25000); // tre 1s
ec




                     Led = tat; // tat Led
                     delay(25000); //tre 1s
el




                }
           }

II. Phối hợp Led và nút nhấn
1. Phối hợp Led đơn và nút nhấn
        Bài toán: Một đèn Led được nối với chân P1.0 của vi điều khiển. Một công tắc
START nối với chân P3.0 và công tắc STOP nối với chân P3.1 của vi điều khiển. hãy
viết chương trình điều khiển để khi bật công tắc START thì Led sang, khi bật công tắc
STOP thì Led tắt.
t
                                         ne
                                      u.
                              ct
  + Lưu đồ thuật giải của bài toán:
                  c
               ni

                              Start
    tro


                          Led = tat
ec




                              Start = 0          Led = bat
el




                                                 Led = tat
                              Stop = 0




 + Chương trình điều khiển:
 */==================Bo tien xu li===================*/
 #include<AT89x51.h> // Dinh kem file thu vien
#define bat 1          // Dinh nghia gia tri bat den Led
 #define tat 0          // Dinh nghia gia tri tat den Led
 /*==================khai bao bien==================*/
 sbit Led = P1^0; // Khai bao bien Led kieu bit chan P1.0
  sbit STOP = P3^0; // cong tac STOP de tat Led
 sbit START = P3^1; // cong tac START de bat Led




                                           t
 /*=================== ham chinh==================*/




                                         ne
 void main(void)
 {
       Led = tat; //ban dau tat Led



                                      u.
       while(1){
             if((START==0)&&(STOP==1)) {
                            ct
                    Led = bat;
             }
                    c
             if((START==1)&&(STOP==0)){
                 ni

                    Led = tat;
             }
         }
     tro


 }
ec
el
2. Phối hợp Led 7 thanh và nút nhấn
Các số    P1.0    P1.1     P1.2       P1.3   P1.4    P1.5    P1.6             số nạp hex
 hiển         g       f       e        d         c       b       a       dp   mov P1,#
  thị
   0      1       0       0       0          0       0       0       1        81
   1      1       1       1       1          0       0       1       1        cf




                                                  t
   2      0       1       0       0          1       0       0       1        92




                                                ne
   3      0       1       1       0          0       0       0       1        86
   4      0       0       1       1          0       0       1       1        cc
   5      0       0       1       0          0       1       0       1        a4



                                             u.
   6      0       0       0       0          0       1       0       1        a0
   7      1       1       1       1          0       0       0       1        8f
                                  ct
   8      0       0       0       0          0       0       0       1        80
   9      0       0       1       0          0       0       0       1        84
                             c
                          ni

         Bài toán:
         Một Nút bấm được nối với chân P3.4, hãy lập trình điều khiển đếm số lần ấn
           tro


phím từ 0 đến 9 và hiển thị trên Led 7 thanh.
ec
el
+ Lưu đồ thuật giải:

                                 START


                                   Dem=0;




                                                 t
                                  ctac==0?




                                               ne
                                   dem++;



                                dem<=10?

                                            u.
                          c       ct
                                   dem=0;
                       ni

                            hiển thi ra Led 7 thanh
          tro



+ Chương trình điều khiển:
ec




     /*==================Bo tien xu li===================*/
      #include<AT89x51.h> // Dinh kem file thu vien
      /*=================Khai bao bien toan cuc=============*/
el




      sfr dataP = 0x90; // du lieu la P1
      // ma 7 thanh tu 0 den 9 la
      // 0x81h,0xcfh,0x92h,0x86h,0xcch,0xa4,0xa0h,0x8fh,0x80h,0x84h.


      sbit ctac = P3^4;
      unsigned char dem=0;
      /*====================Khai bao ham==================*/
      /*----------------------------ham delay========================*/
      void delay(long time)
{
        while(time--);
 }
 /*----------------------chuong trinh con kiem tra co phim nhan-------------*/
 void phim_an(void)
 {




                                             t
        if(ctac==0) //co phim nhan




                                           ne
        {
                 delay(500); //chong rung phim
                 while(ctac==0); //Cho nha phim



                                        u.
                 delay(500); // chong rung phim
                 dem++; //tang bien dem
                                ct
                 if(dem==10) dem=0;
        }
                     c
 }
                  ni

 /*----------------hien thi so lan an phim------------------------------------------*/
 void solan_an(void)
 {
     tro


        switch(dem)
            {
                 case 0: {dataP=0x81;break;}
ec




                 case 1: {dataP=0xcf;break;}
                 case 2: {dataP=0x92;break;}
el




                 case 3: {dataP=0x86;break;}
                 case 4: {dataP=0xcc;break;}
                 case 5: {dataP=0xa4;break;}
                 case 6: {dataP=0xa0;break;}
                 case 7: {dataP=0x8f;break;}
                 case 8: {dataP=0x80;break;}
                 case 9: {dataP=0x84;break;}
            };
 }
/*-------------------------chuong trinh chinh-------------------------------------------*/
 void main(void)
     {
         dataP = 0x81; // ban dau la so 0
         while(1){
               phim_an();




                                             t
                solan_an();




                                           ne
         }
 }




                                        u.
                     c          ct
                  ni
         tro
ec
el
Bài 3 Hiển thị LCD, Giao tiếp bàn phím Hex, Hiển thị ma trận Led
I. LCD
1. Ghép nối vi điều khiển với LCD 16x2.
    - Bảng mô tả sơ đồ chân của LCD 16x2:
    Chân          Ký hiệu          I/O                         Mô tả
      1             Vss             -                          Mass




                                              t
      2             Vcc             -                    Dương nguồn 5v




                                            ne
      3             VEE             -            Cấp nguồn điều khiển tương phản
      4             RS              I               RS=0 chon thanh ghi lệnh
                                                   RS=1 chon thanh ghi dữ liệu



                                         u.
      5             R/W             I             R/W=1 đọc dữ liệu, R/W=1 ghi
      6              E             I/O                       Cho phép
                                 ct
      7             DB0            I/O                      Bit dữ liệu
      8             DB1            I/O                             Nt
                        c
      9             DB2            I/O                             Nt
                     ni

     10             DB3            I/O                             Nt
     11             DB4            I/O                             Nt
           tro


     12             DB5            I/O                             Nt
     13             DB6            I/O                             Nt
     14             DB7            I/O                             Nt
ec




      Chân 15 và 16 là A và K. Nó được nối với 2 chân của 1 con Led dùng để sáng
LCD trong bóng tối chúng ta không sử dụng.
    - Sơ đồ ghép nối LCD với vi điều khiển:
el
t
                                           ne
                                        u.
                        c        ct
 2. Nguyên lí hoạt động của LCD.
   - Chân VCC, Vss, và VEE: các chân VCC và VSS cáp dương nguồn 5v và mass tương
                     ni

ứng. Chân VEE được dùng để điều khiển độ tương phản.
   - Chân chọn thanh ghi RS(Register Select): có 2 thanh ghi trong LCD chân RS được
          tro


dùng để chọn thanh ghi. nếu RS=0 thì thanh ghi mã lệnh được chọn để cho phép người
dùng gửi 1 lệnh lên chẳng hạn như xoá màn hình, đưa con trỏ về đầu dòng… Nếu RS=1
thì thanh ghi dữ liệu được chọn cho phép người dùng gửi dữ liệu cần hiển thị lên LCD.
ec




    - Chân đọc/ghi (R/W): đầu vào đọc/ghi cho phép người dùng đọc thông tin từ LCD
khi R/W=1 hoặc ghi thông tin lên LCD.
el




    - Chân cho phép E(Enable): chân cho phép được sử dụng bởi LCD để chốt dữ liệu
của nó. Khi dữ liệu được cấp đến chân dữ liệu thì 1 xung mức cao xuống thấp phải được
áp đến chân này để LCD chốt dữ liệu trên các chân dữ liệu. Xung này có độ rộng tối
thiểu 450ns.
     - Chân DB0-DB7: đây là đường dữ liệu 8 bít, được dùng để gửi thông tin lên LCD
hoặc đọc nội dung các thanh ghi trong LCD. Để hiển thị các chữ cái và các con số,
chúng ta gửi mã ASCII của các chữ cái từ A đến Z , a đến z và các chữ số từ 0 đến 9 đến
các chân này khi bật RS=1.
    - Bảng mã lệnh của LCD:
Mã (HEX)         Lệnh đến thanh ghi của LCD
    01                Xoá màn hình hiển thị
    02                   Trở về đầu dòng
    04         Giảm con trỏ(dịch con trỏ sang trái )
    06         Tăng con trỏ(dịch con trỏ sang phải)
    05               Dịch hiển thị sang phải




                          t
    07                Dịch hiển thị sang trái




                        ne
    08               Tắt con trỏ, tắt hiển thị
    0a               Tắt hiển thị, bật con trỏ
    0c               Bật hiển thi, tắt con trỏ



                     u.
    0e           Bật hiển thị, nhấp nháy con trỏ
    0f            Tắt con trỏ, nhấp nháy con trỏ
               ct
    10             Dịch vị trí con trỏ sang trái
    14             Dịch vị trí con trỏ sang phải
               c
    18            Dịch toàn bộ hiển thị sang trái
            ni

    1c           Dịch toàn bộ hiển thị sang phải
    80           Ép con trỏ về đầu dòng thứ nhất
         tro


   0c0            Ép con trỏ về đầu dòng thứ 2
    38               Hai dòng và ma tận 5x7.
ec
el
3. Phần luyện tập:
      Hãy viết chương trình hiển thị trên LCD:
             Dòng 1 chữ “VIETNAM” bằng cách hiển thị tưng kí tự
             Dòng 2 chữ "VI DIEU KHIEN" bằng cách hiển thị cả chữ. Với sơ đồ mạch
cho dướí đây.




                                                t
                                              ne
                                           u.
                         c         ct
                      ni

Chương trình:
      /*=========bo tien xu li===============*/
          tro


      #include<AT89x51.h>
      #include<string.h>
      /*===========khai bao bien toan cuc============*/
ec




      sfr LCDdata = 0xA0; // cong P2, 8 bit du lieu.
      sbit BF = 0xA7; // co ban, bit DB7.
      sbit RS = P3^0; // chon thanh ghi
el




      sbit RW = P3^1; // doc/ghi
      sbit EN = P3^2; //cho phep chot du lieu
      /*===========cac chuong trinh con cua LCD==========*/
      /*--------------kiem tra su san sang cua LCD------------------------*/
      void wait(void)
      {
             RS=0; //chon thanh ghi lenh
             RW=1; //đoc tu LCD
LCDdata=0xff; //gia tri 0xff
        while(BF) //kiem tra co ban
        {
               EN=0; //dua xung cao xuong thap đe chot.
               EN=1; //dua chan cho phep len cao
        }




                                             t
 }




                                           ne
 /*------------------------thiet lap lenh cho LCD--------------------------*/
 void LCDcontrol(unsigned char x)
 {



                                        u.
        RS=0;//chon thanh ghi lenh
        RW=0;//ghi len LCD.
        LCDdata=x ;// gia tri x
                               ct
        EN=1;//cho phep muc cao
                    c
        EN=0;//xung cao xuong thap
                 ni

        wait();//đoi LCD san sang.
 }
 /*------------------------------Khoi tao LCD-------------------------*/
     tro


 void LCDinit(void)
 {
        LCDcontrol(0x38);//2 dong va ma tran 5x7
ec




        LCDcontrol(0x0e);//bat man hinh, bat con tro
        LCDcontrol(0x01);//xoa man hinh
el




 }
 /*-------------------------thiet lap du lieu cho LCD-----------------*/
 void LCDwrite(unsigned char c)
 {
        RS=1;//ghi du lieu
        RW=0;//ghi du lieu len LCD
        LCDdata=c;//gia tri C
        EN=1;//cho phep muc cao
        EN=0;//xung cao xuong thap
wait();//cho
 }
 void LCDwrites(unsigned char *s)
 {
       unsigned char data lens,count;
       lens=strlen(s);




                                         t
       for(count=0;count<lens;count++){




                                       ne
             LCDwrite(*(s+count));
       }
 }



                                    u.
 /*=====================chuong trinh tre================*/
 void delay(long time)
 {
                           ct
       while(time--);
                  c
 }
               ni

 /*========================ham chinh==================*/
 void main(void)
 {
     tro


       LCDinit(); // khoi tao LCD
       LCDcontrol(0x82);// dua con tro den vi tri thu 4 dong 1
       LCDwrite(‘V’);
ec




       LCDwrite(‘I’);
       LCDwrite(‘E’);
el




       LCDwrite(‘T’);
       LCDwrite(‘ ’);
       LCDwrite(‘N’);
       LCDwrite(‘A’);
       LCDwrite(‘M’);
       LCDcontrol(0xC0);
       LCDwrites("VI DIEU KHIEN");
       while(1); //vong lap vo han
 }
II. Giao tiếp bàn phím Hex (ma trận phím 4x4)
1. Thuật toán đọc bàn phím
                                     Begin


                                Cộti = 0 (i=1-4)




                                                  t
             Sai




                                                ne
                                   Hàngi = 0
                                    (i =1-4)




                                             u.
                                           Đúng
                             Trả lại kết quả phím đã
                                       nhấn
                                    ct
2. Chương trình
      Hãy viết chương trình đọc ma trận phím và hiển thi số thứ tự phím trên LCD.
                        c
                     ni
          tro
ec
el
Chương trình:
     /*=========bo tien xu li===============*/
     #include<AT89x51.h>
     #include<string.h>

     #define H1 P1_0




                                              t
     #define H2 P1_1




                                            ne
     #define H3 P1_2
     #define H4 P1_3
     /*===========khai bao bien toan cuc============*/



                                         u.
     sfr LCDdata = 0xA0; // cong P2, 8 bit du lieu.
     sbit BF = 0xA7; // co ban, bit DB7.
                                     ct
     sbit RS = P3^0; // chon thanh ghi
     sbit RW = P3^1; // doc/ghi
                        c
     sbit EN = P3^2; //cho phep chot du lieu
     #include"LCD.h"// Thu vien LCD tu xay dung
                     ni

     /*-------- ham doc phim nhan tu ma tran phim 4x4---------------*/
     unsigned char Phim(void)
         tro


     {
             unsigned char phimnhan, dem, chot;
             phimnhan=0;
ec




             chot=128;
             dem=4;
             while(dem--){
el




                    P1=~chot;
                    if(!H1){
                           delay(500);
                           phimnhan=dem+1;
                           delay(500);
                   }else if(!H2 ){
                           delay(500);
                           phimnhan=dem+5;
                           delay(500);
}else if(!H3 ){
                        delay(500);
                        phimnhan=dem+9;
                        delay(500);
                }else if(!H4 ){
                        delay(500);
                        phimnhan=dem+13;




                                           t
                        delay(500);




                                         ne
                }
                chot>>=1;
       }




                                      u.
       return phimnhan;
 }
                                  ct
 void viewphim(unsigned char phimnhan)
 {
                       c
       if(phimnhan<10){
                LCDwrite(phimnhan+48);
                    ni

       }else{
                LCDwrite(phimnhan/10+48);
     tro


                LCDwrite(phimnhan%10+48);
       }
 }
ec




 void main(void)
 {
       unsigned char phimnhan=0;
el




       LCDinit();
       LCDwrites("Hay Nhan Phim");
       LCDcontrol(0xC0);
       while(1){
             phimnhan=Phim();
                if(phimnhan){
                        LCDcontrol(0x01);
                        LCDwrites("Hay Nhan Phim");
                        LCDcontrol(0xC0);
viewphim(phimnhan);
                      }
                }
       }


III. Hiển thị ma trận Led
1. Thuật toán




                                               t
                                             ne
2. Xây dựng chương trình
      Bài toán: Viết chương trình hiển thị ma trận LED bằng phương pháp quét cột hiển
thị dong chữ "LAP TRINH VI DIEU KHIEN BANG NGON NGU C", với dong chữ chạy




                                          u.
từ trái sang phải.
                             c     ct
                          ni
           tro
ec
el




+ Chương trình:
// Khai bao chi thi tien xu ly
#include<AT89x51.h>

// Dinh nghia cac cong va cac chan dieu khien
#define CLOCK P3_2
#define DATA P3_3
#define CLEAR P3_4
#define Pxanh P1
#define Pdo P2

// Dinh nghia cac hang so
#define Nhanh 10
#define Trungbinh 25
#define Cham 50




                                                 t
                                               ne
#define Cuccham 75
#define Sieucham 150
#define Mxanh 1




                                            u.
#define Mdo 2
#define Mcam 3
// Khai bao mang chu hien thi
                                    ct
unsigned char code Mcode[256]={
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                          c
      0,255,1,1,1,1,/* L */
                       ni

      0,63,72,136,72,63,/* A */
      0,255,144,144,144,96,/* P */
           tro


      0,
      0,128,128,255,128,128,/* T */
      0,255,144,144,144,111,/* R */
ec




      0,129,129,255,129,129,/* I */
      0,255,96,24,6,255,/* N */
      0,255,16,16,16,255,/* H */
el




      0,
      0,252,2,3,2,252,/* V */
      0,129,129,255,129,129,/* I */
      0,
      0,255,129,129,129,126,/* D */
      0,129,129,255,129,129,/* I */
      0,255,145,145,145,129,/* E */
      0,254,1,1,1,254,/* U */
      0,
0,255,24,36,66,129,/* K */
      0,255,16,16,16,255,/* H */
      0,129,129,255,129,129,/* I */
      0,255,145,145,145,129,/* E */
      0,255,96,24,6,255,/* N */
      0,
      0,255,145,145,145,110,/* B */




                                                 t
                                               ne
      0,63,72,136,72,63,/* A */
      0,255,96,24,6,255,/* N */
      0,126,129,129,137,78,/* G */




                                            u.
      0,
      0,255,96,24,6,255,/* N */
      0,126,129,129,137,78,/* G */
                                    ct
      0,126,129,129,129,126,/* O */
      0,255,96,24,6,255,/* N */
                         c
      0,
                      ni

      0,255,96,24,6,255,/* N */
      0,126,129,129,137,78,/* G */
           tro


      0,254,1,1,1,254,/* U */
      0,
      0,126,129,129,129,70,/* C */
ec




      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
      };
el




// Khai bao bien toan cuc
unsigned char data Start,End,Tocdolap,i,j,k;
unsigned char data Mdata1[32],Mdata2[32],Mau;
unsigned char data Dk1,Dk2,Dk3,Dk4,Dk5;


// Khai bao nguyen mau cac ham
void delay(unsigned long time);
unsigned char Mu2(unsigned char somu);
void Do(unsigned char chiso);
void Xanh(unsigned char chiso);
void Cam(unsigned char chiso);
void Dobyte(unsigned char chiso);
void Xanhbyte(unsigned char chiso);
void Cambyte(unsigned char chiso);




                                                t
                                              ne
void Chaychudo(void);
void Chaychuxanh(void);
void Chaychucam(void);




                                           u.
void Chaychu(void);


void Taomangnhapnhay(void);
                                    ct
void Nhapnhayxanh(void);
void Nhapnhaycam(void);
                           c
void Nhapnhaydo(void);
                        ni

void Taomanglen(void);
           tro


void Lxanh(void);
void Ldo(void);
void Lcam(void);
ec




void Len(void);
/******************Ma nguon cac ham*************************/
// Ham tao tre
el




void delay(unsigned long time)
{
       while(time--);
}
// Khoi ham hien thi chu chay tu trai sang phai
void Xanh(unsigned char chiso)
{
       CLOCK=1;
       DATA=0;
CLOCK=0;
     Pxanh=Mcode[chiso];
     delay(12);
     Pxanh=0;
}


void Do(unsigned char chiso)




                                     t
                                   ne
{
     CLOCK=1;
     DATA=0;




                                u.
     CLOCK=0;
     Pdo=Mcode[chiso];
     delay(12);
                                ct
     Pdo=0;
}
                       c
                    ni

void Cam(unsigned char chiso)
{
         tro


     CLOCK=1;
     DATA=0;
     CLOCK=0;
ec




     Pxanh=Mcode[chiso];
     Pdo=Pxanh;
     delay(12);
el




     Pdo=0;
     Pxanh=0;
}

void Chaychucam(void)
{
     for(i=Start+1;i<Dk1;i++)
     {
            Tocdolap=Nhanh;
while(Tocdolap--)
           {
                  DATA=1;
                  Dk2=i+32;
                  for(j=i;j<Dk2;j++)Cam(j);
           }
     }




                                            t
                                          ne
}
void Chaychuxanh(void)
{




                                       u.
     for(i=Start+1;i<Dk1;i++)
     {
           Tocdolap=Nhanh;
                                ct
           while(Tocdolap--)
           {
                      c
                  DATA=1;
                   ni

                  Dk2=i+32;
                  for(j=i;j<Dk2;j++)Xanh(j);
         tro


           }
     }
}
ec




void Chaychudo(void)
{
     for(i=Start+1;i<Dk1;i++)
el




     {
           Tocdolap=Nhanh;
           while(Tocdolap--)
           {
                  DATA=1;
                  Dk2=i+32;
                  for(j=i;j<Dk2;j++)Do(j);
           }
     }
}

void Chaychu(void)
{
      Dk1=End-31;
      if(Mau==Mxanh)Chaychuxanh();
      else if(Mau==Mdo)Chaychudo();




                                                  t
                                                ne
      else Chaychucam();

}


// Khoi ham hien thi chu nhap nhay tai cho
void Cambyte(unsigned char chiso)
                                             u.
                                   ct
{
      CLOCK=1;
                        c
      DATA=0;
                     ni

      CLOCK=0;
      Pxanh=Mdata2[chiso];
          tro


      Pdo=Pxanh;
      delay(12);
      Pdo=0;
ec




      Pxanh=0;
}
el




void Dobyte(unsigned char chiso)
{
      CLOCK=1;
      DATA=0;
      CLOCK=0;
      Pdo=Mdata2[chiso];
      delay(12);
      Pdo=0;
}
void Xanhbyte(unsigned char chiso)
{
     CLOCK=1;
     DATA=0;
     CLOCK=0;
     Pxanh=Mdata2[chiso];




                                           t
                                         ne
     delay(12);
     Pxanh=0;
}


void Nhapnhaydo(void)
{
                                      u.
                                ct
     while(Tocdolap--){
            DATA=1;
                       c
            for(k=0;k<32;k++)Dobyte(k);
                    ni

     }
}
         tro


void Nhapnhayxanh(void)
{
     while(Tocdolap--){
ec




           DATA=1;
            for(k=0;k<32;k++)Xanhbyte(k);
     }
el




}
void Nhapnhaycam(void)
{
     while(Tocdolap--){
            DATA=1;
            for(k=0;k<32;k++)Cambyte(k);
     }
}
void Taomangnhapnhay(void)
{
      for(i=0;i<32;i++)
             Mdata2[i]=0;


      Dk4=End-Start;
      Dk5=(32-Dk4)/2;




                                               t
                                             ne
      Dk4=32-Dk5;
      for(i=Dk5;i<Dk4;i++)
             Mdata2[i]=Mcode[Start+i-Dk5];




                                          u.
}


void Nhapnhay(void)
                                   ct
{
      unsigned char demnhay;
                         c
      demnhay=10;
                      ni

      Taomangnhapnhay();
      while(demnhay--)
          tro


      {
             Tocdolap=Nhanh;
             if(Mau==Mxanh)Nhapnhayxanh();
ec




             else if(Mau==Mdo)Nhapnhaydo();
             else Nhapnhaycam();
             CLEAR=0;
el




             delay(1250);
             CLEAR=1;
      }
}
// Khoi ham hien thi chu di tu duoi len
unsigned char Mu2(unsigned char somu)
{
      if(!somu) return 1;
      else return 2*Mu2(somu-1);
}

void Taomanglen(void)
{
     for(i=0;i<32;i++)
            Mdata2[i]=0;




                                            t
                                          ne
     Dk4=End-Start;
     Dk5=(32-Dk4)/2;
     Dk4=32-Dk5;




                                       u.
     for(i=Dk5;i<Dk4;i++)
            Mdata1[i]=Mcode[Start+i-Dk5];
     i=8;
                               ct
}
void Lcam(void)
                       c
{
                    ni

     unsigned char data dem;
     Tocdolap=Trungbinh;
            tro


     while(Tocdolap--)
     {
            DATA=1;
ec




            for(dem=0;dem<32;dem++)
            {
                  CLOCK=1;
el




                  DATA=0;
                  CLOCK=0;
                  Pxanh=Mdata2[dem];
                  Pdo=Pxanh;
                  delay(12);
                  Pxanh=0;
                  Pdo=0;
            }
     }
}
void Ldo(void)
{
     unsigned char data dem;
     Tocdolap=Trungbinh;
     while(Tocdolap--)
     {




                                             t
                                           ne
            DATA=1;
            for(dem=0;dem<32;dem++)
            {




                                        u.
                   CLOCK=1;
                   DATA=0;
                   CLOCK=0;
                                ct
                   Pdo=Mdata2[dem];
                   delay(12);
                       c
                   Pdo=0;
                    ni

            }
     }
         tro


}

void Lxanh(void)
ec




{
     unsigned char data dem;
     Tocdolap=Trungbinh;
el




     while(Tocdolap--)
     {
            DATA=1;
            for(dem=0;dem<32;dem++)
            {
                   CLOCK=1;
                   DATA=0;
                   CLOCK=0;
                   Pxanh=Mdata2[dem];
delay(12);
                  Pxanh=0;
            }
     }
}


void Len(void)




                                            t
                                          ne
{
     Taomanglen();
     while(i--)




                                       u.
     {
            for(j=Dk5;j<Dk4;j++)
                  Mdata2[j]= Mdata1[j]/Mu2(i);
                                ct
            if(Mau==Mxanh)Lxanh();
            else if(Mau==Mdo)Ldo();
                        c
            else Lcam();
                     ni

     }
         tro


     for(i=0;i<7;i++)
     {
            for(j=Dk5;j<Dk4;j++)
ec




                   Mdata2[j]= Mdata2[j]*2;
            if(Mau==Mxanh)Lxanh();
            else if(Mau==Mdo)Ldo();
el




            else Lcam();
     }
}
/*Ham chinh*/
void main(void)
{
     TMOD=0x01;
     Pxanh=0;
     Pdo=0;
P3=16;

 while(1)
 {
       Start=0;End=194;Mau=3;
       Chaychu();




                                       t
                                     ne
       Start=0;End=17;Mau=1;
       Len();
       Start=19;End=48;Mau=1;




                                  u.
       Len();
       Start=50;End=61;Mau=1;
       Len();
                         ct
       Start=63;End=87;Mau=1;
       Len();
                   c
       Start=89;End=118;Mau=1;
                ni

       Len();
       Start=120;End=143;Mau=1;
     tro


       Len();
       Start=145;End=168;Mau=1;
       Len();
ec




       Start=170;End=187;Mau=1;
       Len();
       Start=189;End=194;Mau=1;
el




       Len();


       Start=0;End=17;Mau=2;
       Nhapnhay();
       Start=19;End=48;Mau=2;
       Nhapnhay();
       Start=50;End=61;Mau=2;
       Nhapnhay();
       Start=63;End=87;Mau=2;
Nhapnhay();
        Start=89;End=118;Mau=2;
        Nhapnhay();
        Start=120;End=143;Mau=2;
        Nhapnhay();
        Start=145;End=168;Mau=2;
        Nhapnhay();




                                        t
                                      ne
        Start=170;End=187;Mau=2;
        Nhapnhay();
        Start=189;End=194;Mau=2;




                                   u.
        Nhapnhay();
    }                     ct
}
                  c
               ni
        tro
ec
el
Bài 5: Giao tiếp ADC - Xử lý ngắt
I. Giao tiếp ADC




                                               t
                                             ne
                                          u.
                            c          ct
                         ni

+Chương trình:
            tro


#include<regx51.h>
#include<string.h>
ec




/*===========khai bao bien toan cuc============*/
 sfr LCDdata = 0xA0; // cong P2, 8 bit du lieu.
sbit BF = 0xA7; // co ban, bit DB7.
el




sbit RS = 0xb0; // chon thanh ghi
sbit RW = 0xb1; // doc/ghi
sbit EN = 0xb2; //cho phep chot du lieu
#include"Lcd.h"// Thu vien LCD tu xay dung
#define RD P3_3
#define WR P3_4
#define INTR P3_5
/*-------- Ham tre ---------------*/
void delay(long time)
{
       while(time--);
}
/*-------- ham doc phim nhan tu ma tran phim 4x4---------------*/


void view(unsigned char val)
{




                                                t
                                              ne
       unsigned char var;
       if(val<10){
                LCDwrite(val+48);




                                           u.
       }else if(val<100){
                LCDwrite(val/10+48);
                LCDwrite(val%10+48);
                                    ct
       }else{
                var=val/10;
                           c
                LCDwrite(var/10+48);
                        ni

                LCDwrite(var%10+48);
                LCDwrite(val%10+48);
           tro


       }
}
void main(void)
ec




{
       unsigned char ADCval=0;
       RD=0;
el




       LCDinit();
       LCDcontrol(0x83);
       LCDwrites("ADC0804");
       while(1){
                WR=1;
                WR=0;
                while(!INTR);
                ADCval=P1;
                LCDcontrol(0x01);
LCDcontrol(0x83);
              LCDwrites("ADC0804");
              LCDcontrol(0xC0);
              view(ADCval);
              delay(5000);
       }
}




                                               t
                                             ne
II. Lập trình xử lý ngắt
1. Ngắt timer/counter.
  1.1. cơ chế tạo trễ của timer và cách tính toán giá trị nạp vào timer.
      a. chế độ 1:



                                          u.
        - ở chế độ 1 đó là bộ định thời 16 bit, do đó các giá trị trong khoảng từ 0000 đến
FFFF có thể sử dụng để nạp cho TH và TL của bộ định thời.
        - Sau khi TH, TL được nạp giá trị ban đầu 16 bit thì bộ định thời phải được khởi
                                  ct
động với lệnh TR0 = 1 với timer0 và TR1 = 1 với timer1, khi này bộ định thời bắt đầu
đếm tăng theo xung clock từ giá trị ban đầu cho tới giá trị đỉnh là FFFF. Khi đó bộ định
                          c
thời sẽ quay vong từ FFFF về 0000 và bật cờ báo tràn TF0 với timer0 và TF1 với
timer1(ban dầu TFx=0) khi đó cần phải có thao tác để xoá cờ để lần sau còn biết được
                       ni

khi nào bộ đếm tràn.
        - khi bộ đếm tràn thì TH và Tl của bộ định thời sẽ mang giá trị 0 do đó phải có
thao tác nạp lại giá trị ban đầu cho chúng và xoá cờ TF để bộ đếm được lặp lại.
           tro


        - Như vậy khoảng thời gian mà bộ định thời tạo trễ chính là khoangre thời gian
nó đếm tăng từ giá trị ban đầu được nạp cho tới giá trị đỉnh FFFF.
        - tính toán giá trị nạp vào thanh ghi chứa của bộ định thời từ thời gian muốn tạo
trễ(t): gọi N = 65536 – t/chu ki máy. Sau khi chuyển sang mã HEX được 1 số có 4 chữ
ec




số có dạng: x1x2y1y2. khi đó giá trị nạp cho thanh ghi chứa như sau: TH = x1x2, TL =
y1y2.
        Ví dụ: muốn tạo trễ 500us thì:
el




  Giả sử chu kì máy là 1us: có N = 65536 – 500/1 = 65036. chuyển sang mã HEX là
FE0C, từ đó: TH = 0xFE, TL = 0x0C.
        - các bước lập trình cho bộ định thời để tạo trễ ở chế độ 1:
                +B1: chọn chế độ 1 cho bộ định thời cần dung, từ đó xác định giá trị nạp
cho thanh ghi TMOD.
                + B2: tính toán giá trị ban đầu cần nạp cho TH và TL từ thời gian trễ mong
muốn.
                + B3: khởi động bộ định thời.
                + B4: kiểm tra trạng thái bật của cờ TF.
                + B5:dung bộ định thời.
                + B6: xoá cờ TF cho vòng lặp kế tiếp.
+ B7: quay trở về B2 để nạp lại giá trị cho TH và TL.
       b. Chế độ 2:
         - Ở chế độ này bộ định thời là 8 bit, do vậy chỉ cho phép các giá trị từ 00 đến FF
được nạp vào thanh ghi TH của bộ định thời. sau khi nạp giá trị 8 bit thì vi điều khiển sẽ
sao nội dung của TH sang TL và bộ định thời được khởi động bằng lệnh TRx=1.
         - Sau khi được khởi động thì bộ định thời bắt đầu đếm tăng trong thanh ghi TL từ
giá trị ban đầu đến giá trị đỉnh FF. và khi quay vòng từ FF về 00 thì cờ TFx được bật lên
1, khi này thanh ghi TL mang giá trị 0 nhưng TL sẽ ngay lập tức được tự động nạp lại




                                                t
với giá trị ban đầu được lưu trong thanh ghi TH.




                                              ne
         - như vậy trong chế độ này mỗi khi bộ đếm tràn thì thanh ghi chứa sẽ được vi
điều khiển nạp lại giá trị ban đầu, do đó chế độ này được gọi là chế độ tự động nạp lại.
         - tính giá trị nạp vào thanh ghi chứa của bộ định thời từ thời gian trễ (t):
         Gọi N = 256 – t/chu kì máy. Sau khi chuyển sang mã HEX được 1 số, ta nạp số



                                           u.
này vào thanh ghi TH và cả TL(nạp vào TL giá trị đếm lần 1 và nạp vào TH cho những
lần sau để khi bộ đếm tràn thì phần cứng của vi điều khiển sẽ tự động sao TH sang TL).
         Ví dụ: tạo trễ 50usthì là:
                                   ct
         Giả sử chu kì máy là 1us: có N = 256 – 50/1 = 205, chuyển sang mã HEX : 0CE
         Từ đó: TH = 0xCE và TL = 0xCE.
                         c
         - các bước lập trình cho bộ định thời để tạo trễ ở chế độ 2.
                 + B1: nạp giá trị cho thanh ghi thiết lập chế độ TMOD với timer muốn sử
                      ni

dụng.
                 + B2: nạp vào TH giá trị đém ban đầu.
                 +B3: khởi động bộ định thời.
          tro


                 + B4: kiểm tra cờ báo tràn TFx.
                 + B5: xoá cờ tràn TFx, quay về B4.
       * lưu ý: 2 chế độ khác của bộ định thời là chế độ 0(chế độ bộ định thời 13 bit, bộ
định thời/bộ đếm 8 bit, định tỷ lệ trước 5 bit ) và chế độ 3(chế độ bộ định thời chia tách)
ec




ở đay không giới thiệu.
   1.2. Ngắt của bộ định thời.
      - nguyên tắc sử dụng bộ định thời ở chế độ ngắt:
el




         + khai báo ngắt của bộ định thời muốn sử dụng
         + nguồn gây ngắt.
         + chương trình chính và chương trình phục vụ ngắt.
     - với ngắt định thời việc khai báo nguồn ngắt bao gồm việc khai báo ngắt toàn cục là
EA = 1 và khai báo ngắt cho từng bộ định thời muốn dùng ET0 = 1(timer0) và ET1 =
1(timer1)
     - Nguồn báo ngắt định thời(với cả 2 chế độ) đều là khi bộ đếm tràn(khi cờ TFx = 1),
khi cờ TFx = 1 thì vi điều khiển kết thúc công việc hiện tại ở chương trình chính và
chuyển vào chương trình phục vụ ngắt căn cứ theo địa chỉ của chương trình phục vụ
ngắt.khi thực hiện xong chương trình phục vụ ngắt vi điều khiển quay trở về chương
trình tại nơi bị gián đoạn khi trước.
- Tóm lại ngắt định thời là việc ta sử dụng bộ định thời tạo trễ một khoảng thời gian
được tính toán trước, sau khoảng thời gian này 1 công việc ta mong muốn sẽ được thực
hiện ở chương trình phục vụ ngắt. công việc đó có thể coi là độc lập với công việc ở
chương trình chính
     - các công việc lập trình sử dung ngắt định thời :
        + tính toán thời gian trễ mong muốn và công việc muốn thực hiện sau khoảng
thời gian đó.
        + khai báo ngắt định thời trong chương trình chính (EA=1, ETX=1).




                                                 t
        + lựa chon bộ định thời và chế độ của nó trong thanh ghi TMOD




                                               ne
        + khởi động bộ định thời.
        + Xây dựng chương trình chính và các chương trình con cần thiết.
        + xây dựng chương trình phục vụ ngắt thực hiện 1 công việc mong muốn (xác
định rõ địa chỉ ngắt theo thứ tự ngắt trong bảng vector ngắt)



                                            u.
     - Chú ý: trong chương trình phục vụ ngắt các bạn phải xoá cờ báo tràn TFx và nạp
lại giá trị cho bộ định thời với chế độ 1 còn chế độ 2 thì không cần.
  1.3. bài toán:
                                    ct
     Bài toán 1: sử dụng bộ định thời với ngắt của nó tạo một xung vuông với tần số
1kHZ đối xứng (50% mức 1 và 50% mức 0 ) trên chân P1.0.
                         c
Bài giải:
  - ta có : f = 1kHZ → T = 1/1000s = 1000us → TON = TOFF = T/2 = 500us. Như vậy
                      ni

chu kì xung là đối xứng nên hai phần này bộ đếm đếm giống nhau(tạo trễ khoảng thời
gian bằng nhau). nửa chu kì đầu bộ đếm tạo trễ 500us cho mức 0, sau khi bộ đếm đếm
đến giá trị đỉnh của thanh ghi chứa là FFFF thì cờ báo TFx = 1 gây ngắt, vi điều khiển
          tro


phải chuyển vào chương trình phục vụ ngắt và sẽ lật trạng thái xung ra. Trong nửa chu
kì còn lại cũng như vậy và cứ như thế.
  - Do thời gian trễ là 500us do đó ta chọn chế độ 16 bit, sử dụng kết quả từ ví dụ trên
để nạp giá trị ban đầu cho TH và TL.
ec




  - Chương trình điều khiển:
    /*================khai bao thu vien===============*/
    #include<AT89x51.h>
el




   /*=============khai bao bien=====================*/
   sbit xung = P1^0;
   /*==============khai bao ham ==================*/
   /*--------------------------chuong trinh phuc vu ngat timer0 tao xung--------------------*/
   void timer0_int(void) interrupt 1
    {
       TF0=0; // xoa co bao tran timer0
       xung = !xung; // tao muc 1 ra chan P1.0
       TH0 = 0xfe; // (65536-500)↔hex =0fe0c (thach anh 12MHz)
       TL0 = 0x0c;
}
  /*=============chuong trinh chinh=============*/
  void main(void)
  {
     EA = 1; // cho phep ngat toan cuc
     ET0 = 1; // cho phep ngat T0
     TMOD = 0x01; // timer0 che do 1
     xung = 0; //gia tri ban dau cua xung muon tao




                                            t
     TH0 = 0xfe; // (65536-500)↔hex =0fe0c (thach anh 12MHz)




                                          ne
     TL0 = 0x0c;
     TR0 = 1; // khoi dong timer
     while(1) PCON|=1; //khong lam gi ca de doi ngat.
  }



                                       u.
  Bài toán 2: sử dụng bộ định thời với ngắt của tạo đồng hồ số hiển thị lên LCD.
                                ct
                        c
                     ni
         tro
ec
el




+ Chương trình:
/*================khai bao thu vien===============*/

#include<regx51.h>
#include<string.h>

#define LCDdata P2
sbit RS=P3^0;
sbit RW=P3^1;
sbit EN=P3^2;
sbit BF=LCDdata^7;
#include"lcd.h"
/*=============khai bao bien=====================*/
 unsigned char data Time[8];
 unsigned char data i;

/*==============khai bao ham ==================*/
 void T10ms(void) interrupt 1 using 0
 {




                                             t
       TR0=0;




                                           ne
       TH0=0xD8;
       TL0=0xEF;
       TR0=1;
       if(Time[0]==9){



                                        u.
              Time[0]=0;
              if(Time[1]==9){
                     Time[1]=0;
                                 ct
                     if(Time[2]==9){
                            Time[2]=0;
                        c
                            if(Time[3]==5){
                                   Time[3]=0;
                     ni

                                   if(Time[4]==9){
                                          Time[4]=0;
                                          if(Time[5]==5){
          tro


                                                 Time[5]=0;
                                                 if(Time[6]==9&&Time[7]<2){
                                                        Time[6]=0;
                                                        Time[7]++;
ec




                                                 }else if(Time[6]==3&&Time[7]==2){
                                                        Time[6]=0;
                                                        Time[7]=0;
el




                                                 }else Time[6]++;
                                          }else Time[5]++;
                                   }else Time[4]++;
                            }else Time[3]++;
                     }else Time[2]++;
              }else Time[1]++;
       }else Time[0]++;
       LCDwrite(Time[7]+48);LCDwrite(Time[6]+48);LCDwrite(':');
       LCDwrite(Time[5]+48);LCDwrite(Time[4]+48);LCDwrite(':');
       LCDwrite(Time[3]+48);LCDwrite(Time[2]+48);LCDwrite(':');
       LCDwrite(Time[1]+48);LCDwrite(Time[0]+48);
LCDcontrol(0xC0);
}
     /*==============Chuong trinh chinh ==================*/
void main()
{
     TMOD|=1;
     EA=1;
     ET0=1;




                                              t
     TH0=0xD8;




                                            ne
     TL0=0xEF;
     for(i=0;i<8;i++)Time[i]=0;
     LCDinit();
     LCDwrites("Dong ho so");



                                         u.
     LCDcontrol(0xC0);
     TR0=1;
     while(1)PCON|=1;
                                  ct
}
                        c
 2. Lập trình với các ngắt ngoài của vi điều khiển.
   2.1. Khái niệm:
                     ni

     - bộ vi điều khiển 8051có hai ngắt ngoài là INT0 và INT1 với 2 chân tác động đầu
vào tương ứng là P3.2 và P3.3.
    - Ngắt ngoài là ngắt của vi điều khiển mà tác động ngắt ở đây chính là các tác động
          tro


bên ngoài của vi điều khiển tác động vào vi điều khiển thong qua các chân ngắt đưới
dạng một tín hiệu điện áp dạng xung.
    - tác động ngắt ngoài có hai dạng là tác động theo dạng mức và dạng sườn.
        + kích hoạt theo mức: ở chế độ này các chân INT0 và INT1 bình thường ở mức
ec




cao giống như các chân khác của vi điều khiển, khi có tín hiệu mức thấp cấp tới thì tín
hiệu này kích hoạt ngắt. lưu ý là trước khi thực hiện lệnh cuối cùng của chương trình
phục vụ ngắt thì mức thấp tại các chân ngắt phải được chuyển lên mức cao, nếu không
el




sẽ lại gây ra một ngắt ngay lập tức.
        + Kích hoạt theo sườn: bình thường các chân ngắt của vi điều khiển ở mức cao,
khi có tín hiệu tác động vào chúng có dạng sườn xuống thì sẽ tác động ngắt.
    - Để sử dụng chế độ ngắt này thì phải tác động vào thanh ghi TCON cụ thể là
TCON.1=1 hoặc IT0=1 thì cho phép ngắt ngoài 0 kích hoạt sườn, còn TCON.2=1 hoặc
IT1=1 thì cho phép ngắt ngoài 1 kích hoạt sườn.
  2.2. cách lập trình:
    - Để lập trình cho ngắt của vi điều khiển ta phải thực sự hiệu bản chất của ngắt và
quá trình thực hiện ngắt của vi điều khiển diễn ra.
    - mẫu viết hàm ngắt như sau:
        Void name(void)interrupt x(x là số thứ tự ngắt ngoài x = 0 hoặc 2)
{
                     //chương trình phục vụ ngắt
        }
    - Trong chương trình chính ta phải có thao tác thiết lập việc cho phép các ngắt được
sử dụng.
  2.3. bài toán:
       sử dụng ngắt ngoài của vi điều khiển với nhiệm vụ là: bình thường vi điều khiển
bật một Led đơn tại chân P1.0 và khi có ngắt ngoài thì tắt Led ở P1.0 và bật Led ở chân




                                                   t
P1.1 sau 1s thì bật lại Led P1.0 và tắt Led P1.1.




                                                 ne
                                              u.
                           c         ct
                        ni
            tro
ec
el




Bài giải:
      /*==================Bo tien xu li===================*/
           #include<AT89x51.h> // Dinh kem file thu vien
           #define bat 1               // Dinh nghia gia tri bat den Led
           #define tat 0               // Dinh nghia gia tri tat den Led
           /*==================khai bao bien==================*/
           sbit Led1 = P1^0; // Khai bao bi?n Led ki?u bit chan P1.0
           sbit Led2 = P1^1; // Khai bao bi?n Led ki?u bit chan P1.0
           /*================= Khai bao hàm==================*/
           /*------------------------------ham tre -------------------------------------*/
           void delay(long time)
{
             while(time--);
      }
     void INT_0(void) interrupt 0 // chuong trinh phuc vu ngat
     {
             Led1=tat;
             Led2=bat;
             delay(25000);




                                          t
             Led1=bat;




                                        ne
             Led2=tat;
     }
     /*--------------------------------ham chinh--------------------------------*/
     void main(void)



                                     u.
     {
             EA=1; // cho phep ngat toan cuc
             EX0=1; // cho phep ngat ngoai 0
                            ct
             IT0=1; //ngat kich phat suon
             Led1=bat;
                 c
             Led2=tat;
             while(1);
              ni

     }
 tro
ec
el
Bài 6: Điều khiển động cơ DC, động cơ Servo, động cơ bước
1. Đông cơ DC
2. Động cơ Servo
3. Động cơ bước (Step motor)
      Điều khiển động cơ bước với tốc độ tăng dần từ 5 đến 100 v/p, mỗi lần chuyển tốc
độ tăng 5v/p thời gian chuyển 1s, hiển thị tốc độ trên LCD.




                                                t
                                              ne
                                           u.
                         c         ct
                      ni
          tro


+ Chương trình:
#include<regx51.h>
#include<string.h>
ec




#define LCDdata P2
el




sbit RS=P3^0;
sbit RW=P3^1;
sbit EN=P3^2;
sbit BF=LCDdata^7;
#include"lcd.h"


unsigned char data Bytecao1,Bytethap1;
unsigned char data Buoc,Nbuoc;
unsigned char data Mbuoc[4]={144,192,96,48};
void viewspeed(unsigned char speed);
void Xuly(unsigned char Nspeed);



void Dkdongco(void) interrupt 1 using 0
{




                                               t
                                             ne
      TR0=0;
      TH0=Bytecao1;
      TL0=Bytethap1;




                                          u.
      TR0=1;
      P1=Mbuoc[Buoc];
      Buoc++;
                                 ct
      if(Buoc==4)Buoc=0;
}
                        c
                     ni

void Xuly(unsigned char speed)
{
         tro


      unsigned int data Chuki1,Chuki2;
      unsigned int data tam1,tam2;
      TR0=0;
ec




      viewspeed(speed);
      Nbuoc=200;
      tam2=10000/Nbuoc;
el




      tam1=6000/speed;
      Chuki1=tam1*tam2;
      Chuki2=65535-Chuki1;
      Bytecao1=Chuki2/256;
      Bytethap1=Chuki2%256;
      TR0=1;
}


void delay(unsigned long time)
{
     while(time--);
}
void viewspeed(unsigned char speed)
{
     unsigned char data a1,a2;
     LCDcontrol(0xc0);




                                             t
                                           ne
     a1=speed%10;
     speed=speed/10;
     a2=speed%10;




                                        u.
     speed=speed/10;
     LCDwrite(speed+48);
     LCDwrite(a2+48);
                                  ct
     LCDwrite(a1+48);
     LCDwrites("(vong/phut)");
                           c
}
                        ni

void main()
         tro


{
     unsigned char data i;
     TMOD=17;
ec




     EA=1;
     LCDinit();
     ET0=1;
el




     LCDcontrol(0x80);
     LCDwrites("CT DK DC buoc" );
     LCDcontrol(0xc0);
     LCDwrites("V:5-100(v/p)");
     delay(100000);
     while(1){
              Buoc=2;
              for(i=5;i<101;i=i+5){
                    LCDcontrol(0x01);
LCDcontrol(0x80);
            LCDwrites("CT DK DC buoc" );
            Xuly(i);
            delay(500000);
        }
    }
}




                                     t
                                   ne
                                u.
                c        ct
             ni
        tro
ec
el
Bài 7: Giao tiếp Vi điều khiển với Máy tính
I. Cổng truyền thông nối tiếp

1. Thanh ghi SCON – SBUF
II. Xây dựng chương trình
1. Chương trình VB
      + Giao diện




                                                t
                                              ne
                                           u.
                         c        ct
                      ni

      + Thuật toán
          tro


      + Chương trình:


Option Explicit
ec




Dim Mau As Byte
Private Sub cbcolor_Click()
  If (cbcolor.Text = "Mau do") Then
el




    Mau = 1
    txtchu.ForeColor = &HFF&
    lbHienthi.ForeColor = &HFF&
  ElseIf (cbcolor.Text = "Mau xanh") Then
    Mau = 2
    txtchu.ForeColor = vbGreen
    lbHienthi.ForeColor = &HFF00&
  ElseIf (cbcolor.Text = "Mau cam") Then
    Mau = 3
txtchu.ForeColor = &H80FF&
   lbHienthi.ForeColor = &H80FF&
  End If
End Sub


Private Sub cbcolor_GotFocus()
  SendKeys "%{DOWN}"




                                                 t
                                               ne
End Sub

Private Sub cmdCode_Click()




                                            u.
  MsgBox Code(txtchu)
End Sub                           ct
Private Sub cmdExit_Click()
  If MSComm1.PortOpen Then
                           c
     MSComm1.PortOpen = False
                        ni

  End If
  End
           tro


End Sub
Function Code(s As String) As String
ec




 Dim i As Integer
    s = Replace(s, " ", "")
  For i = 1 To Len(s)
el




    Code = Code & " " & Asc(Mid(s, i, 1))
  Next

End Function
Private Sub OpenPort()
  Dim s As String
  MSComm1.Settings = "57600,N,8,1"
  MSComm1.CommPort = 1
  MSComm1.PortOpen = True
MSComm1.InputLen = 0
  s = MSComm1.Input
  MsgBox "Port did open"
End Sub
Private Sub cmdOpenport_Click()
  If MSComm1.PortOpen Then
    MSComm1.PortOpen = False




                                            t
                                          ne
  End If
  OpenPort




                                       u.
End Sub


Private Sub cmdSend_Click()
                                  ct
Dim s As String
                        c
                     ni

If MSComm1.PortOpen = False Then
  MsgBox "Port did not open"
          tro


  OpenPort
End If
ec




If MSComm1.PortOpen Then
  txtchu.Text = UCase(txtchu.Text)
  s = Chr(Mau) & Chr(Len(txtchu.Text)) & txtchu.Text & Chr(255)
el




  Do While (MSComm1.OutBufferCount > 0)
  Loop
  MSComm1.Output = s
End If


End Sub


Private Sub cmdStop_Click()
  MSComm1.Output = Chr(250)
MsgBox "Port Stoped"
End Sub

Private Sub Form_Load()


  txtchu.ForeColor = vbRed
  txtchu.Text = "DO AN GHEP NOI"




                                             t
                                           ne
  Mau = 1

End Sub


Private Sub Form_Resize()
  If (Me.WindowState = 1) Then
                                        u.
                                   ct
    Me.Height = 4000
    Me.Width = 7230
                         c
  End If
                      ni

End Sub
            tro


Private Sub txtchu_GotFocus()
  txtchu.SelStart = 0
  txtchu.SelLength = Len(txtchu)
ec




End Sub


2. Chương trình vi điều khiển
el




      + Thuật toán
      + Chương trình:
/************Khai bao tien xy ly***************/
 #include<regx51.h>
/*********Dinh nghia hang so mau**********/
#define Mdo 1
#define Mxanh 2
#define Mcam 3
/*****Khai bao mang ki tu gom chu so va chu cai****/
unsigned char code Mchar[36][7]={
     48,0,126,129,129,129,126,/*0*/
     49,0,0,33,65,255,1,/*1*/
     50,0,99,135,137,145,97,/* 2 */
     51,0,66,129,145,145,110,/* 3 */
     52,0,24,40,72,255,8,/* 4 */
     53,0,226,145,145,145,142,/* 5 */




                                             t
                                           ne
     54,0,118,137,137,137,70,/* 6 */
     55,0,128,135,136,144,224,/* 7 */
     56,0,110,145,145,145,110,/* 8 */




                                        u.
     57,0,102,145,145,145,110,/* 9 */
     65,0,63,72,136,72,63,/* A */
     66,0,255,145,145,145,110,/* B */
                                   ct
     67,0,126,129,129,129,70,/* C */
     68,0,255,129,129,129,126,/* D */
                        c
     69,0,255,145,145,145,129,/* E */
                     ni

     70,0,255,144,144,144,128,/* F */
     71,0,126,129,129,137,78,/* G */
         tro


     72,0,255,16,16,16,255,/* H */
     73,0,129,129,255,129,129,/* I */
     74,0,2,129,130,252,128,/* J */
ec




     75,0,255,24,36,66,129,/* K */
     76,0,255,1,1,1,1,/* L */
     77,0,255,64,32,64,255,/* M */
el




     78,0,255,96,24,6,255,/* N */
     79,0,126,129,129,129,126,/* O */
     80,0,255,144,144,144,96,/* P */
     81,0,126,129,133,130,125,/* Q */
     82,0,255,144,144,144,111,/* R */
     83,0,98,144,144,144,78,/* S */
     84,0,128,128,255,128,128,/* T */
     85,0,254,1,1,1,254,/* U */
     86,0,252,2,3,2,252,/* V */
87,0,255,12,3,12,255,/* W */
      88,0,199,40,16,40,199,/* X */
      89,0,224,16,15,16,224,/* Y */
      90,0,131,133,153,161,193/* Z */
      };
/*******Dinh nghia cac chan va cac cong dieu khien*****/
sfr Pxanh=0x90;




                                                 t
                                               ne
sfr Pdo=0xA0;

sbit Clear=P3^4;




                                            u.
sbit Data=P3^3;
sbit Clock=P3^2;
/**************Khai bao bien toan cuc*************/
                                        ct
unsigned char data Ktnhan,nhanmau,j,i,Maxc,Count,nLap;
unsigned char data Mau,Chay,tam,dem;
                             c
unsigned char data MC[76],MQ[32];
                          ni

/**********Khoi ham chuong trinh**********/
// Ham ngat noi tiep
           tro


void Ngatnoitiep(void) interrupt 4        using 0
{
      if(RI){
ec




                RI=0;
                tam=SBUF;
                if(tam==250){
el




                         Chay=1;i=j=77;dem=8;
                         Count=0;
                         Clear=0;
                }else{
                         if(nhanmau){
                               Mau=tam;
                               Chay=1;i=j=77;dem=8;
                               Count=nhanmau=0;
                               P1=P2=0;
Clear=0;
                     }else if(tam==255){
                             Clear=1;
                              Chay=0;
                              Ktnhan=nhanmau=1;
                     }else{
                              if(Ktnhan){




                                                 t
                                               ne
                                    Maxc=tam;
                                    Ktnhan=0;
                              }else if(Count<76&&Count<Maxc){




                                            u.
                                    MC[Count]=tam;
                                    Count++;
                              }
                                     ct
                     }
              }
                            c
      }
                         ni

}
void Khoitao(void)
          tro


{
      PCON|=128;
      EA=1;
ec




      ES=1;
      SM0=0;
      SM1=1;
el




      Ktnhan=nhanmau=1;
      Chay=1;
      P0=P1=P2=0;
      P3_0=1;
      nLap=1;
}
// Ham tao tre
void delay(void)
{
unsigned char data i;
     i=10;
     while(i--);
}
// Ham hien thi mau cam
void Cam(void)
{




                                           t
                                         ne
     while(nLap--)
     {
            Data=1;




                                      u.
            for(j=0;j<32;j++){
                   Clock=1;
                   Data=0;
                                  ct
                   Clock=0;
                   Pdo=Pxanh=MQ[j];
                         c
                   delay();
                      ni

                   Pxanh=Pdo=0;
            }
         tro


     }

}
ec




// Ham hien thi mau xanh
void Xanh(void)
{
el




     while(nLap--)
     {
            Data=1;
            for(j=0;j<32;j++){
                   Clock=1;
                   Data=0;
                   Clock=0;
                   Pxanh=MQ[j];
                   delay();
Pxanh=0;
            }
      }


}
// Ham hien thi mau do
void Do(void)




                                      t
                                    ne
{
      while(nLap--)
      {




                                 u.
            Data=1;
            for(j=0;j<32;j++){
                    Clock=1;
                                 ct
                    Data=0;
                    Clock=0;
                         c
                    Pdo=MQ[j];
                      ni

                    delay();
                    Pdo=0;
          tro


            }
      }
}
ec




// Ham thay doi mang hien thi
void change(void)
{
el




      MQ[0]=MQ[1];MQ[1]=MQ[2];MQ[2]=MQ[3];MQ[3]=MQ[4];
      MQ[4]=MQ[5];MQ[5]=MQ[6];MQ[6]=MQ[7];MQ[7]=MQ[8];
      MQ[8]=MQ[9];MQ[9]=MQ[10];MQ[10]=MQ[11];MQ[11]=MQ[12];
      MQ[12]=MQ[13];MQ[13]=MQ[14];MQ[14]=MQ[15];MQ[15]=MQ[16];
      MQ[16]=MQ[17];MQ[17]=MQ[18];MQ[18]=MQ[19];MQ[19]=MQ[20];
      MQ[20]=MQ[21];MQ[21]=MQ[22];MQ[22]=MQ[23];MQ[23]=MQ[24];
      MQ[24]=MQ[25];MQ[25]=MQ[26];MQ[26]=MQ[27];MQ[27]=MQ[28];
      MQ[28]=MQ[29];MQ[29]=MQ[30];MQ[30]=MQ[31];
}
// Ham tim vitri ki tu hien thi trong bang chu cai va chu so
unsigned char Chiso(unsigned char chr)
{
      unsigned char data End,Start,Mid,Mctam;
      if(chr==Mchar[0][0]){
               return 0;
      }else if(chr==Mchar[35][0]){




                                                  t
                                                ne
               return 35;
      }else{
               End=35;




                                             u.
               Start=0;
               while(1){
                      Mid=(End+Start)/2;
                                      ct
                      Mctam=Mchar[Mid][0];
                      if(chr==Mctam){
                              c
                             return Mid;
                           ni

                      }else if(chr<Mctam){
                               End=Mid;
          tro


                      }else{
                               Start=Mid;
                      }
ec




               }
      }
}
el




void Chaychu(void)
{
      unsigned char vitri;

      for(j=0;j<32;j++){
               MQ[j]=0;
      }
      for(i=0;i<Count;i++)
      {
if(MC[i]==32){
                      change();
                      MQ[31]=0;
                      if(Mau==Mxanh)Xanh();
                      else if(Mau==Mdo)Do();
                      else Cam();
                      change();




                                                 t
                                               ne
                      MQ[31]=0;
                      if(Mau==Mxanh)Xanh();
                      else if(Mau==Mdo)Do();




                                            u.
                      else Cam();
             }else{
                      vitri=Chiso(MC[i]);
                                    ct
                      for(dem=1;dem<7;dem++){
                            change();
                             c
                            MQ[31]=Mchar[vitri][dem];
                          ni

                            if(Mau==Mxanh)Xanh();
                            else if(Mau==Mdo)Do();
          tro


                            else Cam();
                      }
             }
ec




      }
      if(!Chay){
             for(i=0;i<32;i++){
el




                      change();
                      MQ[31]=0;
                      if(Mau==Mxanh)Xanh();
                      else if(Mau==Mdo)Do();
                      else Cam();
             }
      }
}
// Chuong trinh chinh
void main()
{
     Khoitao();
     REN=1;
     while(1){
              while(Chay);
              Chaychu();




                                  t
                                ne
     }
}




                             u.
                         c   ct
                      ni
         tro
ec
el

Más contenido relacionado

La actualidad más candente (14)

7 can ban assembly
7 can ban assembly7 can ban assembly
7 can ban assembly
 
Lap trinh assembler
Lap trinh assemblerLap trinh assembler
Lap trinh assembler
 
Chuong 01
Chuong 01Chuong 01
Chuong 01
 
lap trinh c Phan2 chuong5
 lap trinh c Phan2 chuong5 lap trinh c Phan2 chuong5
lap trinh c Phan2 chuong5
 
Lập trình C cơ bản cho vi điều khiển
Lập trình C cơ bản cho vi điều khiểnLập trình C cơ bản cho vi điều khiển
Lập trình C cơ bản cho vi điều khiển
 
Hàm can bản
Hàm can bảnHàm can bản
Hàm can bản
 
Tin học ứng dụng trong kinh doanh data4u
Tin học ứng dụng trong kinh doanh data4uTin học ứng dụng trong kinh doanh data4u
Tin học ứng dụng trong kinh doanh data4u
 
Phần 6: Hàm
Phần 6: HàmPhần 6: Hàm
Phần 6: Hàm
 
Quan ly bo nho trong C#
Quan ly bo nho trong C#Quan ly bo nho trong C#
Quan ly bo nho trong C#
 
Chương trình dịch nguyễn văn linh[bookbooming.com]
Chương trình dịch   nguyễn văn linh[bookbooming.com]Chương trình dịch   nguyễn văn linh[bookbooming.com]
Chương trình dịch nguyễn văn linh[bookbooming.com]
 
Giao trinh thiet ke web bai 4 - php
Giao trinh thiet ke web   bai 4 - phpGiao trinh thiet ke web   bai 4 - php
Giao trinh thiet ke web bai 4 - php
 
Phần 3: Các kiểu dữ liệu cơ sở
Phần 3: Các kiểu dữ liệu cơ sởPhần 3: Các kiểu dữ liệu cơ sở
Phần 3: Các kiểu dữ liệu cơ sở
 
Phần 12: Hàm (Nâng cao)
Phần 12: Hàm (Nâng cao)Phần 12: Hàm (Nâng cao)
Phần 12: Hàm (Nâng cao)
 
lap trinh assembly cho VXL
lap trinh  assembly cho VXLlap trinh  assembly cho VXL
lap trinh assembly cho VXL
 

Destacado

He thong chong trom bang hong ngoai dung vi xu ly
He thong chong trom bang hong ngoai dung vi xu lyHe thong chong trom bang hong ngoai dung vi xu ly
He thong chong trom bang hong ngoai dung vi xu ly
Dao Nguyen Thi
 
Tính toán điện trở cho led
Tính toán điện trở cho ledTính toán điện trở cho led
Tính toán điện trở cho led
trungnb22
 
8051 Danh Cho Nguoi Chua Biet Gi
8051 Danh Cho Nguoi Chua Biet Gi8051 Danh Cho Nguoi Chua Biet Gi
8051 Danh Cho Nguoi Chua Biet Gi
kakaruchi
 
50 mach dieu_khien_bang_cam_bien_7555
50 mach dieu_khien_bang_cam_bien_755550 mach dieu_khien_bang_cam_bien_7555
50 mach dieu_khien_bang_cam_bien_7555
my chieu
 
Bai tap thuc hanh nhap mon tin hoc
Bai tap thuc hanh nhap mon tin hocBai tap thuc hanh nhap mon tin hoc
Bai tap thuc hanh nhap mon tin hoc
Hồ Lợi
 
[Share] tổng hợp các bài tập c căn bản
[Share] tổng hợp các bài tập c căn bản[Share] tổng hợp các bài tập c căn bản
[Share] tổng hợp các bài tập c căn bản
Khong Biet Khong Quen
 
Bai tap lap trinh c
Bai tap lap trinh  cBai tap lap trinh  c
Bai tap lap trinh c
tiểu minh
 

Destacado (20)

Chuong6 hoạt động ngắt
Chuong6 hoạt động ngắtChuong6 hoạt động ngắt
Chuong6 hoạt động ngắt
 
11 Lập trình ngắt
11 Lập trình ngắt11 Lập trình ngắt
11 Lập trình ngắt
 
13 DC Bước - Bàn phím DAC
13 DC Bước - Bàn phím DAC13 DC Bước - Bàn phím DAC
13 DC Bước - Bàn phím DAC
 
He thong chong trom bang hong ngoai dung vi xu ly
He thong chong trom bang hong ngoai dung vi xu lyHe thong chong trom bang hong ngoai dung vi xu ly
He thong chong trom bang hong ngoai dung vi xu ly
 
00 su dung_plc_dieu_khien_he_thong_truyen_dong_trong_robot_cong_nghiep_3002
00 su dung_plc_dieu_khien_he_thong_truyen_dong_trong_robot_cong_nghiep_300200 su dung_plc_dieu_khien_he_thong_truyen_dong_trong_robot_cong_nghiep_3002
00 su dung_plc_dieu_khien_he_thong_truyen_dong_trong_robot_cong_nghiep_3002
 
Quy trinh tieu chuan sua chua tu lanh 123thue
Quy trinh tieu chuan sua chua tu lanh 123thueQuy trinh tieu chuan sua chua tu lanh 123thue
Quy trinh tieu chuan sua chua tu lanh 123thue
 
Tính toán điện trở cho led
Tính toán điện trở cho ledTính toán điện trở cho led
Tính toán điện trở cho led
 
ở đâY là những mạch ứng dụng tham khảo trong thiết kế mạch nguồn cho mạch như...
ở đâY là những mạch ứng dụng tham khảo trong thiết kế mạch nguồn cho mạch như...ở đâY là những mạch ứng dụng tham khảo trong thiết kế mạch nguồn cho mạch như...
ở đâY là những mạch ứng dụng tham khảo trong thiết kế mạch nguồn cho mạch như...
 
Chuong 6 truyen thong noi tiep
Chuong 6 truyen thong noi tiepChuong 6 truyen thong noi tiep
Chuong 6 truyen thong noi tiep
 
Bai Tap Vi Xu Ly
Bai Tap Vi Xu LyBai Tap Vi Xu Ly
Bai Tap Vi Xu Ly
 
8051 Danh Cho Nguoi Chua Biet Gi
8051 Danh Cho Nguoi Chua Biet Gi8051 Danh Cho Nguoi Chua Biet Gi
8051 Danh Cho Nguoi Chua Biet Gi
 
Tong hop tai lieu bep tu
Tong hop tai lieu bep tuTong hop tai lieu bep tu
Tong hop tai lieu bep tu
 
Cac mach dien hay
Cac mach dien hayCac mach dien hay
Cac mach dien hay
 
50 mach dieu_khien_bang_cam_bien_7555
50 mach dieu_khien_bang_cam_bien_755550 mach dieu_khien_bang_cam_bien_7555
50 mach dieu_khien_bang_cam_bien_7555
 
Bai tap thuc hanh nhap mon tin hoc
Bai tap thuc hanh nhap mon tin hocBai tap thuc hanh nhap mon tin hoc
Bai tap thuc hanh nhap mon tin hoc
 
BÀI GIẢNG SỬA CHỮA BOARD MÁY LẠNH 2 CỤM (PHẦN CƠ BẢN)
BÀI GIẢNG SỬA CHỮA BOARD MÁY LẠNH 2 CỤM (PHẦN CƠ BẢN)BÀI GIẢNG SỬA CHỮA BOARD MÁY LẠNH 2 CỤM (PHẦN CƠ BẢN)
BÀI GIẢNG SỬA CHỮA BOARD MÁY LẠNH 2 CỤM (PHẦN CƠ BẢN)
 
Các loại ic
Các loại icCác loại ic
Các loại ic
 
[Share] tổng hợp các bài tập c căn bản
[Share] tổng hợp các bài tập c căn bản[Share] tổng hợp các bài tập c căn bản
[Share] tổng hợp các bài tập c căn bản
 
ĐIỆN TỬ CƠ BẢN NÂNG CAO
ĐIỆN TỬ CƠ BẢN NÂNG CAOĐIỆN TỬ CƠ BẢN NÂNG CAO
ĐIỆN TỬ CƠ BẢN NÂNG CAO
 
Bai tap lap trinh c
Bai tap lap trinh  cBai tap lap trinh  c
Bai tap lap trinh c
 

Similar a C cho 8051

Tai lieu lap trinh c cho 8051
Tai lieu lap trinh c cho 8051Tai lieu lap trinh c cho 8051
Tai lieu lap trinh c cho 8051
viet Nguyen
 
06 tong quan ve ngon ngu c
06 tong quan ve ngon ngu c06 tong quan ve ngon ngu c
06 tong quan ve ngon ngu c
Trí Nguyễn
 
chapter2.2.Variable.datatype.Arithmetic_Expression.pdf
chapter2.2.Variable.datatype.Arithmetic_Expression.pdfchapter2.2.Variable.datatype.Arithmetic_Expression.pdf
chapter2.2.Variable.datatype.Arithmetic_Expression.pdf
NguyenDiem50
 
Bài 4&5: Một số kiểu dữ liệu chuẩn và khai báo biến
Bài 4&5: Một số kiểu dữ liệu chuẩn và khai báo biếnBài 4&5: Một số kiểu dữ liệu chuẩn và khai báo biến
Bài 4&5: Một số kiểu dữ liệu chuẩn và khai báo biến
Châu Trần
 
Danhsachlienket -phpapp02
Danhsachlienket -phpapp02Danhsachlienket -phpapp02
Danhsachlienket -phpapp02
quoclong90
 
Danh Sach Lien Ket
Danh Sach Lien KetDanh Sach Lien Ket
Danh Sach Lien Ket
Tony Nhân
 
Bài 4,5:Một số kiểu dữ liệu chuẩn,Khai báo biến
Bài 4,5:Một số kiểu dữ liệu chuẩn,Khai báo biếnBài 4,5:Một số kiểu dữ liệu chuẩn,Khai báo biến
Bài 4,5:Một số kiểu dữ liệu chuẩn,Khai báo biến
indochinasp
 
Bai giangtrenlop
Bai giangtrenlopBai giangtrenlop
Bai giangtrenlop
Hồ Lợi
 

Similar a C cho 8051 (20)

Tai lieu lap trinh c cho 8051
Tai lieu lap trinh c cho 8051Tai lieu lap trinh c cho 8051
Tai lieu lap trinh c cho 8051
 
Bài giảng Lập trình cơ bản - truongkinhtethucpham.com
Bài giảng Lập trình cơ bản - truongkinhtethucpham.comBài giảng Lập trình cơ bản - truongkinhtethucpham.com
Bài giảng Lập trình cơ bản - truongkinhtethucpham.com
 
Bai02 java introduction
Bai02 java introductionBai02 java introduction
Bai02 java introduction
 
Giới thiệu ngôn ngữ lập trình C++
Giới thiệu ngôn ngữ lập trình C++Giới thiệu ngôn ngữ lập trình C++
Giới thiệu ngôn ngữ lập trình C++
 
06 tong quan ve ngon ngu c
06 tong quan ve ngon ngu c06 tong quan ve ngon ngu c
06 tong quan ve ngon ngu c
 
chapter2.2.Variable.datatype.Arithmetic_Expression.pdf
chapter2.2.Variable.datatype.Arithmetic_Expression.pdfchapter2.2.Variable.datatype.Arithmetic_Expression.pdf
chapter2.2.Variable.datatype.Arithmetic_Expression.pdf
 
Bài 4&5: Một số kiểu dữ liệu chuẩn và khai báo biến
Bài 4&5: Một số kiểu dữ liệu chuẩn và khai báo biếnBài 4&5: Một số kiểu dữ liệu chuẩn và khai báo biến
Bài 4&5: Một số kiểu dữ liệu chuẩn và khai báo biến
 
Danhsachlienket -phpapp02
Danhsachlienket -phpapp02Danhsachlienket -phpapp02
Danhsachlienket -phpapp02
 
Danh Sach Lien Ket
Danh Sach Lien KetDanh Sach Lien Ket
Danh Sach Lien Ket
 
Bài 4,5:Một số kiểu dữ liệu chuẩn,Khai báo biến
Bài 4,5:Một số kiểu dữ liệu chuẩn,Khai báo biếnBài 4,5:Một số kiểu dữ liệu chuẩn,Khai báo biến
Bài 4,5:Một số kiểu dữ liệu chuẩn,Khai báo biến
 
Hàm và Chuỗi
Hàm và ChuỗiHàm và Chuỗi
Hàm và Chuỗi
 
Chuong 2@ngon ngu c
Chuong 2@ngon ngu cChuong 2@ngon ngu c
Chuong 2@ngon ngu c
 
Slide pointer sepro
Slide pointer seproSlide pointer sepro
Slide pointer sepro
 
Lập trình hướng đối tượng - p2
Lập trình hướng đối tượng - p2Lập trình hướng đối tượng - p2
Lập trình hướng đối tượng - p2
 
344444
344444344444
344444
 
Bai giangtrenlop
Bai giangtrenlopBai giangtrenlop
Bai giangtrenlop
 
Book
BookBook
Book
 
Book
BookBook
Book
 
BÀI 3: Các khái niệm cơ bản trong lập trình - Giáo trình FPT
BÀI 3: Các khái niệm cơ bản trong lập trình - Giáo trình FPTBÀI 3: Các khái niệm cơ bản trong lập trình - Giáo trình FPT
BÀI 3: Các khái niệm cơ bản trong lập trình - Giáo trình FPT
 
Session 4
Session 4Session 4
Session 4
 

C cho 8051

  • 1. Đề cương ứng dụng lập trình C cho vi điều khiển 8051 Bài 1: Ngôn ngữ C – Trình dịch Keil C I. Ngôn ngữ C cho vi điều khiển 1, Giới thiệu ngôn ngữ C Trong kỹ thuật lập trình vi điều khiển nói chung, ngôn ngữ lập trình được sử dụng thường chia làm 2 loại: Ngôn ngữ bậc thấp và Ngôn ngữ bậc cao. t ne Ngôn ngữ bậc cao là các ngôn ngữ gần vơi ngôn ngữ con người hơn, do đó việc lập trình bằng các ngôn ngữ này trở nên dễ dàng và đơn giản hơn. Có thể kể đến một số ngôn ngữ lập trình bậc cao như C, Basic, Pascal… trong dó C là ngôn u. ngữ thông dụng hơn cả trong kỹ thuật vi điều khiển. Về bản chất, sử dụng các ngôn ngữ này thay cho ngôn ngữ bậc thấp là giảm tải cho lập trình viên trong việc nghiên cứu các tập lệnh và xây dựng các cấu trúc giải thuật. Chương trình viết bằng ngôn ngữ bậc cao cũng sẽ được ct một phần mềm trên máy tính gọi là trình biên dịch (Compiler) chuyển sang dạng hợp ngữ trước khi chuyển sang mã máy. c Khi sử dụng ngôn ngữ C người lập trình không cần hiểu sâu sắc về cấu trúc của bộ vi ni điều khiển. Có nghĩa là với một người chưa quen với một vi điểu khiển cho trước sẽ xây dựng được chương trình một cách nhanh chóng hơn, do không phải mất thời gian tìm hiểu tro kiến trúc của vi điều khiển đó. Và việc sử dụng lại các chương trình đã xây dựng trước đó cũng dễ dàng hơn, có thể sử dụng toàn bộ hoặc sửa chữa một phần. ec 2. Ngôn ngữ C 2.1 Kiểu dữ liệu el 2.1.1 Kiểu dữ liệu trong C Kiểu Số Byte Khoảng giá trị Char 1 -128 – +127 Unsigned char 1 0 – 255 Int 2 -32768 - +32767 Unsigned int 2 0 - 65535 Long 4 -2147483648 - +2147483647
  • 2. Unsigned long 4 0 – 4294697295 Float 4 * Khai báo biến: - Cú pháp: Kiểu_dữ_liệu Vùng_nhớ Tên_biến _at_ Đia_chỉ; Ví dụ: Unsigned char data x; t ne - Khi khai báo biến có thể gán luôn cho biến giá trị ban đầu. Ví dụ: Thay vì: unsigned char x; u. x = 0; Ta chỉ cần: unsigned char x = 0; - Có thể khai báo nhiều biến cùng một kiểu một lúc. ct Ví dụ: unsigned int x,y,z,t; - Chỉ định vùng nhớ: từ khoá “Vùng_nhớ” cho phép người dùng có thể chỉ ra vùng nhớ sử c dụng để lưu trữ các biến sử dụng trong chương trình. Các vùng nhớ có thể sử dụng là: ni CODE, DATA, DATAB, IDATA, PDATA, XDTA. Khi không khai báo vùng nhớ trình dịch Keil C sẽ mặc định đó là vùng nhớ DATA. tro Vùng nhớ Ý nghĩa CODE Bộ nhớ mã nguồn chương trình ec DATA Bộ nhớ dữ liệu gồm 128 Byte thấp của RAM trong vi điều khiển BDATA Bộ nhớ dữ liệu có thê định địa chỉ bit, nằm trong vùng nhớ DATA IDATA Bộ nhớ dữ liệu gồm 128 Byte cao của RAM trong vi điều khiển chỉ có ở một el số dòng vi điều khiển sau này PDATA Bố nhớ dữ liệu ngoài gồm 256 Byte, được truy cập bởi địa chỉ đặt trên P0 XDATA Bộ nhớ dữ liệu ngoài có dung lượng có thể lên đến 64 KB, được truy cập bởi địa chỉ đặt trên P0 và P2 * Định nghĩa lại kiểu - Cú pháp: typedef Kiễu_dữ_liệu Tên_biến; - Ten_biến sau này sẽ được sử dụng như một kiểu dữ liệu mới và có thể dùng để khai báo các biến khác
  • 3. Ví dụ: typedef int m5[5]; Dùng tên m5 khai báo hai biến tên a và b có kiểu dữ liệu là mảng 1 chiểu 5 phần tử: m5 a,b; 2.1.2 Kiểu dữ liệu trong Keil C Kiểu Số bit Bit 1 t ne Sbit 1 Sfr 8 Sfr16 16 u. - bit : dùng để khai báo các biến có giá trị 0 hoặc một hay các biến logic trên vùng RAM của vi điều khiển. Khi khai báo biến kiểu bit trình dịc Keil C sẽ mặc định vùng nhớ sử dụng là BDATA. ct ` - sbit, sfr, sfr16: dùng để định nghĩa các cho các thanh ghi chức năng hoặc các cổng trên vi điều khiển dùng để truy nhập các đoạn dữ liệu 1 bit, 8 bit, 16 bit c 2.1.3 Mảng ni Mảng là một tập hợp nhiều phần tử cùng một kiểu giá trị và chung một tên. Các phần tử của mảng phân biệt với nhau bởi chỉ số hay số thứ tự của phần tử trong dãy phẩn tử. Mỗi tro phần tử có vai trò như một biến và lưu trữ được một giá trị độc lập với các phần tử khác của mảng. Mảng có thể là mảng một chiều hoặc mảng nhiều chiều ec Khai báo: - Cú pháp: Tên_kiểu Vùng_nhớ Tên_mảng[số_phần_tử_mảng]; Khi bỏ trống số phần tử mảng ta sẽ có mảng có số phần tử bất kì. el Ví dụ: Unsigned int data a[5],b[2] [3]; Với khai báo trên ta sẽ có: mảng a là mảng một chiều 5 phần tử. Mảng b là mảng hai chiều, tổng số phần tử là 6. Chỉ số của mảng bắt đầu từ số 0. Mảng có bao nhiêu chiều phải cung cấp đầy đủ bấy nhiêu chỉ sô Ví du: phần tử mảng b[0] [1] là đúng Khi viết b[0] là sai 2.1.4. Con trỏ
  • 4. Khi ta khai báo một biến, biến đó sẽ được cấp phát một khoảng nhớ bao gồm một số byte nhất định dùng để lưu trữ giá trị. Địa chỉ đầu tiên của khoảng nhớ đó chính là địa chỉ của biến được khai báo. Con trỏ là một biến dùng để chứa địa chỉ mà không chứa giá trị, hay giá trị của con trỏ chính là địa chỉ khoảng nhớ mà nó trỏ tới. Với các vùng nhớ cụ thể con trỏ tới vùng nhớ đó chiếm dung lượng phụ thuộc vào độ lớn của vùng nhớ đó. Con trỏ tổng quát khi không xác định trước vùng nhớ sẽ có dung t ne lượng lớn nhất vì vậy tốt nhất nên sử dụng con trỏ cụ thể. Loại con trỏ Kích thước Con trỏ tổng quát 3 byte u. Con trỏ XDATA 2 byte Con trỏ CODE 2 byte Con trỏ DATA 1 byte ct Con trỏ IDATA 1 byte Con trỏ PDATA 1 byte c ni Khai báo biến con trỏ: - Cú pháp: Kiểu_Dữ_liệu Vùng_nhớ *Tên_biến; tro - Ví dụ: int *int_ptr; long data *long_ptr; ec - khi không chỉ rõ vùng nhớ con trỏ sẽ được coi là con trỏ tổng quát. 2.1.5 Kiểu dữ liệu cấu trúc Kiểu dữ liệu cấu trúc là một tập hợp các biến, các mảng và cả các kiểu cấu trúc khác el được biểu thị bởi một tên duy nhất. kiểu dữ liệu cấu trúc dùng để lưu trữ các giá trị, thông tin có liên quan đến nhau. Định nghĩa và khai báo biến cấu trúc: - Định nghĩa: typedef struct { Khai báo các biến thành phần; } Tên_kiểu_cấu_trúc; - Khai báo: Tên_kiểu_cấu_trúc Vùng_nhớ Tên_biến; Ví dụ: typedef struct { char day;
  • 5. char month; int year; } Date_type; Date_type date,date_arr[5]; 2.2 Phép toán Phép gán kí hiệu: “=”. - Cú pháp: Biến_1 = Biến_2; t ne Trong đó Biến_2 có thể là giá trị xác định cũng có thể là biến. 2.2.1 Phép toán số học Phép toán ý nghĩa Ví dụ u. + Phép cộng X=a+b - Phép trừ X=a-b * Phép nhân X=a*b ct / Phép chia lấy phần X=a/b nguyên (a=9, b=2 → X=4) c % Phép chia lấy phần dư a%b ni (a=9, b=2 → X=1) tro 2.2.2 Phép toán Logic AND: && ec OR: || NOT: ! el 2.2.3 Các phép toán so sánh:
  • 6. Phép ý nghĩa Ví dụ toán > So sánh lớn hơn a>b 4>5 các giá trị 0 t >= So sánh lớn hơn hoặc bằng a>=b ne 6>=2 các giá trị 1 < So sánh nhỏ hơn a<b u. 6<7 các giá trị 1 ct <= So sánh nhỏ hơn hoặc bằng a<=b c 8<=5 các giá ni trị 0 == So sánh bằng nhau a==b tro 6==6 các giá trị 1 != So sánh khác nhau a!=b ec 9!=9 các giá trị 0 el 2.2.4 Phép toán thao tác Bit Phép toán Ý nghĩa Ví dụ & Phép và (AND) Bit_1 & Bit_2 | Phép hoặc (OR) Bit_1 | Bit_2 ! Phép đảo (NOT) !Bit_1 ^ Phép hoặc loại trừ (XOR) Bit_1 ^ Bit_2 << Dịch trái a<<3 >> Dịch phải a>>4 ~ Lấy bù theo bit ~a
  • 7. 2.2.5 Phép toán kết hợp Phép toán Ví dụ += a+=5 <=> a=a+5 -= a-=5 <=> a=a-5 *= a*=5 <=> a=a*5 /= a/=5 <=> a=a/5 t ne %= a%=5 <=> a=a%5 2.3 Cấu trúc chương trình C u. 2.3.1 Cấu trúc chương trình * Cấu trúc ct 1. Khai báo chỉ thị tiền xử lý 2. Khai báo các biến toàn cục 3. Khai báo nguyên mẫu các hàm c 4. Xây dựng các hàm và chương trình chính ni * Ví dụ: #include<regx51.h> tro Khai báo chỉ thị tiền xử lý #include<string.h> #define Led1 P1_0 ec Unsigned char code Led_arr[3]; Unsigned char data dem; Khai báo biến toàn cục Unsigned int xdata X; el Void delay(unsigned int n); bit kiemtra(unsigned int a); Khai báo nguyên mẫu hàm void delay(unsigned int n) { Khai báo biến cục bộ; Mã chương trình trễ; }
  • 8. Void main() Xây dựng các hàm và chương { trình chính Khai báo biến cụ bộ; Mã chương trình chính; } Bit kiemtra(unsigned int a) { t ne Khai báo biến cục bô; Mã chương trình kiểm tra biến a; } u. Chú ý: Hàm không khai báo nguyên mẫu phải được xây dựng trước hàm có lời gọi hàm đó. Ở ví dụ trên do hàm “bit kiemtra(unsigned int a)” đã được khai báo nguyên mẫu hàm ở trên nên có thể xây dựng hàm ở bất kì vị trí nào trong chương trình. ct 2.3.2 Chỉ thị tiền xử lý c Các chỉ thị tiền sử lý không phải là các lệnh của ngôn ngữ C mà là các lệnh giúp cho ni việc soạn thảo chương trình nguồn C trước khi biên dịch. Khi dịch một chương trình C thì không phải chính bản chương trình nguồn mà ta soạn thảo được dịch. Trước khi dịch, các tro lệnh tiền xử lý sẽ chỉnh lý bản gốc, sau đó bản chỉnh lý này sẽ được dịch. Có ba cách chỉnh lý được dùng là: + Phép thay thế #define ec + Phép chèn tệp #include + Phép lựa chọn biên dịch #ifdef Các chỉ thị tiền xử lý giúp ta viết chương trình ngắn gọn hơn và tổ chức biên dịch, el gỡ rối chương trình linh hoạt, hiệu quả hơn. * Chỉ thị #define Chỉ thị #define cho phép tạo các macro thay thế đơn giản - Cú pháp: #define Tên_thay_thế dãy_kí_tự Một Tên_thay_thế có thể được định nghĩa lại nhiều lần, nhưng trước khi định nghĩa lại phải giải phóng định nghĩa bằng chỉ thị: #undef Tên_thay_thế - Ví dụ: #define N 100 * Chỉ thị #include
  • 9. Chỉ thị #include báo cho trình biên dịch nhận nội dung của tệp khác và chèn vào tệp chương trình nguồn mà ta soạn thảo. - Cú pháp: Cách 1: #include<tên_tệp> Cách 2: #include“tên_tệp” - Ví dụ: Cách 1: #include<regx51.h> t ne Ở cách này tệp regx51.h sẽ được tìm trong thư mục INC để chèn vào chương trình nguồn. Cách 2: #include“regx51.h” u. Ở cách này tệp regx51.h sẽ được tìm trong thư mục chứa chương trình nguồn nếu không có mới tìm trong thư mục INC Khi muốn chèn tệp ngoài thư viện hoặc ngoài thư mục chứa chương trình nguồn thì ct tên_tệp sẽ bao gồm cả đường dẫn thư mục chứa tệp. c * Chỉ thị #ifdef ni Chỉ thị #ifdef này thường dùng để biên dịch các tệp thư viện. - Cú pháp: tro Cách 1: #ifdef ten_macro Đoạn chương trình #endif ec Cách 2: #ifdef ten_macro Đoạn chương trình 1 #else el Đoạn chương trình 2 #endif Ở cách 1 nếu tên_macro đã được định nghĩa “Đoạn chương trình” sẽ được dịch ngược lại “Đoạn chương trình” sẽ bị bỏ qua. * Chỉ thị #ifndef Chỉ thị #ifndef này thường dùng để biên dịch các tệp thư viện. - Cú pháp: Cách 1: #ifndef ten_macro
  • 10. Đoạn chương trình #endif Cách 2: #ifndef ten_macro Đoạn chương trình 1 #else Đoạn chương trình 2 #endif t ne Ở cách 1 nếu tên_macro chưa được định nghĩa “Đoạn chương trình” sẽ được dịch ngược lại “Đoạn chương trình” sẽ bị bỏ qua. u. 2.3.3 Chú thích trong chương trình Việc viết chú thích trong trình nhằm mục đích giải thích ý nghĩa của câu lệnh, đoạn chương trình hoặc hàm hoạt động như thế nào và làm gì. Viết chú thích sẽ giúp cho người ct đọc có thể hiểu được chương trình dễ dàng và nhanh chóng hơn, sửa lỗi đơn giản hơn hoặc giúp cho ta xem lại chương trình cũ mà ta đã làm trở lên nhanh hơn. c Chú thích trong chương trình sẽ không ảnh hưởng đến chương trình mà ta soạn thảo ni vì trình dịch sẽ bỏ qua tất cả lời chú thích khi biên dịch chương trình sang mã máy. Lời giải thích được đặt sau dấu “//” nếu chú thích chỉ viết trên một dòng hoặc trong tro cặp dấu “*” và “*”. 3 Các lệnh cơ bản trong C + Câu lệnh rẽ nhánh if: ec - Cấu trúc: if(dieu_kien) { // Đoạn chương trình el } Giải thích: nếu dieu_kien đúng thì xư lí các câu lệnh bên trong còn sai thì nhảy qua. - Cấu trúc: if(dieu_kien) { // Đoạn chương trình 1 } else {
  • 11. // Đoạn chương trình 2 } Giải thích: nếu dieu_kien đúng thì xử lí “Đoạn chương trình 1” bên trong còn sai thì x ử l ý “Đoạn chương trình 1” + Câu lệnh lựa chọn: Cấu trúc: switch(bien) t ne { case gia_tri_1: {//các câu lệnh break;} case gia_tri_2: {//các câu lệnh break;} u. case gia_tri_3: {//các câu lệnh break;} ……………………………………... case gia_tri_n: {//các câu lệnh break;} ct } Giải thích: tuỳ vào biến có gia_tri_1 thì thực hiện các câu lệnh tương ứng rồi sau đó c thoát khỏi cấu trúc nhờ câu lệnh break. ni Biến có gia_tri_2 thì thực hiện câu lệnh tương ứng rồi thoát. ……………………. tro Biến có gia_tri_n thì thực hiện các câu lệnh tương ứng rồi thoát. + Vòng lặp xác định: Cấu trúc: for(n=m;n<l;n++) ec { // các câu lệnh xử lí } el Giải thích: m,l là giá trị(m>l), còn n là biến. thực hiện lặp các câu lệnh (l-m) lần. + Vòng lặp không xác định while: Cấu trúc: while(dieu_kien) { // các câu lệnh }
  • 12. Giả thích: thực hiện lặp các câu lệnh khi điều kiện đúng nếu điều kiện sai thì thoát khỏi vòng lặp. + Vòng lặp không xác định do while: Cấu trúc: do { // các câu lệnh } while(dieu_kien); t ne Giả thích: thực hiện lặp các câu lệnh sau đó kiểm tra điều kiện nếu đúng, nếu sai thì thoát khỏi vòng lặp. u. II. Trình biên dịch Keil C (compiler) 2.1. Khởi tạo cho Project. ct c ni tro ec el Để tạo 1 project mới chọn project → New project như sau:
  • 13. t ne u. c ct ni Hộp thoại create new project hiện ra như sau: tro ec el
  • 14. Đánh tên và chuyển đến thư mục bạn lưu project.bạn nên tạo mỗi một thư mục cho 1 project. rồi chọn save. Hộp thoại sau hiện ra: t ne u. c ct ni tro ec Trong này có 1 loạt các hãng điện tử sản xuất 8051. bạn lập trình cho con nào thì chọn con đấy, kích chuột vào dấu + để mở rộng các con IC của các hang. ở đây ta lập trình cho AT89C51 của hang ATMEN nên ta chọn như trên. el Khi chọn chip thì ngay lập tức 1 bảng hiện ra 1 số tính năng của chip các bạn có thể nhìn thấy: 8051 based fully static 24Mhz …. nhập OK, chọ câu trả lời NO khi được hỏi “copy standard 8051 startup code to project and addfile to project” vì nếu chon YES chỉ làm cho file lập trình của bạn thêm nặng.
  • 15. Để tạo một file code các bạn chọ file→new hoặc ấn ctrl+N. như sau: t ne u. c ct ni tro ec Cửa sổ text1 hiện ra. Tiếp theo bạn chọn File → save As hoặc Ctrl+S, để lưu File mặc dù chưa có gì như sau: el
  • 16. t ne u. c ct ni Được cửa sổ sau: tro ec el Các bạn nhập tên vào text box file name.chú ý tên gì cũng được nhưng không được thiếu đuôi mở rộng .C, và nhấn SAVE.
  • 17. Trong ô bên trái màn hình, cửa sổ PROJECT WORKSPACE, các bạn mở rộng cái target 1 ra như sau: t ne u. c ct ni Nhấp chuột phải nên SOURCE GROUP, chọn Add file to Group “Source Group 1” hộp thoại hiện ra chọn file .C mà các bạn vừa SAVE rồi nhấn Add 1lấn rồi nhấn Close. nếu bạn tro nhấn Add 2 lần nó sẽ thong báo là file đã add bạn chỉ việc OK rồi nhấn Close. Được như sau: ec el
  • 18. t ne u. ct Bây giờ trong hình nhìn thấy trong Source Group 1 có file VIDU.C. các bạn nhấp chuột phải vào vùng soạn thảo file VIDU.C để thêm file thư viện. Chon Insert c “#include<REGX51.H>”. ni tro ec el
  • 19. t ne u. c ct ni tro Phần cuối cùng của công việc khởi tạo là các bạn viết lời giải thích cho dự án của mình. phần này rất cần thiết vì nó để người khác hiểu mình làm gì trong project này và khi mình ec cần sử dụng lại code đọc lại còn biết nó là cái gì. el 2.2. Soạn thảo chương trình. Các bạn viết thử 1 chương trình làm ví dụ. khi viết xong mỗi dòng lệnh nên giải thích dòng lệnh đó làm gì. Ví dụ:
  • 20. t ne u. c ct ni tro ec el 2.3. Biên dịch một chương trình.
  • 21. Sau khi soạn thảo xong nhấn Ctrl+S để nhớ. Nhớ xong các bạn biên dịch chương trình bắng cách ấn phím F7 hoặc chọn Build target là biểu tượng ngay trên cửa sổ Workspace, như trên hình: t ne u. c ct ni tro ec el
  • 22. Để biên dịch chương trình thành file HEX các bạn chọn: Project→option for ‘target 1’ như hình vẽ: t ne u. c ct ni tro ec el
  • 23. Trong hộp thoại hiện ra, hãy check vào Creat HEX File như chỉ dẫn: chọn thẻ táp target nhập lại tần số thạch anh là 12Mhz. t ne u. c ct ni Để mô phỏng các bạn chon Debug→Start/stop debug session hoặc ấn Ctrl+F5, hoặc nhấn tro vào Icon chữ D màu đỏ trong cái kính lúp trên thanh công cụ. ec el
  • 24. t ne u. c ct Để hiển thi các cổng, các thanh ghi các bạn chon trong peripherals. ni tro ec el
  • 25. t ne u. c ct ni tro Các bạn thấy 1 cửa sổ nhỏ Parallel Port xuất hiện đó là cái để mô phỏng cho 1 cổng của AT89C51. dấu tick tương đương chân ở mức cao (5V), không tick chân ở mức thấp 0V.trong menu peripherals còn có các ngoại vi khác như timer, interrupt, serial. ec el
  • 26. t ne u. c ct ni tro Để chạy chương trình các bạn ấn chuột phải vào màn hình soạn thảo, rồi ấn F11.mỗi làn ấn sẽ chạy 1 lệnh.khi debug nếu các bạn chờ hàm delay lâu quá 1000 lần lặp các bạn nhấn ctrl+F11 để bỏ qua hàm. ec hoặc ấn F10 để chạy từng dòng lệnh el
  • 27. Bài 2: Điều khiển Led đơn, Led 7 thanh và nút nhấn I. Hiển thị Led đơn Bài toán:Ghép nối LED dơn với chân P1.0 của vi điều khiển, viết chương trình điều khiển LED nhấp nháy với thời gian trễ là 1s. t ne u. c ct ni tro + Lưu đồ thuật toán của bài LED nháy: ec START Khởi tạo hệ thống el Sáng Led Trễ 1S Tắt Led Trễ 1S
  • 28. + Chương trình điều khiển: */==================Bo tien xu li===================*/ #include<AT89x51.h> // Dinh kem file thu vien #define bat 1 // Dinh nghia gia tri bat den Led #define tat 0 // Dinh nghia gia tri tat den Led /*==================khai bao bien==================*/ t sbit Led = P1^0; // Khai bao bien Led kieu bit chan P1.0 ne /*================= Khai bao hàm==================*/ /*------------------------------ham tre -------------------------------------*/ u. void delay(long time) { while(time--); ct } c /*--------------------------------ham chinh--------------------------------*/ ni void main(void) { while(1) tro { Led = bat; // bat Led delay(25000); // tre 1s ec Led = tat; // tat Led delay(25000); //tre 1s el } } II. Phối hợp Led và nút nhấn 1. Phối hợp Led đơn và nút nhấn Bài toán: Một đèn Led được nối với chân P1.0 của vi điều khiển. Một công tắc START nối với chân P3.0 và công tắc STOP nối với chân P3.1 của vi điều khiển. hãy viết chương trình điều khiển để khi bật công tắc START thì Led sang, khi bật công tắc STOP thì Led tắt.
  • 29. t ne u. ct + Lưu đồ thuật giải của bài toán: c ni Start tro Led = tat ec Start = 0 Led = bat el Led = tat Stop = 0 + Chương trình điều khiển: */==================Bo tien xu li===================*/ #include<AT89x51.h> // Dinh kem file thu vien
  • 30. #define bat 1 // Dinh nghia gia tri bat den Led #define tat 0 // Dinh nghia gia tri tat den Led /*==================khai bao bien==================*/ sbit Led = P1^0; // Khai bao bien Led kieu bit chan P1.0 sbit STOP = P3^0; // cong tac STOP de tat Led sbit START = P3^1; // cong tac START de bat Led t /*=================== ham chinh==================*/ ne void main(void) { Led = tat; //ban dau tat Led u. while(1){ if((START==0)&&(STOP==1)) { ct Led = bat; } c if((START==1)&&(STOP==0)){ ni Led = tat; } } tro } ec el
  • 31. 2. Phối hợp Led 7 thanh và nút nhấn Các số P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 số nạp hex hiển g f e d c b a dp mov P1,# thị 0 1 0 0 0 0 0 0 1 81 1 1 1 1 1 0 0 1 1 cf t 2 0 1 0 0 1 0 0 1 92 ne 3 0 1 1 0 0 0 0 1 86 4 0 0 1 1 0 0 1 1 cc 5 0 0 1 0 0 1 0 1 a4 u. 6 0 0 0 0 0 1 0 1 a0 7 1 1 1 1 0 0 0 1 8f ct 8 0 0 0 0 0 0 0 1 80 9 0 0 1 0 0 0 0 1 84 c ni Bài toán: Một Nút bấm được nối với chân P3.4, hãy lập trình điều khiển đếm số lần ấn tro phím từ 0 đến 9 và hiển thị trên Led 7 thanh. ec el
  • 32. + Lưu đồ thuật giải: START Dem=0; t ctac==0? ne dem++; dem<=10? u. c ct dem=0; ni hiển thi ra Led 7 thanh tro + Chương trình điều khiển: ec /*==================Bo tien xu li===================*/ #include<AT89x51.h> // Dinh kem file thu vien /*=================Khai bao bien toan cuc=============*/ el sfr dataP = 0x90; // du lieu la P1 // ma 7 thanh tu 0 den 9 la // 0x81h,0xcfh,0x92h,0x86h,0xcch,0xa4,0xa0h,0x8fh,0x80h,0x84h. sbit ctac = P3^4; unsigned char dem=0; /*====================Khai bao ham==================*/ /*----------------------------ham delay========================*/ void delay(long time)
  • 33. { while(time--); } /*----------------------chuong trinh con kiem tra co phim nhan-------------*/ void phim_an(void) { t if(ctac==0) //co phim nhan ne { delay(500); //chong rung phim while(ctac==0); //Cho nha phim u. delay(500); // chong rung phim dem++; //tang bien dem ct if(dem==10) dem=0; } c } ni /*----------------hien thi so lan an phim------------------------------------------*/ void solan_an(void) { tro switch(dem) { case 0: {dataP=0x81;break;} ec case 1: {dataP=0xcf;break;} case 2: {dataP=0x92;break;} el case 3: {dataP=0x86;break;} case 4: {dataP=0xcc;break;} case 5: {dataP=0xa4;break;} case 6: {dataP=0xa0;break;} case 7: {dataP=0x8f;break;} case 8: {dataP=0x80;break;} case 9: {dataP=0x84;break;} }; }
  • 34. /*-------------------------chuong trinh chinh-------------------------------------------*/ void main(void) { dataP = 0x81; // ban dau la so 0 while(1){ phim_an(); t solan_an(); ne } } u. c ct ni tro ec el
  • 35. Bài 3 Hiển thị LCD, Giao tiếp bàn phím Hex, Hiển thị ma trận Led I. LCD 1. Ghép nối vi điều khiển với LCD 16x2. - Bảng mô tả sơ đồ chân của LCD 16x2: Chân Ký hiệu I/O Mô tả 1 Vss - Mass t 2 Vcc - Dương nguồn 5v ne 3 VEE - Cấp nguồn điều khiển tương phản 4 RS I RS=0 chon thanh ghi lệnh RS=1 chon thanh ghi dữ liệu u. 5 R/W I R/W=1 đọc dữ liệu, R/W=1 ghi 6 E I/O Cho phép ct 7 DB0 I/O Bit dữ liệu 8 DB1 I/O Nt c 9 DB2 I/O Nt ni 10 DB3 I/O Nt 11 DB4 I/O Nt tro 12 DB5 I/O Nt 13 DB6 I/O Nt 14 DB7 I/O Nt ec Chân 15 và 16 là A và K. Nó được nối với 2 chân của 1 con Led dùng để sáng LCD trong bóng tối chúng ta không sử dụng. - Sơ đồ ghép nối LCD với vi điều khiển: el
  • 36. t ne u. c ct 2. Nguyên lí hoạt động của LCD. - Chân VCC, Vss, và VEE: các chân VCC và VSS cáp dương nguồn 5v và mass tương ni ứng. Chân VEE được dùng để điều khiển độ tương phản. - Chân chọn thanh ghi RS(Register Select): có 2 thanh ghi trong LCD chân RS được tro dùng để chọn thanh ghi. nếu RS=0 thì thanh ghi mã lệnh được chọn để cho phép người dùng gửi 1 lệnh lên chẳng hạn như xoá màn hình, đưa con trỏ về đầu dòng… Nếu RS=1 thì thanh ghi dữ liệu được chọn cho phép người dùng gửi dữ liệu cần hiển thị lên LCD. ec - Chân đọc/ghi (R/W): đầu vào đọc/ghi cho phép người dùng đọc thông tin từ LCD khi R/W=1 hoặc ghi thông tin lên LCD. el - Chân cho phép E(Enable): chân cho phép được sử dụng bởi LCD để chốt dữ liệu của nó. Khi dữ liệu được cấp đến chân dữ liệu thì 1 xung mức cao xuống thấp phải được áp đến chân này để LCD chốt dữ liệu trên các chân dữ liệu. Xung này có độ rộng tối thiểu 450ns. - Chân DB0-DB7: đây là đường dữ liệu 8 bít, được dùng để gửi thông tin lên LCD hoặc đọc nội dung các thanh ghi trong LCD. Để hiển thị các chữ cái và các con số, chúng ta gửi mã ASCII của các chữ cái từ A đến Z , a đến z và các chữ số từ 0 đến 9 đến các chân này khi bật RS=1. - Bảng mã lệnh của LCD:
  • 37. Mã (HEX) Lệnh đến thanh ghi của LCD 01 Xoá màn hình hiển thị 02 Trở về đầu dòng 04 Giảm con trỏ(dịch con trỏ sang trái ) 06 Tăng con trỏ(dịch con trỏ sang phải) 05 Dịch hiển thị sang phải t 07 Dịch hiển thị sang trái ne 08 Tắt con trỏ, tắt hiển thị 0a Tắt hiển thị, bật con trỏ 0c Bật hiển thi, tắt con trỏ u. 0e Bật hiển thị, nhấp nháy con trỏ 0f Tắt con trỏ, nhấp nháy con trỏ ct 10 Dịch vị trí con trỏ sang trái 14 Dịch vị trí con trỏ sang phải c 18 Dịch toàn bộ hiển thị sang trái ni 1c Dịch toàn bộ hiển thị sang phải 80 Ép con trỏ về đầu dòng thứ nhất tro 0c0 Ép con trỏ về đầu dòng thứ 2 38 Hai dòng và ma tận 5x7. ec el
  • 38. 3. Phần luyện tập: Hãy viết chương trình hiển thị trên LCD: Dòng 1 chữ “VIETNAM” bằng cách hiển thị tưng kí tự Dòng 2 chữ "VI DIEU KHIEN" bằng cách hiển thị cả chữ. Với sơ đồ mạch cho dướí đây. t ne u. c ct ni Chương trình: /*=========bo tien xu li===============*/ tro #include<AT89x51.h> #include<string.h> /*===========khai bao bien toan cuc============*/ ec sfr LCDdata = 0xA0; // cong P2, 8 bit du lieu. sbit BF = 0xA7; // co ban, bit DB7. sbit RS = P3^0; // chon thanh ghi el sbit RW = P3^1; // doc/ghi sbit EN = P3^2; //cho phep chot du lieu /*===========cac chuong trinh con cua LCD==========*/ /*--------------kiem tra su san sang cua LCD------------------------*/ void wait(void) { RS=0; //chon thanh ghi lenh RW=1; //đoc tu LCD
  • 39. LCDdata=0xff; //gia tri 0xff while(BF) //kiem tra co ban { EN=0; //dua xung cao xuong thap đe chot. EN=1; //dua chan cho phep len cao } t } ne /*------------------------thiet lap lenh cho LCD--------------------------*/ void LCDcontrol(unsigned char x) { u. RS=0;//chon thanh ghi lenh RW=0;//ghi len LCD. LCDdata=x ;// gia tri x ct EN=1;//cho phep muc cao c EN=0;//xung cao xuong thap ni wait();//đoi LCD san sang. } /*------------------------------Khoi tao LCD-------------------------*/ tro void LCDinit(void) { LCDcontrol(0x38);//2 dong va ma tran 5x7 ec LCDcontrol(0x0e);//bat man hinh, bat con tro LCDcontrol(0x01);//xoa man hinh el } /*-------------------------thiet lap du lieu cho LCD-----------------*/ void LCDwrite(unsigned char c) { RS=1;//ghi du lieu RW=0;//ghi du lieu len LCD LCDdata=c;//gia tri C EN=1;//cho phep muc cao EN=0;//xung cao xuong thap
  • 40. wait();//cho } void LCDwrites(unsigned char *s) { unsigned char data lens,count; lens=strlen(s); t for(count=0;count<lens;count++){ ne LCDwrite(*(s+count)); } } u. /*=====================chuong trinh tre================*/ void delay(long time) { ct while(time--); c } ni /*========================ham chinh==================*/ void main(void) { tro LCDinit(); // khoi tao LCD LCDcontrol(0x82);// dua con tro den vi tri thu 4 dong 1 LCDwrite(‘V’); ec LCDwrite(‘I’); LCDwrite(‘E’); el LCDwrite(‘T’); LCDwrite(‘ ’); LCDwrite(‘N’); LCDwrite(‘A’); LCDwrite(‘M’); LCDcontrol(0xC0); LCDwrites("VI DIEU KHIEN"); while(1); //vong lap vo han }
  • 41. II. Giao tiếp bàn phím Hex (ma trận phím 4x4) 1. Thuật toán đọc bàn phím Begin Cộti = 0 (i=1-4) t Sai ne Hàngi = 0 (i =1-4) u. Đúng Trả lại kết quả phím đã nhấn ct 2. Chương trình Hãy viết chương trình đọc ma trận phím và hiển thi số thứ tự phím trên LCD. c ni tro ec el
  • 42. Chương trình: /*=========bo tien xu li===============*/ #include<AT89x51.h> #include<string.h> #define H1 P1_0 t #define H2 P1_1 ne #define H3 P1_2 #define H4 P1_3 /*===========khai bao bien toan cuc============*/ u. sfr LCDdata = 0xA0; // cong P2, 8 bit du lieu. sbit BF = 0xA7; // co ban, bit DB7. ct sbit RS = P3^0; // chon thanh ghi sbit RW = P3^1; // doc/ghi c sbit EN = P3^2; //cho phep chot du lieu #include"LCD.h"// Thu vien LCD tu xay dung ni /*-------- ham doc phim nhan tu ma tran phim 4x4---------------*/ unsigned char Phim(void) tro { unsigned char phimnhan, dem, chot; phimnhan=0; ec chot=128; dem=4; while(dem--){ el P1=~chot; if(!H1){ delay(500); phimnhan=dem+1; delay(500); }else if(!H2 ){ delay(500); phimnhan=dem+5; delay(500);
  • 43. }else if(!H3 ){ delay(500); phimnhan=dem+9; delay(500); }else if(!H4 ){ delay(500); phimnhan=dem+13; t delay(500); ne } chot>>=1; } u. return phimnhan; } ct void viewphim(unsigned char phimnhan) { c if(phimnhan<10){ LCDwrite(phimnhan+48); ni }else{ LCDwrite(phimnhan/10+48); tro LCDwrite(phimnhan%10+48); } } ec void main(void) { unsigned char phimnhan=0; el LCDinit(); LCDwrites("Hay Nhan Phim"); LCDcontrol(0xC0); while(1){ phimnhan=Phim(); if(phimnhan){ LCDcontrol(0x01); LCDwrites("Hay Nhan Phim"); LCDcontrol(0xC0);
  • 44. viewphim(phimnhan); } } } III. Hiển thị ma trận Led 1. Thuật toán t ne 2. Xây dựng chương trình Bài toán: Viết chương trình hiển thị ma trận LED bằng phương pháp quét cột hiển thị dong chữ "LAP TRINH VI DIEU KHIEN BANG NGON NGU C", với dong chữ chạy u. từ trái sang phải. c ct ni tro ec el + Chương trình: // Khai bao chi thi tien xu ly #include<AT89x51.h> // Dinh nghia cac cong va cac chan dieu khien #define CLOCK P3_2 #define DATA P3_3 #define CLEAR P3_4
  • 45. #define Pxanh P1 #define Pdo P2 // Dinh nghia cac hang so #define Nhanh 10 #define Trungbinh 25 #define Cham 50 t ne #define Cuccham 75 #define Sieucham 150 #define Mxanh 1 u. #define Mdo 2 #define Mcam 3 // Khai bao mang chu hien thi ct unsigned char code Mcode[256]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, c 0,255,1,1,1,1,/* L */ ni 0,63,72,136,72,63,/* A */ 0,255,144,144,144,96,/* P */ tro 0, 0,128,128,255,128,128,/* T */ 0,255,144,144,144,111,/* R */ ec 0,129,129,255,129,129,/* I */ 0,255,96,24,6,255,/* N */ 0,255,16,16,16,255,/* H */ el 0, 0,252,2,3,2,252,/* V */ 0,129,129,255,129,129,/* I */ 0, 0,255,129,129,129,126,/* D */ 0,129,129,255,129,129,/* I */ 0,255,145,145,145,129,/* E */ 0,254,1,1,1,254,/* U */ 0,
  • 46. 0,255,24,36,66,129,/* K */ 0,255,16,16,16,255,/* H */ 0,129,129,255,129,129,/* I */ 0,255,145,145,145,129,/* E */ 0,255,96,24,6,255,/* N */ 0, 0,255,145,145,145,110,/* B */ t ne 0,63,72,136,72,63,/* A */ 0,255,96,24,6,255,/* N */ 0,126,129,129,137,78,/* G */ u. 0, 0,255,96,24,6,255,/* N */ 0,126,129,129,137,78,/* G */ ct 0,126,129,129,129,126,/* O */ 0,255,96,24,6,255,/* N */ c 0, ni 0,255,96,24,6,255,/* N */ 0,126,129,129,137,78,/* G */ tro 0,254,1,1,1,254,/* U */ 0, 0,126,129,129,129,70,/* C */ ec 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; el // Khai bao bien toan cuc unsigned char data Start,End,Tocdolap,i,j,k; unsigned char data Mdata1[32],Mdata2[32],Mau; unsigned char data Dk1,Dk2,Dk3,Dk4,Dk5; // Khai bao nguyen mau cac ham void delay(unsigned long time); unsigned char Mu2(unsigned char somu);
  • 47. void Do(unsigned char chiso); void Xanh(unsigned char chiso); void Cam(unsigned char chiso); void Dobyte(unsigned char chiso); void Xanhbyte(unsigned char chiso); void Cambyte(unsigned char chiso); t ne void Chaychudo(void); void Chaychuxanh(void); void Chaychucam(void); u. void Chaychu(void); void Taomangnhapnhay(void); ct void Nhapnhayxanh(void); void Nhapnhaycam(void); c void Nhapnhaydo(void); ni void Taomanglen(void); tro void Lxanh(void); void Ldo(void); void Lcam(void); ec void Len(void); /******************Ma nguon cac ham*************************/ // Ham tao tre el void delay(unsigned long time) { while(time--); } // Khoi ham hien thi chu chay tu trai sang phai void Xanh(unsigned char chiso) { CLOCK=1; DATA=0;
  • 48. CLOCK=0; Pxanh=Mcode[chiso]; delay(12); Pxanh=0; } void Do(unsigned char chiso) t ne { CLOCK=1; DATA=0; u. CLOCK=0; Pdo=Mcode[chiso]; delay(12); ct Pdo=0; } c ni void Cam(unsigned char chiso) { tro CLOCK=1; DATA=0; CLOCK=0; ec Pxanh=Mcode[chiso]; Pdo=Pxanh; delay(12); el Pdo=0; Pxanh=0; } void Chaychucam(void) { for(i=Start+1;i<Dk1;i++) { Tocdolap=Nhanh;
  • 49. while(Tocdolap--) { DATA=1; Dk2=i+32; for(j=i;j<Dk2;j++)Cam(j); } } t ne } void Chaychuxanh(void) { u. for(i=Start+1;i<Dk1;i++) { Tocdolap=Nhanh; ct while(Tocdolap--) { c DATA=1; ni Dk2=i+32; for(j=i;j<Dk2;j++)Xanh(j); tro } } } ec void Chaychudo(void) { for(i=Start+1;i<Dk1;i++) el { Tocdolap=Nhanh; while(Tocdolap--) { DATA=1; Dk2=i+32; for(j=i;j<Dk2;j++)Do(j); } }
  • 50. } void Chaychu(void) { Dk1=End-31; if(Mau==Mxanh)Chaychuxanh(); else if(Mau==Mdo)Chaychudo(); t ne else Chaychucam(); } // Khoi ham hien thi chu nhap nhay tai cho void Cambyte(unsigned char chiso) u. ct { CLOCK=1; c DATA=0; ni CLOCK=0; Pxanh=Mdata2[chiso]; tro Pdo=Pxanh; delay(12); Pdo=0; ec Pxanh=0; } el void Dobyte(unsigned char chiso) { CLOCK=1; DATA=0; CLOCK=0; Pdo=Mdata2[chiso]; delay(12); Pdo=0; }
  • 51. void Xanhbyte(unsigned char chiso) { CLOCK=1; DATA=0; CLOCK=0; Pxanh=Mdata2[chiso]; t ne delay(12); Pxanh=0; } void Nhapnhaydo(void) { u. ct while(Tocdolap--){ DATA=1; c for(k=0;k<32;k++)Dobyte(k); ni } } tro void Nhapnhayxanh(void) { while(Tocdolap--){ ec DATA=1; for(k=0;k<32;k++)Xanhbyte(k); } el } void Nhapnhaycam(void) { while(Tocdolap--){ DATA=1; for(k=0;k<32;k++)Cambyte(k); } }
  • 52. void Taomangnhapnhay(void) { for(i=0;i<32;i++) Mdata2[i]=0; Dk4=End-Start; Dk5=(32-Dk4)/2; t ne Dk4=32-Dk5; for(i=Dk5;i<Dk4;i++) Mdata2[i]=Mcode[Start+i-Dk5]; u. } void Nhapnhay(void) ct { unsigned char demnhay; c demnhay=10; ni Taomangnhapnhay(); while(demnhay--) tro { Tocdolap=Nhanh; if(Mau==Mxanh)Nhapnhayxanh(); ec else if(Mau==Mdo)Nhapnhaydo(); else Nhapnhaycam(); CLEAR=0; el delay(1250); CLEAR=1; } } // Khoi ham hien thi chu di tu duoi len unsigned char Mu2(unsigned char somu) { if(!somu) return 1; else return 2*Mu2(somu-1);
  • 53. } void Taomanglen(void) { for(i=0;i<32;i++) Mdata2[i]=0; t ne Dk4=End-Start; Dk5=(32-Dk4)/2; Dk4=32-Dk5; u. for(i=Dk5;i<Dk4;i++) Mdata1[i]=Mcode[Start+i-Dk5]; i=8; ct } void Lcam(void) c { ni unsigned char data dem; Tocdolap=Trungbinh; tro while(Tocdolap--) { DATA=1; ec for(dem=0;dem<32;dem++) { CLOCK=1; el DATA=0; CLOCK=0; Pxanh=Mdata2[dem]; Pdo=Pxanh; delay(12); Pxanh=0; Pdo=0; } }
  • 54. } void Ldo(void) { unsigned char data dem; Tocdolap=Trungbinh; while(Tocdolap--) { t ne DATA=1; for(dem=0;dem<32;dem++) { u. CLOCK=1; DATA=0; CLOCK=0; ct Pdo=Mdata2[dem]; delay(12); c Pdo=0; ni } } tro } void Lxanh(void) ec { unsigned char data dem; Tocdolap=Trungbinh; el while(Tocdolap--) { DATA=1; for(dem=0;dem<32;dem++) { CLOCK=1; DATA=0; CLOCK=0; Pxanh=Mdata2[dem];
  • 55. delay(12); Pxanh=0; } } } void Len(void) t ne { Taomanglen(); while(i--) u. { for(j=Dk5;j<Dk4;j++) Mdata2[j]= Mdata1[j]/Mu2(i); ct if(Mau==Mxanh)Lxanh(); else if(Mau==Mdo)Ldo(); c else Lcam(); ni } tro for(i=0;i<7;i++) { for(j=Dk5;j<Dk4;j++) ec Mdata2[j]= Mdata2[j]*2; if(Mau==Mxanh)Lxanh(); else if(Mau==Mdo)Ldo(); el else Lcam(); } } /*Ham chinh*/ void main(void) { TMOD=0x01; Pxanh=0; Pdo=0;
  • 56. P3=16; while(1) { Start=0;End=194;Mau=3; Chaychu(); t ne Start=0;End=17;Mau=1; Len(); Start=19;End=48;Mau=1; u. Len(); Start=50;End=61;Mau=1; Len(); ct Start=63;End=87;Mau=1; Len(); c Start=89;End=118;Mau=1; ni Len(); Start=120;End=143;Mau=1; tro Len(); Start=145;End=168;Mau=1; Len(); ec Start=170;End=187;Mau=1; Len(); Start=189;End=194;Mau=1; el Len(); Start=0;End=17;Mau=2; Nhapnhay(); Start=19;End=48;Mau=2; Nhapnhay(); Start=50;End=61;Mau=2; Nhapnhay(); Start=63;End=87;Mau=2;
  • 57. Nhapnhay(); Start=89;End=118;Mau=2; Nhapnhay(); Start=120;End=143;Mau=2; Nhapnhay(); Start=145;End=168;Mau=2; Nhapnhay(); t ne Start=170;End=187;Mau=2; Nhapnhay(); Start=189;End=194;Mau=2; u. Nhapnhay(); } ct } c ni tro ec el
  • 58. Bài 5: Giao tiếp ADC - Xử lý ngắt I. Giao tiếp ADC t ne u. c ct ni +Chương trình: tro #include<regx51.h> #include<string.h> ec /*===========khai bao bien toan cuc============*/ sfr LCDdata = 0xA0; // cong P2, 8 bit du lieu. sbit BF = 0xA7; // co ban, bit DB7. el sbit RS = 0xb0; // chon thanh ghi sbit RW = 0xb1; // doc/ghi sbit EN = 0xb2; //cho phep chot du lieu #include"Lcd.h"// Thu vien LCD tu xay dung #define RD P3_3 #define WR P3_4 #define INTR P3_5 /*-------- Ham tre ---------------*/ void delay(long time)
  • 59. { while(time--); } /*-------- ham doc phim nhan tu ma tran phim 4x4---------------*/ void view(unsigned char val) { t ne unsigned char var; if(val<10){ LCDwrite(val+48); u. }else if(val<100){ LCDwrite(val/10+48); LCDwrite(val%10+48); ct }else{ var=val/10; c LCDwrite(var/10+48); ni LCDwrite(var%10+48); LCDwrite(val%10+48); tro } } void main(void) ec { unsigned char ADCval=0; RD=0; el LCDinit(); LCDcontrol(0x83); LCDwrites("ADC0804"); while(1){ WR=1; WR=0; while(!INTR); ADCval=P1; LCDcontrol(0x01);
  • 60. LCDcontrol(0x83); LCDwrites("ADC0804"); LCDcontrol(0xC0); view(ADCval); delay(5000); } } t ne II. Lập trình xử lý ngắt 1. Ngắt timer/counter. 1.1. cơ chế tạo trễ của timer và cách tính toán giá trị nạp vào timer. a. chế độ 1: u. - ở chế độ 1 đó là bộ định thời 16 bit, do đó các giá trị trong khoảng từ 0000 đến FFFF có thể sử dụng để nạp cho TH và TL của bộ định thời. - Sau khi TH, TL được nạp giá trị ban đầu 16 bit thì bộ định thời phải được khởi ct động với lệnh TR0 = 1 với timer0 và TR1 = 1 với timer1, khi này bộ định thời bắt đầu đếm tăng theo xung clock từ giá trị ban đầu cho tới giá trị đỉnh là FFFF. Khi đó bộ định c thời sẽ quay vong từ FFFF về 0000 và bật cờ báo tràn TF0 với timer0 và TF1 với timer1(ban dầu TFx=0) khi đó cần phải có thao tác để xoá cờ để lần sau còn biết được ni khi nào bộ đếm tràn. - khi bộ đếm tràn thì TH và Tl của bộ định thời sẽ mang giá trị 0 do đó phải có thao tác nạp lại giá trị ban đầu cho chúng và xoá cờ TF để bộ đếm được lặp lại. tro - Như vậy khoảng thời gian mà bộ định thời tạo trễ chính là khoangre thời gian nó đếm tăng từ giá trị ban đầu được nạp cho tới giá trị đỉnh FFFF. - tính toán giá trị nạp vào thanh ghi chứa của bộ định thời từ thời gian muốn tạo trễ(t): gọi N = 65536 – t/chu ki máy. Sau khi chuyển sang mã HEX được 1 số có 4 chữ ec số có dạng: x1x2y1y2. khi đó giá trị nạp cho thanh ghi chứa như sau: TH = x1x2, TL = y1y2. Ví dụ: muốn tạo trễ 500us thì: el Giả sử chu kì máy là 1us: có N = 65536 – 500/1 = 65036. chuyển sang mã HEX là FE0C, từ đó: TH = 0xFE, TL = 0x0C. - các bước lập trình cho bộ định thời để tạo trễ ở chế độ 1: +B1: chọn chế độ 1 cho bộ định thời cần dung, từ đó xác định giá trị nạp cho thanh ghi TMOD. + B2: tính toán giá trị ban đầu cần nạp cho TH và TL từ thời gian trễ mong muốn. + B3: khởi động bộ định thời. + B4: kiểm tra trạng thái bật của cờ TF. + B5:dung bộ định thời. + B6: xoá cờ TF cho vòng lặp kế tiếp.
  • 61. + B7: quay trở về B2 để nạp lại giá trị cho TH và TL. b. Chế độ 2: - Ở chế độ này bộ định thời là 8 bit, do vậy chỉ cho phép các giá trị từ 00 đến FF được nạp vào thanh ghi TH của bộ định thời. sau khi nạp giá trị 8 bit thì vi điều khiển sẽ sao nội dung của TH sang TL và bộ định thời được khởi động bằng lệnh TRx=1. - Sau khi được khởi động thì bộ định thời bắt đầu đếm tăng trong thanh ghi TL từ giá trị ban đầu đến giá trị đỉnh FF. và khi quay vòng từ FF về 00 thì cờ TFx được bật lên 1, khi này thanh ghi TL mang giá trị 0 nhưng TL sẽ ngay lập tức được tự động nạp lại t với giá trị ban đầu được lưu trong thanh ghi TH. ne - như vậy trong chế độ này mỗi khi bộ đếm tràn thì thanh ghi chứa sẽ được vi điều khiển nạp lại giá trị ban đầu, do đó chế độ này được gọi là chế độ tự động nạp lại. - tính giá trị nạp vào thanh ghi chứa của bộ định thời từ thời gian trễ (t): Gọi N = 256 – t/chu kì máy. Sau khi chuyển sang mã HEX được 1 số, ta nạp số u. này vào thanh ghi TH và cả TL(nạp vào TL giá trị đếm lần 1 và nạp vào TH cho những lần sau để khi bộ đếm tràn thì phần cứng của vi điều khiển sẽ tự động sao TH sang TL). Ví dụ: tạo trễ 50usthì là: ct Giả sử chu kì máy là 1us: có N = 256 – 50/1 = 205, chuyển sang mã HEX : 0CE Từ đó: TH = 0xCE và TL = 0xCE. c - các bước lập trình cho bộ định thời để tạo trễ ở chế độ 2. + B1: nạp giá trị cho thanh ghi thiết lập chế độ TMOD với timer muốn sử ni dụng. + B2: nạp vào TH giá trị đém ban đầu. +B3: khởi động bộ định thời. tro + B4: kiểm tra cờ báo tràn TFx. + B5: xoá cờ tràn TFx, quay về B4. * lưu ý: 2 chế độ khác của bộ định thời là chế độ 0(chế độ bộ định thời 13 bit, bộ định thời/bộ đếm 8 bit, định tỷ lệ trước 5 bit ) và chế độ 3(chế độ bộ định thời chia tách) ec ở đay không giới thiệu. 1.2. Ngắt của bộ định thời. - nguyên tắc sử dụng bộ định thời ở chế độ ngắt: el + khai báo ngắt của bộ định thời muốn sử dụng + nguồn gây ngắt. + chương trình chính và chương trình phục vụ ngắt. - với ngắt định thời việc khai báo nguồn ngắt bao gồm việc khai báo ngắt toàn cục là EA = 1 và khai báo ngắt cho từng bộ định thời muốn dùng ET0 = 1(timer0) và ET1 = 1(timer1) - Nguồn báo ngắt định thời(với cả 2 chế độ) đều là khi bộ đếm tràn(khi cờ TFx = 1), khi cờ TFx = 1 thì vi điều khiển kết thúc công việc hiện tại ở chương trình chính và chuyển vào chương trình phục vụ ngắt căn cứ theo địa chỉ của chương trình phục vụ ngắt.khi thực hiện xong chương trình phục vụ ngắt vi điều khiển quay trở về chương trình tại nơi bị gián đoạn khi trước.
  • 62. - Tóm lại ngắt định thời là việc ta sử dụng bộ định thời tạo trễ một khoảng thời gian được tính toán trước, sau khoảng thời gian này 1 công việc ta mong muốn sẽ được thực hiện ở chương trình phục vụ ngắt. công việc đó có thể coi là độc lập với công việc ở chương trình chính - các công việc lập trình sử dung ngắt định thời : + tính toán thời gian trễ mong muốn và công việc muốn thực hiện sau khoảng thời gian đó. + khai báo ngắt định thời trong chương trình chính (EA=1, ETX=1). t + lựa chon bộ định thời và chế độ của nó trong thanh ghi TMOD ne + khởi động bộ định thời. + Xây dựng chương trình chính và các chương trình con cần thiết. + xây dựng chương trình phục vụ ngắt thực hiện 1 công việc mong muốn (xác định rõ địa chỉ ngắt theo thứ tự ngắt trong bảng vector ngắt) u. - Chú ý: trong chương trình phục vụ ngắt các bạn phải xoá cờ báo tràn TFx và nạp lại giá trị cho bộ định thời với chế độ 1 còn chế độ 2 thì không cần. 1.3. bài toán: ct Bài toán 1: sử dụng bộ định thời với ngắt của nó tạo một xung vuông với tần số 1kHZ đối xứng (50% mức 1 và 50% mức 0 ) trên chân P1.0. c Bài giải: - ta có : f = 1kHZ → T = 1/1000s = 1000us → TON = TOFF = T/2 = 500us. Như vậy ni chu kì xung là đối xứng nên hai phần này bộ đếm đếm giống nhau(tạo trễ khoảng thời gian bằng nhau). nửa chu kì đầu bộ đếm tạo trễ 500us cho mức 0, sau khi bộ đếm đếm đến giá trị đỉnh của thanh ghi chứa là FFFF thì cờ báo TFx = 1 gây ngắt, vi điều khiển tro phải chuyển vào chương trình phục vụ ngắt và sẽ lật trạng thái xung ra. Trong nửa chu kì còn lại cũng như vậy và cứ như thế. - Do thời gian trễ là 500us do đó ta chọn chế độ 16 bit, sử dụng kết quả từ ví dụ trên để nạp giá trị ban đầu cho TH và TL. ec - Chương trình điều khiển: /*================khai bao thu vien===============*/ #include<AT89x51.h> el /*=============khai bao bien=====================*/ sbit xung = P1^0; /*==============khai bao ham ==================*/ /*--------------------------chuong trinh phuc vu ngat timer0 tao xung--------------------*/ void timer0_int(void) interrupt 1 { TF0=0; // xoa co bao tran timer0 xung = !xung; // tao muc 1 ra chan P1.0 TH0 = 0xfe; // (65536-500)↔hex =0fe0c (thach anh 12MHz) TL0 = 0x0c;
  • 63. } /*=============chuong trinh chinh=============*/ void main(void) { EA = 1; // cho phep ngat toan cuc ET0 = 1; // cho phep ngat T0 TMOD = 0x01; // timer0 che do 1 xung = 0; //gia tri ban dau cua xung muon tao t TH0 = 0xfe; // (65536-500)↔hex =0fe0c (thach anh 12MHz) ne TL0 = 0x0c; TR0 = 1; // khoi dong timer while(1) PCON|=1; //khong lam gi ca de doi ngat. } u. Bài toán 2: sử dụng bộ định thời với ngắt của tạo đồng hồ số hiển thị lên LCD. ct c ni tro ec el + Chương trình: /*================khai bao thu vien===============*/ #include<regx51.h> #include<string.h> #define LCDdata P2 sbit RS=P3^0; sbit RW=P3^1; sbit EN=P3^2; sbit BF=LCDdata^7;
  • 64. #include"lcd.h" /*=============khai bao bien=====================*/ unsigned char data Time[8]; unsigned char data i; /*==============khai bao ham ==================*/ void T10ms(void) interrupt 1 using 0 { t TR0=0; ne TH0=0xD8; TL0=0xEF; TR0=1; if(Time[0]==9){ u. Time[0]=0; if(Time[1]==9){ Time[1]=0; ct if(Time[2]==9){ Time[2]=0; c if(Time[3]==5){ Time[3]=0; ni if(Time[4]==9){ Time[4]=0; if(Time[5]==5){ tro Time[5]=0; if(Time[6]==9&&Time[7]<2){ Time[6]=0; Time[7]++; ec }else if(Time[6]==3&&Time[7]==2){ Time[6]=0; Time[7]=0; el }else Time[6]++; }else Time[5]++; }else Time[4]++; }else Time[3]++; }else Time[2]++; }else Time[1]++; }else Time[0]++; LCDwrite(Time[7]+48);LCDwrite(Time[6]+48);LCDwrite(':'); LCDwrite(Time[5]+48);LCDwrite(Time[4]+48);LCDwrite(':'); LCDwrite(Time[3]+48);LCDwrite(Time[2]+48);LCDwrite(':'); LCDwrite(Time[1]+48);LCDwrite(Time[0]+48);
  • 65. LCDcontrol(0xC0); } /*==============Chuong trinh chinh ==================*/ void main() { TMOD|=1; EA=1; ET0=1; t TH0=0xD8; ne TL0=0xEF; for(i=0;i<8;i++)Time[i]=0; LCDinit(); LCDwrites("Dong ho so"); u. LCDcontrol(0xC0); TR0=1; while(1)PCON|=1; ct } c 2. Lập trình với các ngắt ngoài của vi điều khiển. 2.1. Khái niệm: ni - bộ vi điều khiển 8051có hai ngắt ngoài là INT0 và INT1 với 2 chân tác động đầu vào tương ứng là P3.2 và P3.3. - Ngắt ngoài là ngắt của vi điều khiển mà tác động ngắt ở đây chính là các tác động tro bên ngoài của vi điều khiển tác động vào vi điều khiển thong qua các chân ngắt đưới dạng một tín hiệu điện áp dạng xung. - tác động ngắt ngoài có hai dạng là tác động theo dạng mức và dạng sườn. + kích hoạt theo mức: ở chế độ này các chân INT0 và INT1 bình thường ở mức ec cao giống như các chân khác của vi điều khiển, khi có tín hiệu mức thấp cấp tới thì tín hiệu này kích hoạt ngắt. lưu ý là trước khi thực hiện lệnh cuối cùng của chương trình phục vụ ngắt thì mức thấp tại các chân ngắt phải được chuyển lên mức cao, nếu không el sẽ lại gây ra một ngắt ngay lập tức. + Kích hoạt theo sườn: bình thường các chân ngắt của vi điều khiển ở mức cao, khi có tín hiệu tác động vào chúng có dạng sườn xuống thì sẽ tác động ngắt. - Để sử dụng chế độ ngắt này thì phải tác động vào thanh ghi TCON cụ thể là TCON.1=1 hoặc IT0=1 thì cho phép ngắt ngoài 0 kích hoạt sườn, còn TCON.2=1 hoặc IT1=1 thì cho phép ngắt ngoài 1 kích hoạt sườn. 2.2. cách lập trình: - Để lập trình cho ngắt của vi điều khiển ta phải thực sự hiệu bản chất của ngắt và quá trình thực hiện ngắt của vi điều khiển diễn ra. - mẫu viết hàm ngắt như sau: Void name(void)interrupt x(x là số thứ tự ngắt ngoài x = 0 hoặc 2)
  • 66. { //chương trình phục vụ ngắt } - Trong chương trình chính ta phải có thao tác thiết lập việc cho phép các ngắt được sử dụng. 2.3. bài toán: sử dụng ngắt ngoài của vi điều khiển với nhiệm vụ là: bình thường vi điều khiển bật một Led đơn tại chân P1.0 và khi có ngắt ngoài thì tắt Led ở P1.0 và bật Led ở chân t P1.1 sau 1s thì bật lại Led P1.0 và tắt Led P1.1. ne u. c ct ni tro ec el Bài giải: /*==================Bo tien xu li===================*/ #include<AT89x51.h> // Dinh kem file thu vien #define bat 1 // Dinh nghia gia tri bat den Led #define tat 0 // Dinh nghia gia tri tat den Led /*==================khai bao bien==================*/ sbit Led1 = P1^0; // Khai bao bi?n Led ki?u bit chan P1.0 sbit Led2 = P1^1; // Khai bao bi?n Led ki?u bit chan P1.0 /*================= Khai bao hàm==================*/ /*------------------------------ham tre -------------------------------------*/ void delay(long time)
  • 67. { while(time--); } void INT_0(void) interrupt 0 // chuong trinh phuc vu ngat { Led1=tat; Led2=bat; delay(25000); t Led1=bat; ne Led2=tat; } /*--------------------------------ham chinh--------------------------------*/ void main(void) u. { EA=1; // cho phep ngat toan cuc EX0=1; // cho phep ngat ngoai 0 ct IT0=1; //ngat kich phat suon Led1=bat; c Led2=tat; while(1); ni } tro ec el
  • 68. Bài 6: Điều khiển động cơ DC, động cơ Servo, động cơ bước 1. Đông cơ DC 2. Động cơ Servo 3. Động cơ bước (Step motor) Điều khiển động cơ bước với tốc độ tăng dần từ 5 đến 100 v/p, mỗi lần chuyển tốc độ tăng 5v/p thời gian chuyển 1s, hiển thị tốc độ trên LCD. t ne u. c ct ni tro + Chương trình: #include<regx51.h> #include<string.h> ec #define LCDdata P2 el sbit RS=P3^0; sbit RW=P3^1; sbit EN=P3^2; sbit BF=LCDdata^7; #include"lcd.h" unsigned char data Bytecao1,Bytethap1; unsigned char data Buoc,Nbuoc; unsigned char data Mbuoc[4]={144,192,96,48};
  • 69. void viewspeed(unsigned char speed); void Xuly(unsigned char Nspeed); void Dkdongco(void) interrupt 1 using 0 { t ne TR0=0; TH0=Bytecao1; TL0=Bytethap1; u. TR0=1; P1=Mbuoc[Buoc]; Buoc++; ct if(Buoc==4)Buoc=0; } c ni void Xuly(unsigned char speed) { tro unsigned int data Chuki1,Chuki2; unsigned int data tam1,tam2; TR0=0; ec viewspeed(speed); Nbuoc=200; tam2=10000/Nbuoc; el tam1=6000/speed; Chuki1=tam1*tam2; Chuki2=65535-Chuki1; Bytecao1=Chuki2/256; Bytethap1=Chuki2%256; TR0=1; } void delay(unsigned long time)
  • 70. { while(time--); } void viewspeed(unsigned char speed) { unsigned char data a1,a2; LCDcontrol(0xc0); t ne a1=speed%10; speed=speed/10; a2=speed%10; u. speed=speed/10; LCDwrite(speed+48); LCDwrite(a2+48); ct LCDwrite(a1+48); LCDwrites("(vong/phut)"); c } ni void main() tro { unsigned char data i; TMOD=17; ec EA=1; LCDinit(); ET0=1; el LCDcontrol(0x80); LCDwrites("CT DK DC buoc" ); LCDcontrol(0xc0); LCDwrites("V:5-100(v/p)"); delay(100000); while(1){ Buoc=2; for(i=5;i<101;i=i+5){ LCDcontrol(0x01);
  • 71. LCDcontrol(0x80); LCDwrites("CT DK DC buoc" ); Xuly(i); delay(500000); } } } t ne u. c ct ni tro ec el
  • 72. Bài 7: Giao tiếp Vi điều khiển với Máy tính I. Cổng truyền thông nối tiếp 1. Thanh ghi SCON – SBUF II. Xây dựng chương trình 1. Chương trình VB + Giao diện t ne u. c ct ni + Thuật toán tro + Chương trình: Option Explicit ec Dim Mau As Byte Private Sub cbcolor_Click() If (cbcolor.Text = "Mau do") Then el Mau = 1 txtchu.ForeColor = &HFF& lbHienthi.ForeColor = &HFF& ElseIf (cbcolor.Text = "Mau xanh") Then Mau = 2 txtchu.ForeColor = vbGreen lbHienthi.ForeColor = &HFF00& ElseIf (cbcolor.Text = "Mau cam") Then Mau = 3
  • 73. txtchu.ForeColor = &H80FF& lbHienthi.ForeColor = &H80FF& End If End Sub Private Sub cbcolor_GotFocus() SendKeys "%{DOWN}" t ne End Sub Private Sub cmdCode_Click() u. MsgBox Code(txtchu) End Sub ct Private Sub cmdExit_Click() If MSComm1.PortOpen Then c MSComm1.PortOpen = False ni End If End tro End Sub Function Code(s As String) As String ec Dim i As Integer s = Replace(s, " ", "") For i = 1 To Len(s) el Code = Code & " " & Asc(Mid(s, i, 1)) Next End Function Private Sub OpenPort() Dim s As String MSComm1.Settings = "57600,N,8,1" MSComm1.CommPort = 1 MSComm1.PortOpen = True
  • 74. MSComm1.InputLen = 0 s = MSComm1.Input MsgBox "Port did open" End Sub Private Sub cmdOpenport_Click() If MSComm1.PortOpen Then MSComm1.PortOpen = False t ne End If OpenPort u. End Sub Private Sub cmdSend_Click() ct Dim s As String c ni If MSComm1.PortOpen = False Then MsgBox "Port did not open" tro OpenPort End If ec If MSComm1.PortOpen Then txtchu.Text = UCase(txtchu.Text) s = Chr(Mau) & Chr(Len(txtchu.Text)) & txtchu.Text & Chr(255) el Do While (MSComm1.OutBufferCount > 0) Loop MSComm1.Output = s End If End Sub Private Sub cmdStop_Click() MSComm1.Output = Chr(250)
  • 75. MsgBox "Port Stoped" End Sub Private Sub Form_Load() txtchu.ForeColor = vbRed txtchu.Text = "DO AN GHEP NOI" t ne Mau = 1 End Sub Private Sub Form_Resize() If (Me.WindowState = 1) Then u. ct Me.Height = 4000 Me.Width = 7230 c End If ni End Sub tro Private Sub txtchu_GotFocus() txtchu.SelStart = 0 txtchu.SelLength = Len(txtchu) ec End Sub 2. Chương trình vi điều khiển el + Thuật toán + Chương trình: /************Khai bao tien xy ly***************/ #include<regx51.h> /*********Dinh nghia hang so mau**********/ #define Mdo 1 #define Mxanh 2 #define Mcam 3 /*****Khai bao mang ki tu gom chu so va chu cai****/
  • 76. unsigned char code Mchar[36][7]={ 48,0,126,129,129,129,126,/*0*/ 49,0,0,33,65,255,1,/*1*/ 50,0,99,135,137,145,97,/* 2 */ 51,0,66,129,145,145,110,/* 3 */ 52,0,24,40,72,255,8,/* 4 */ 53,0,226,145,145,145,142,/* 5 */ t ne 54,0,118,137,137,137,70,/* 6 */ 55,0,128,135,136,144,224,/* 7 */ 56,0,110,145,145,145,110,/* 8 */ u. 57,0,102,145,145,145,110,/* 9 */ 65,0,63,72,136,72,63,/* A */ 66,0,255,145,145,145,110,/* B */ ct 67,0,126,129,129,129,70,/* C */ 68,0,255,129,129,129,126,/* D */ c 69,0,255,145,145,145,129,/* E */ ni 70,0,255,144,144,144,128,/* F */ 71,0,126,129,129,137,78,/* G */ tro 72,0,255,16,16,16,255,/* H */ 73,0,129,129,255,129,129,/* I */ 74,0,2,129,130,252,128,/* J */ ec 75,0,255,24,36,66,129,/* K */ 76,0,255,1,1,1,1,/* L */ 77,0,255,64,32,64,255,/* M */ el 78,0,255,96,24,6,255,/* N */ 79,0,126,129,129,129,126,/* O */ 80,0,255,144,144,144,96,/* P */ 81,0,126,129,133,130,125,/* Q */ 82,0,255,144,144,144,111,/* R */ 83,0,98,144,144,144,78,/* S */ 84,0,128,128,255,128,128,/* T */ 85,0,254,1,1,1,254,/* U */ 86,0,252,2,3,2,252,/* V */
  • 77. 87,0,255,12,3,12,255,/* W */ 88,0,199,40,16,40,199,/* X */ 89,0,224,16,15,16,224,/* Y */ 90,0,131,133,153,161,193/* Z */ }; /*******Dinh nghia cac chan va cac cong dieu khien*****/ sfr Pxanh=0x90; t ne sfr Pdo=0xA0; sbit Clear=P3^4; u. sbit Data=P3^3; sbit Clock=P3^2; /**************Khai bao bien toan cuc*************/ ct unsigned char data Ktnhan,nhanmau,j,i,Maxc,Count,nLap; unsigned char data Mau,Chay,tam,dem; c unsigned char data MC[76],MQ[32]; ni /**********Khoi ham chuong trinh**********/ // Ham ngat noi tiep tro void Ngatnoitiep(void) interrupt 4 using 0 { if(RI){ ec RI=0; tam=SBUF; if(tam==250){ el Chay=1;i=j=77;dem=8; Count=0; Clear=0; }else{ if(nhanmau){ Mau=tam; Chay=1;i=j=77;dem=8; Count=nhanmau=0; P1=P2=0;
  • 78. Clear=0; }else if(tam==255){ Clear=1; Chay=0; Ktnhan=nhanmau=1; }else{ if(Ktnhan){ t ne Maxc=tam; Ktnhan=0; }else if(Count<76&&Count<Maxc){ u. MC[Count]=tam; Count++; } ct } } c } ni } void Khoitao(void) tro { PCON|=128; EA=1; ec ES=1; SM0=0; SM1=1; el Ktnhan=nhanmau=1; Chay=1; P0=P1=P2=0; P3_0=1; nLap=1; } // Ham tao tre void delay(void) {
  • 79. unsigned char data i; i=10; while(i--); } // Ham hien thi mau cam void Cam(void) { t ne while(nLap--) { Data=1; u. for(j=0;j<32;j++){ Clock=1; Data=0; ct Clock=0; Pdo=Pxanh=MQ[j]; c delay(); ni Pxanh=Pdo=0; } tro } } ec // Ham hien thi mau xanh void Xanh(void) { el while(nLap--) { Data=1; for(j=0;j<32;j++){ Clock=1; Data=0; Clock=0; Pxanh=MQ[j]; delay();
  • 80. Pxanh=0; } } } // Ham hien thi mau do void Do(void) t ne { while(nLap--) { u. Data=1; for(j=0;j<32;j++){ Clock=1; ct Data=0; Clock=0; c Pdo=MQ[j]; ni delay(); Pdo=0; tro } } } ec // Ham thay doi mang hien thi void change(void) { el MQ[0]=MQ[1];MQ[1]=MQ[2];MQ[2]=MQ[3];MQ[3]=MQ[4]; MQ[4]=MQ[5];MQ[5]=MQ[6];MQ[6]=MQ[7];MQ[7]=MQ[8]; MQ[8]=MQ[9];MQ[9]=MQ[10];MQ[10]=MQ[11];MQ[11]=MQ[12]; MQ[12]=MQ[13];MQ[13]=MQ[14];MQ[14]=MQ[15];MQ[15]=MQ[16]; MQ[16]=MQ[17];MQ[17]=MQ[18];MQ[18]=MQ[19];MQ[19]=MQ[20]; MQ[20]=MQ[21];MQ[21]=MQ[22];MQ[22]=MQ[23];MQ[23]=MQ[24]; MQ[24]=MQ[25];MQ[25]=MQ[26];MQ[26]=MQ[27];MQ[27]=MQ[28]; MQ[28]=MQ[29];MQ[29]=MQ[30];MQ[30]=MQ[31]; }
  • 81. // Ham tim vitri ki tu hien thi trong bang chu cai va chu so unsigned char Chiso(unsigned char chr) { unsigned char data End,Start,Mid,Mctam; if(chr==Mchar[0][0]){ return 0; }else if(chr==Mchar[35][0]){ t ne return 35; }else{ End=35; u. Start=0; while(1){ Mid=(End+Start)/2; ct Mctam=Mchar[Mid][0]; if(chr==Mctam){ c return Mid; ni }else if(chr<Mctam){ End=Mid; tro }else{ Start=Mid; } ec } } } el void Chaychu(void) { unsigned char vitri; for(j=0;j<32;j++){ MQ[j]=0; } for(i=0;i<Count;i++) {
  • 82. if(MC[i]==32){ change(); MQ[31]=0; if(Mau==Mxanh)Xanh(); else if(Mau==Mdo)Do(); else Cam(); change(); t ne MQ[31]=0; if(Mau==Mxanh)Xanh(); else if(Mau==Mdo)Do(); u. else Cam(); }else{ vitri=Chiso(MC[i]); ct for(dem=1;dem<7;dem++){ change(); c MQ[31]=Mchar[vitri][dem]; ni if(Mau==Mxanh)Xanh(); else if(Mau==Mdo)Do(); tro else Cam(); } } ec } if(!Chay){ for(i=0;i<32;i++){ el change(); MQ[31]=0; if(Mau==Mxanh)Xanh(); else if(Mau==Mdo)Do(); else Cam(); } } } // Chuong trinh chinh
  • 83. void main() { Khoitao(); REN=1; while(1){ while(Chay); Chaychu(); t ne } } u. c ct ni tro ec el