Hiển thị các bài đăng có nhãn Lập Trình 8051 Căn Bản. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn Lập Trình 8051 Căn Bản. Hiển thị tất cả bài đăng

Thứ Ba, 5 tháng 4, 2016

Bài 7: Giao tiếp UART với 8051.

Chào các bạn!

     Giao tiếp UART là chuẩn giao tiếp nối tiếp được sử dụng phổ biến trong các dòng VĐK. Mặc dù có tốc độ truyền không cao, nhưng ngược lại giao tiếp UART có phần cứng gọn nhẹ, dễ thiết kế và giá thành thấp. Giao tiếp UART được sử dụng nhiều trong các ứng dụng như giao tiếp máy tinh, giao tiếp module SIM, module GPS...
     Hôm nay mình xin hướng dẫn các cấu hình sử dụng UART trong VĐK 8051.


I. Các thanh ghi cấu hình giao tiếp UART trong VĐK 8051.

1. Thanh ghi cấu hình cổng nối tiếp SCON.

     Đây là thanh ghi 8 bit, chứa các bit sử dụng để cài đặt chế độ của giao tiếp UART và các bit cờ báo trạng thái truyền và nhận.
     Các bit của thanh ghi được mô tả như sau.
Hình 1.1: Thanh ghi SCON.

     SM0, SM1: Đây là 2 bit sử dụng để xác định các chế độ làm việc. Có 4 chế độ truyền UART trong 8051, được miêu tả trong bảng sau.
Hình 1.2: Các chế độ hoạt động của UART.
     SM2: Đây là bit sử dụng cho truyền thông giữa các bộ vi điều khiển.
     REN: Bit cho phép nhận dữ liệu, khi sử dụng chức năng nhận dữ liệu qua cổng UART, phải bật bit này lên 1.
     TB8, RB8: Bit thứ 9 của truyền/nhận trong chế độ truyền 9 bit.
      TI, RI: Cờ báo ngắt truyền, ngắt nhận.

2. Thanh ghi sử dụng cài đặt tốc độ Baudrate: TMOD, TH1.

      Như các bạn thấy trong hình 1.2, tùy vào chế độ hoạt động mà tốc độ baudrate có cách tính khác nhau. Với chế độ được sử dụng thông dụng nhất, chế độ 1, 8 bit dữ liệu, 1 bit start, 1 bit stop. Tốc độ baudrate được xác định qua timer 1.
     Trước hết để sử dụng timer 1 để xác định tốc độ baudrate chúng ta cần cài đặt timer 1 ở chế độ 8 bit tự nạp lại. Do đó, cần gán giá trị 0x20 cho thanh ghi TMOD (TMOD = 0x20).
     Giá trị gán vào thanh ghi TH1 để xác định tốc độ baudrate được tính như sau.
     TH1 =256 - (F(crystal)/12/32/baudrate).    (Với F(crystal) tính bằng đơn vị Hz).
     Ví dụ: Muốn truyền UART với tốc độ baudrate là 9600 ta cần gán cho TH1 giá trị sau.
     TH1 =256 - (F(crystal)/12/32/9600).
     Nếu mạch sử dụng thạch anh 11.0592 MHz = 11059200 Hz, ta sẽ có:
     TH1 = 256 - (11059200/12/32/9600) = 253.
     Như vậy gán cho thanh ghi TH1 giá trị 253 (TH1 = 253), là ta đã cài đặt giao tiếp UART với tốc độ baudrate 9600.

3. Bit nhân đôi tốc độ baudrate.

     Trong 8051 có một bit được sử dụng để nhân đôi tốc độ truyền của giao tiếp UART. Đó là bit SMOD (bit thứ 7) trong thanh ghi PCON. Khi set bit SMOD lên 1, tốc độ truyền của giao tiếp UART sẽ được nhân đôi. 
     Trở lại với ví dụ ở mục 2 phía trên, nếu như chúng ta muốn sử dụng tốc độ baudrate 19200 thì giá trị gán cho TH1 phải là bao nhiêu? Mạch vẫn sử dụng thạch anh 11.0592 MHz.
     Theo công thức tính đã cho ở trên ta sẽ có:
     TH1 = 256 - (11059200/12/32/19200) = 254.5
     Nhưng số cần gán cho TH1 phải là một số nguyên, nếu chúng ta gán 254 hoặc 255 thì vẫn không đúng tốc độ baudrate 19200.
     Vậy để có được tốc độ baudrate 19200, chúng ta cần sử dụng bit nhân đôi tốc độ SMOD. Gán giá trị 253 cho thanh ghi TH1 (để có baudrate 9600), và set bit SMOD lên 1 để nhân đôi tốc độ lên 19200.


4. Thanh ghi truyền/nhận dữ liệu: SBUF.

     SBUF là thanh ghi 8 bit, được sử dụng chung cho cả truyền và nhận dữ liệu trong UART.
     Để truyền dữ liệu, chúng ta chỉ cần ghi dữ liệu vào thanh ghi SBUF.
     Để nhận dữ liệu chúng ta đọc giá trị từ thanh ghi SBUF.

II. Các bước thiết lập để truyền/nhận dữ liệu qua UART với 8051.

1. Thiết lập chế độ truyền, tốc độ baudrate.

     1. Ghi giá trị 0x20 vào thanh ghi TMOD để cài đặt sử dụng timer 1 ở chế độ 8 bit, tự nạp lại (TMOD = 0x20).
     2. Ghi vào thanh ghi TH1 giá trị thích hợp để chọn tốc độ baudrate. Giá trị này được tính dựa vào công thức đã cho ở mục 2 trong phần I.
     3. Ghi vào thanh ghi SCON giá trị 0x50 để thiết lập chế độ truyền 8 bit, 1 bit start, 1 bit stop (SCON = 0x50 (SM0 = 0, SM1 = 1, REN = 1)).
     4. Bật bit TR1 để khởi động timer 1.
 

    TMOD = 0x20;    //Timer 1, 8bit tu nap lai
    TH1 = 253;     //Buadrate: 9600
    SCON = 0x50;   //SM0 = 0, SM1 = 1; REN = 1;
    TR1 = 1;   // khoi dong timer 1
 

2. Truyền 1 ký tự.

     1. Ghi ký tự vào thanh ghi SBUF để truyền đi.
     2. Chờ cho cờ TI được bật.
     3. Xóa cờ TI để sử dụng cho lần truyền ký tự tiếp theo.

Hàm truyền 1 ký tự được viết như sau.
 

/*Ham truyen 1 ky tu*/
void UART_PutChar(unsigned char chr)
{
 SBUF = chr;           //ghi ky tu vao SBUF de truyen
 while(TI == 0);       //Cho cho co TI bat len 1
 TI = 0;
}    
 


3. Nhận 1 ký tự.

     1. Chờ cờ RI được bật báo có dữ liệu đến.     2.  Đọc dữ liệu từ thanh ghi SBUF.
     3. Xóa cờ RI cho lần nhận dữ liệu tiếp theo.
Hàm nhận dữ liệu không dùng ngắt được viết như sau.
 

/*Ham nhan 1 ky tu*/
unsigned char UART_GetChar(void)
{
 unsigned char temp;
 while(RI == 0);    //Cho co RI duoc bat len 1 bao co du lieu den
 temp = SBUF;          // doc du lieu 
 RI = 0;               // xoa co RI de lan nhan tiep theo
 return temp;
}
 


4. Nhận dữ liệu sử dụng ngắt.

     Thông thường, với một công việc thụ động như nhận dữ liệu qua UART thì việc sử dụng ngắt sẽ tiện lợi hơn rất nhiều. VĐK 8051 cho phép thiết lập ngắt UART bằng cách bật 2 bit ES và EA trong thanh ghi IE lên 1.
     Sau đó chúng ta có thể sử dụng hàm ngắt nhận dữ liệu như sau để nhận dữ liệu.

 

/*ISR UART*/
void ISR_UART(void) interrupt 4
{
 if(RI == 1)           //Kiem tra xem la ngat nhan hay truyen
 {
    chr_isr = SBUF;   //nhan du lieu
    RI = 0;
 }
}
 
     
Các bạn có thể tham khảo source code và mô phỏng Tại Đây.   
Pass giải nén: dientu79.blogspot.com
Hãy Like Fanpage để cập nhật thông tin bài viết mới nhất.

Thứ Hai, 28 tháng 3, 2016

Bài 6: Timer/Counter với 8051

Chào các bạn!

     Hôm nay, mình xin giới thiệu với các bạn cách cấu hình và sử dụng bộ Timer/Counter với 8051.
     Bộ Timer/Counter trong 8051 có thể được sử dụng trong rất nhiều ứng dụng như đếm sự kiện (Counter)  trên chân T0(P3.4), T1(P3.5), sử dụng tạo hàm delay với độ chính xác cao, sử dụng tạo tín hiệu PWM, sử dụng ngắt timer để quét led 7 thanh...
     Trong bài viết này mình sẽ hướng dẫn các bạn sử dụng timer trong 8051 ở chế độ counter và sử dụng timer để tạo hàm delay. Ứng dụng tạo PWM sử dụng timer mình sẽ đề cập trong một bài viết khác.

I. Các thanh ghi điều khiển bộ Timer/Counter trong 8051.

1. Thanh ghi TMOD.

     Cả hai bộ Timer/Counter(bộ T/C) 0 và 1 của 8051 đều sử dụng chung thanh ghi TMOD để thiết lập các chế độ hoạt động của bộ T/C. Thanh ghi TMOD là thanh ghi 8 bit, có 4 bit thấp dành cho bộ T/C0 và 4 bit cao dành cho bộ T/C1
Hình 1.1: Thanh ghi TMOD.
     Ý nghĩa các bit trong thanh ghi TMOD như sau.
GATE: GATE = 1: Bộ T/C được cho phép hoạt động khi chân INTx ở mức cao và bit TRx trong thanh ghi TCON được set lên 1. (x: 0 hoặc 1).
             GATE = 0: Bộ T/C được cho phép hoạt động khi bit TRx trong thanh ghi TCON được set lên 1.
CT: CT = 1: Chức năng counter được chọn.
       CT = 0: Chức năng timer được chọn.
M1, M0: 2 bit chọn các chế độ hoạt động của T/C.

M1                 M0                    Mode                                           Mô tả

0                      0                         0             Chế độ định thời 13 bit, 8 bit THx, 5 bit TLx

0                      1                         1             Chế độ định thời 16 bit.

1                      0                         2             Chế độ 8 bit tự nạp lại.

1                      1                         3             Chế độ bộ định thời chia tách.

2. Thanh ghi TCON.

Hình 1.1: Thanh ghi TCON.
     Thanh ghi TCON có 4 bit cao chứa các bit điều khiển và các bit cờ báo trạng thái của các bộ T/Cx.
     Ý nghĩa 4 bit cao của thanh ghi TCON như sau.

TF1: Cờ báo tràn bộ T/C1.
TR1: Bit điều khiển khởi động hoặc dừng bộ T/C1.
TF0: Cờ báo tràn bộ T/C0.
TR0: Bit điều khiển khởi động hoặc dừng bộ T/C0.

3. Thanh ghi chứa giá trị THx, TLx.

     Cả hai bộ T/C (T/C0 và T/C1) đều có các thanh ghi chứa giá trị bao gồm 16 bit, nhưng được truy cập theo 2 byte, byte cao THx và byte thấp TLx.
     Đối với bộ T/C0 thì 2 byte của thanh ghi chứa giá trị là TH0 và TL0, tương tự đối với T/C1 là TH1 và TL1.

II. Cấu hình Timer/Counter hoạt động ở chế độ counter.

     Sau đây mình sẽ hướng dẫn các bạn cấu hình bộ timer/counter 0 trong 8051 để thực hiện bài toán đếm xung cạnh xuống (falling edge) trên chân T0 và hiển thị số đếm lên LCD1602.
     Sơ đồ mạch mô phỏng như sau.
Hình 2.1: Sơ đồ mạch mô phỏng.
     Các bước cấu hình cho timer/counter 0 như sau.
1. Ghi vào thanh ghi TMOD để chọn chế độ Counter, chọn mode (8bit hoặc 16bit hoặc 13bit). Ở đây mình sẽ chọn chế độ counter nên sẽ set bit C/T=1, Mode 16 bit: M1 = 0, M0 = 1. ==>Giá trị ghi vào TMOD là 0x05. (Chỉ sử dụng Timer 0).
2. Set bit TR0 (TR0 = 1) để cho phép timer 0 hoạt động.
3. Lấy giá trị trong thanh ghi TL0, TH0 và lưu và trong một biến 16 bit và sau đó hiển thị lên LCD.

     Đoạn code trong chương trình main được viết như sau.

 

 /*Cau hinh Timer0 che do counter*/
 TMOD = 0x05; //CT=1, M1=0, M0=1. Couter, Mode 16bit
 /*Enbale Timer0*/
 TR0 = 1;
 /*Init LCD*/
 lcd1602_init();
 lcd1602_clear();
 lcd1602_gotoxy(0,0);
 lcd1602_puts("COUNTER USE 8051");
 lcd1602_gotoxy(0,1);
 lcd1602_puts("COUNTER=");
 while(1)
 {
  /*Doc gia tri tu TH0 va TL0*/
  low_byte = TL0;
  high_byte = TH0;
  bt_num=(high_byte*256)+low_byte;
  sprintf(lcd_buff,"%d",bt_num);
  lcd1602_gotoxy(9,1);
  lcd1602_puts(lcd_buff);
  
 }
 

     Trong đoạn code trên, các bạn thấy chỉ có 2 dòng lệnh sử dụng cho việc cấu hình Timer 0.
TMOD = 0x05;
TR0 = 1;
     Trong vòng lặp while(1), giá trị của thanh ghi TL0, TH0 liên tục được cập nhật và đưa vào biến bt_num, sau đó được hiển thị lên LCD.
     Các bạn có thể download source code và mô phỏng Tại Đây để tham khảo.
     Pass giải nén: dientu79.blogspot.com
     Hãy Like Fanpage để cập nhật thông tin bài viết mới nhất.

III. Cấu hình Timer/Counter hoạt động ở chế độ counter.

     Tiếp theo, mình sẽ hướng dẫn các bạn sử dụng T/C 0 của 8051 để sử dụng chức năng định thời. Mình sẽ dùng bộ T/C0 để viết một chương trình con delay.
     Nguyên tắc hoạt độn của bộ timer/counter ở chế độ timer như sau. 
     Khi bit TR của bộ T/C được set, bộ T/C sẽ được cho phép hoạt động, và cứ mỗi xung nhịp clock thì giá trị của thanh ghi chứa giá trị TH0, TL0 tăng lên 1(bắt đầu từ giá trị được cài đặt, mặc định là 0). Phụ thuộc vào mode hoạt động (8bit, 13bit, hay 16bit) mà giới hạn tràn của thanh ghi chứa giá trị là khác nhau. 
     Với mode 8bit, chỉ có thanh ghi TL được sử dụng để định thời, thanh ghi TH được sử dụng để ghi giá trị khởi tạo, và mỗi khi thanh ghi TL bị tràn (vượt quá 255) thì giá trị trong thanh ghi TH được tự động load vào thanh ghi TL. Vậy nên chế đọ này được gọi là 8 bit tự nạp lại.
     Với mode 16 bit, thì cả 2 thanh ghi TL và TH đều sử dụng chứa giá trị của T/C. Và khi T/C tràn (giá trị TH,TL vượt quá 65535) thì sẽ được reset về 0 và đồng thời cờ báo tràn TF được bật. Vậy nên sau khi tràn, phải khởi tạo lại giá trị cho TH,TL để có được thời gian định thì mong muốn.
     Mode 13 bit tương tự mode 16 bit.
     Các bước cấu hình cho bộ T/C0 hoạt động cở chế độ timer (định thời) như sau.
1. Ghi vào thanh ghi TMOD để chọn chế độ timer, chọn mode: Ví dụ ở đây mình chọn chế độ timer (C/T = 0) và mode 16 bit (M1=0, M0=1), mình sẽ ghi giá trị 0x01 vào TMOD (TMOD = 0x01).
2. Ghi vào thanh ghi TL0, TH0 các giá trị để tạo ra giá trị định thời mong muốn. Ví dụ mình muốn định thời 1ms (với thạch anh 12MHz), mình sẽ ghi vào thanh ghi giá TH, TL giá trị (65536 - 1000 =64536). Vì với thạch anh 12MHz, xung nhịp của 8051 là 1/12 của tần số thạch anh là 1MHz. Tương ứng với một xung nhịp là 1us, do vậy để có thời gian 1ms = 1000us, mình cần cho bộ T/C đếm 1000 lần. Mình gán giá trị 64536 bởi vì sau 1000 lần tăng giá trị thì T/C sẽ tràn và khi đó cờ TF sẽ bật lên 1. Chỉ cần kiểm tra cờ TF là mình biết đã đủ 1ms hay chưa. 

3. Set thanh ghi TR để cho phép bộ T/C hoạt động.
4. Kiểm tra cờ TF để biết bộ T/C đã tràn hay chưa.
5. Khởi tạo lại giá trị cho các thanh ghi TH,TL để chuẩn bị cho lần chạy tiếp theo.

Chương trình con delay_1ms được viết như sau.
 

 /*Ham delay su dung timer*/
 void delay_1ms(void)
 {
  TMOD = 0x01;   //Timer 0, mode 16 bit
  /*Gan gia tri 64536 cho thanh ghi TH0, TL0*/
  TL0 = 0x18;    //byte thap cua gia tri 64536
  TH0 = 0xFC;    //byte cao cua gia tri 64536
  TF0 = 0;       //xóa co bao tran TF0
  TR0 = 1;       //Cho phep timer 0 hoat dong
  while(TF0 == 0); //Cho cho bo timer tran
  TR0 = 0;   //Ngung timer 0
 }
 

     Đoạn chương trình trên khá đơn giản, Sau khi khởi tạo chọn chế độ cho thanh ghi TMOD. Giá trị 64536 được gán vào TL0 và TH0. 64536 là một số 16bit nên chúng ta cần tách ra 2 byte thấp và cao để đưa vào các thanh ghi TL0, TH0 tương ứng. Sau đó xóa cờ báo tràn và cho phép timer chạy bằng lệnh TR0 = 1; Câu lệnh while(TF0 == 0); sẽ chờ cho đến khi timer tràn (65536). Như vậy từ 65534 đến 65536 bộ timer đã tăng 1000 giá trị, mỗi lần tăng một giá trị là 1 xung nhịp clock (chu kỳ 1us). Như vậy khi gọi chương trình trên, mất 1ms=1000us thì mới thoát khỏi được chương trình.
     Trong các bài tiếp theo mình sẽ trình bày ngắt timer để quét led 7 thanh và sử dụng timer để tạo PWM điều khiển động cơ.
     Hãy Like Fanpage để cập nhật thông tin bài viết mới nhất.
Website được thực hiện bởi: cửa hàng linh kiện điện tử Đức Long https://muabanlinhkien.net/

Chủ Nhật, 27 tháng 3, 2016

Bài 5: Ngắt ngoài với 8051

Chào các bạn!

Hôm nay, mình xin giới thiệu đến các bạn cách cấu hình và sử dụng ngắt ngoài với VĐK 8051.

I. Các nguồn ngắt của VĐK 8051.

     Vi điều khiển 8051 gồm có sáu nguồn ngắt như sau (Reset cũng là một nguồn ngắt).

II. Các thanh ghi điều khiển ngắt của 8051.

1. Thanh ghi cho phép ngắt/cấm ngắt IE (Interrupt enable).
Hình 2.1: Thanh ghi cho phép ngắt/cấm ngắt.
Ý nghĩa của các bit trong thanh ghi IE như sau.

EX0: Cho phép (EX0 = 1) hoặc cấm (EX0 = 0) ngắt ngoài 0.
ET0: Cho phép (ET0 = 1) hoặc cấm (ET0 = 0) ngắt timer 0.
EX1: Cho phép (EX1 = 1) hoặc cấm (EX1 = 0) ngắt ngoài 1.
ET1: Cho phép (ET1 = 1) hoặc cấm (ET1 = 0) ngắt timer 1.
ES: Cho phép (ES = 1) hoặc cấm (ES = 0) ngắt cổng nối tiếp.
ET2: Cho phép (ET2 = 1) hoặc cấm (ET2 = 0) ngắt timer 2.
EA: Cho phép (EA = 1) hoặc cấm (EA = 0) ngắt toàn cục. 

2. Thanh ghi TCON.
     Thanh ghi TCON là thanh ghi có chứa các bit điều khiển hoạt động timer, các bit cờ báo tràn timer, các bit cấu hình ngắt kích phát mưc/kich phát sườn sử dụng cho ngắt ngoài. 
Hình 2.2: Thanh ghi TCON.

Ý nghĩa của các bit trong thanh ghi TCON như sau.

TF1: Cờ báo tràn của timer 1. Được set lên 1 khi timer 1 tràn và được xóa bởi phần cứng khi chương trình nhày vào trình phục vụ ngắt (chương trình ngắt).
TR1: bit điều khiển hoạt động của timer 1. TR1 = 1: timer 1 bắt đầu hoạt động, TR1 = 0: Dừng timer 1.
TF0: Tương tự TF1, nhưng sử dụng cho timer 0.
TR0: Tương tự TR1, nhưng sử dụng cho timer 0.
IE1: Cờ ngắt ngoài 1 kích phát sườn, được set lên 1 khi phát hiện có sườn xuống ngắt ngoài, và được xóa khi ngắt được xử lý.
IT1: Bit điều khiển kiểu ngắt ngoài 1. Có 2 kiểu ngắt ngoài là ngắt kích phát mức và ngắt kích phát sườn. Bit IT1 được sử dụng để chọn 1 trong 2 kiểu ngắt ngoài này cho ngắt ngoài 1. Khi IT1 = 0, ngắt ngoài 1 là ngắt kích phát mức, ngược lại IT1 = 1, ngắt ngoài 1 là ngắt kích phát sườn.
IE0: Tương tự IE1 nhưng sử dụng cho ngắt ngoài 0.
IT0: Tương tự IT1nhưng sử dụng cho ngắt ngoài 0.

III. Cấu hình ngắt ngoài cho 8051 sử dụng Keil C.

     Sau đây, mình xin chia sẻ cách cấu hình ngắt ngoài cho 8051 trong Keil C.
     Mình sẽ cấu hình sử dụng ngắt ngoài 0, đối với ngắt ngoài 1 các bạn có thể làm tương tự, chỉ khác nhau là thay đổi các bit cấu hình cho ngắt ngoài 0 sang ngắt ngoài 1.
     Sơ đồ mô phỏng được cho như sau.

Hình 3.1: Sơ đồ mạch mô phỏng.
     Đối với mạch điện như trên hình 3.1, mình sẽ viết chương trình sử dụng ngắt ngoài để đếm số trên led 7 thanh tăng giá trị từ 0 -> 9.
     Như các bạn thấy nút nhấn được nối vào chân P3.2, do vậy mình sẽ sử dụng ngắt ngoài 0 (EX0=1).
     Kiểu ngắt ở đây mình sử dụng ngắt kích phát sườn (IT0 = 1).
     Để sử dụng ngắt, chúng ta cần thực hiện 2 công việc. 1 là cấu hình các thanh ghi cho phép sử dụng ngắt, và 2 là viết chương trình thực hiện ngắt.
     Cấu hình các thanh ghi cho phép sử dụng ngắt được thực hiện trong chương trình chính. Để cấu hình cho phép sử dụng ngắt ngoài 0, kiểu ngắt kích phát sườn ta thực hiện như sau.


 

/*Cau hinh ngat ngoai 0*/
EX0 = 1; //cho phep ngat ngoai 0
IT0 = 1; //ngat kich phat suon
EA = 1;  //cho phep ngat toan cuc.
 

     Trong chương trình ngắt, chúng ta sẽ thực hiện công việc tăng giá trị của biến đếm và kiểm tra biến đếm có bị tràn (lớn hơn 9) hay không. Chương trình ngắt được viết như sau

 

/*Chuong trinh phuc vu ngat ngoai 0*/
void ISR_EX0 (void) interrupt 0
{
 bt_num ++;
 if(bt_num > 9)
  bt_num = 0;
}
 

     Công việc còn lại trong chương trình chính là xuất giá trị tương ứng với biến đếm bt_num ra led 7 thanh.

 

while(1)
 {
  /*Xuat gia tri ra led 7 thanh*/
  LED_PORT =  code_7_seg[bt_num];
 }
 

     Các bạn có thể download source code và chương trình mô phỏng Tại Đây.
     Chúc các bạn thành công.

Thứ Bảy, 12 tháng 3, 2016

Bài 4: Led 7 Thanh Đơn.

Chào các bạn!

     Led 7 thanh (Led 7 đoạn) được sử dụng rộng rãi trong các thiết bị điện tử, dùng để hiển thị số, ký tự. Hôm nay, mình xin chia sẻ với các bạn lập trình hiển thị led 7 thanh với 8051.

I. Cấu tạo led 7 thanh.

     Led 7 thanh được chia làm 2 loại, Led anot chung và led katot chung. Cả hai loại này có đều có cấu tạo từ 8 con led đơn ghép lại với nhau thành hình số 8 và 1 dấu chấm (xem hình dưới).
Hình 1.1: Cấu tạo chung của led 7 thanh.
     Nếu là led Anot chung thì 8 chân dương của led (chân Anot) sẽ được nối chung với nhau (chân COM ở hình 1.1), các chân Katot sẽ được đưa ra làm các chân dữ liệu A,B,C,D,E,F,G,DP. Để điều khiển led anot chung, chúng ta cấp nguồn dương vào chân anot chung (chân COM) và xuất dữ liệu tích cực mức 0 ra 8 chân dữ liệu để hiển thị theo ý muốn.
Hình 1.2: Cấu tạo bên trong led 7 thanh anot chung.

      Nếu là led Katot chung thì 8 chân âm của led (chân Katot) sẽ được nối chung với nhau (chân COM ở hình 1.1), các chân Anot sẽ được đưa ra làm các chân dữ liệu A,B,C,D,E,F,G,DP. Để điều khiển led anot chung, chúng ta cấp nguồn âm vào chân katot chung (chân COM) và xuất dữ liệu tích cực mức 1 ra 8 chân dữ liệu để hiển thị theo ý muốn.
Hình 1.3: Cấu tạo bên trong led 7 thanh katot chung.


II. Bảng mã led 7 thanh.

     Tùy vào sơ đồ mạch, tùy vào ký tự hay số muốn hiển thị mà dữ liệu xuất ra sẽ khác nhau. Sau đây mình xin đưa ra bảng mã led 7 thanh cho 2 loại led Anot chung và Katot chung với cách mắc mạch thông dụng nhất: Chân A,B,C,D,E,F,G,DP lần lượt nối vào các chân từ P2.0 - P2.7. (Mình nói đây là các thông dụng nhất bởi vì trong một số mạch ứng dụng, vì để dễ đi dây nên người thiết kế không mắc mạch theo thứ tự như trên nữa, mà họ mắc mạch sao cho khi thiết kế mạch in dễ đi dây nhất.)

     1. Bảng mã led các số từ 0-9 cho led 7 thanh Anot chung.

     2. Bảng mã led các số từ 0-9 cho led 7 thanh katot chung.


III. Lập trình hiển thị led 7 thanh với 8051.

     Để hiển thị 1 số trên led 7 thanh, ta chỉ cần xuất ra vi điều khiển mã hexa tương ứng với số đó. Ví dụ để hiển thị số 1 trên led 7 thanh anot chung, chúng ta xuất mã hexa 0xF9 ra các chân dữ liệu của led 7, tương tự như vậy, để hiển thị các số từ 0-9 các bạn chỉ cần xuất các mã tương ứng đã cho ở phần 2.
     Sau đây, mình xin giới thiệu đến các bạn chương trình thực hiện bài toán: mỗi lần nhấn nút BT1, số hiện thị trên led 7 sẽ tăng thêm 1 đơn vị, khi tăng vượt quá 9, thì sẽ nhảy về số 0, và khi nhấn BT2 thì số trên led 7 thanh sẽ giảm 1 đơn vị, khi giảm về dưới 0 thì sẽ nhảy lên 9.
     Sơ đồ mạch mô phỏng như sau.
Hình 3.1: Sơ đồ nguyên lý.
     Để thực hiện yêu cầu bài toán, mình sẽ dùng một biến để đếm số lần nhấn nút, khi nhấn nút BT1 mình sẽ tăng biến này lên một giá trị, khi nhấn nút BT2 mình sẽ giảm biến này đi một giá trị. Trong chương trình cũng phải kiểm tra giới hạn giá trị của biến khi lớn hơn 9 và nhỏ thua 0. Sau đó dùng biến này làm tham số để xuất giá trị hexa tương ứng ra led 7 thanh để hiển thị.
     Nội dung chương trình như sau.
   
     1. Khai báo mảng chứa các giá trị led 7 thanh ở đầu chương trình.
 

//khai bao mang cac so hien thi tren led 7 anot chung
unsigned char code_7_seg[10] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
                              // 0      1     2     3     4    5     6      7    8      9
 

     2. Nội dung chương trình chính.
 

        signed char bt_num = 0; 
 while(1)
 {
  /*Kiem tra nut nhan BT1*/
  if(BT1==0)
  {
   delay_ms(10);
   if(BT1==0)
   {
    while(BT1==0);
    bt_num++;
    if(bt_num > 9)
     bt_num = 0;
   }
  }
  /*Kiem tra nut nhan BT2*/
  if(BT2==0)
  {
   delay_ms(10);
   if(BT2==0)
   {
    while(BT2==0);
    bt_num--;
    if(bt_num <0)
     bt_num = 9;
   }
  }
  /*Xuat gia tri ra led 7 thanh*/
  LED_PORT =  code_7_seg[bt_num];
 }
 
   
     Các bạn có thể download source code và mô phỏng Tại Đây.
Website được thực hiện bởi: cửa hàng linh kiện điện tử Đức Long https://muabanlinhkien.net/

Chủ Nhật, 6 tháng 3, 2016

Bài 3: GPIO Với 8051: Nút Nhấn.

Chào các bạn!

     Nút nhấn (Button) là một linh kiện điện tử thông dụng trong các thiết bị điện tử. Nút nhấn thường được sử dụng để làm các nút điều khiển một chức năng nào đó, ví dụ nút điều chỉnh âm lượng, điều chỉnh độ sáng hay nút cho phép chọn các chế độ hoạt động...
     Hôm nay, mình xin giới thiệu đến các bạn bài viết sử dụng nút nhấn với vi điều khiển 8051. Ở bài trước, mình đã viết về việc sử dụng chân vi điều khiển 8051 xuất tín hiệu điều khiển led đơn (Output), hôm nay mình sẽ viết về việc sử dụng chân vi điều khiển 8051 để đọc tín hiệu từ nút nhấn (Input).

I. Sơ đồ nguyên lý.

     Trước hết, mình xin giới thiệu đến các bạn sơ đồ nguyên lý có sử dụng nút nhấn. Mình chỉ lấy sơ đồ mạch điều khiển led đơn ở bài trước và thêm hai nút nhấn vào P1.0 và P1.7 để điều khiển. Sơ đồ được cho như hình dưới.
 

     Các bạn lưu ý, khi mắc mạch sử dụng nút nhấn cho vi điều khiển 8051, các bạn nên mắc điện trở kéo ở chân vi điều khiển, điều này nhằm mục đích ổn định mức logic mặc định của chân VĐK khi nút chưa được nhấn. Ví dụ, ở sơ đồ trên, mình có mắc điện trở treo 10k lên nguồn dương. Vậy mặc định khi nút chưa được chấn, chân VĐK có mức logic 1 (5V), khi nút được nhấn, chân VĐK sẽ có mức logic 0 (0V).

II. Bài toán.

Mình xin được hướng dẫn các bạn làm quen lập trình VĐK 8051 với 2 bài toán như sau. 

1. Bài 1.

     Sử dụng 2 nút nhấn BT1 và BT2 lập trình điều khiển: Khi nhấn nút nhấn BT1, 8 led đơn D1-D8 sáng. Khi nhấn nút nhấn BT2, 8 led đơn D1-D8 tắt.
     Bài toán này khá đơn giản, chỉ cần kiểm tra mức logic trên 2 chân nối vào nút nhấn (P1.0 và P1.7), chân nào có mức logic 0 (tương ứng với nút được nhấn) thì mình sẽ thực hiện lệnh theo yêu cầu khi nút nhấn đó được nhấn. Vì ở đây đề bài không nói đến yêu cầu nhấn và giữ hay nhấn rồi nhả ra, nên mình chưa cần quan tâm vấn đề đó, chỉ cần biết rằng đã nhấn nút nhấn thì sẽ thực hiện lệnh, sau đó còn giữ hay thả ra thì chưa cần quan tâm.
     Để kiểm tra được mức logic trên chân VĐK (mức 0 hay mức 1), mình sẽ dùng câu lệnh "if". Lưu đồ thực hiện bài toán được cho như hình sau.
     Sau đây là đoạn code trong chương trình chính thực hiện bài toán đã cho.

 while(1)
 {
  /*Kiem tra xem BT1 co duoc nhan hay khong
  Neu duoc nhan, bat 8 led sang bang lenh P2 =0;
  Neu khong duoc nhan, di denh lenh tiep theo kiem 
                tra nut nhan BT2
  */
  if(BT1 == 0)
  {
   P2 = 0;       /*Bat 8 led sang*/
  }
  if(BT2 == 0)
  {
   P2=0xFF;     /*tat het 8 led*/
  }
 }
 

2. Bài 2.

       Sử dụng nút nhấn BT1 điều khiển theo yêu cầu: Ban đầu 8 led D1-D8 tắt, Khi nhấn nút nhấn BT1 1 lần (nhấn rồi nhả ra) thì 8 led D1-D8 sáng, sau đó tiếp tục nhấn nút BT1 thêm 1 lần nữa thì 8 led D1-D8 tắt, và tiếp tục lặp đi lặp lại như vậy.
   
     Với bài toán này, mấu chốt là mình phải đếm được số lần nhấn nút. Sau đó dựa vào số lần nhấn này điều khiển led. Để thực hiện bài toán này, mình sẽ dùng 1 biến để đếm số lần nhấn. Biến sẽ khởi tạo bằng 0, nếu nhấn lần thứ nhất biến tăng giá trị lên 1, lần thứ 2, biến tăng giá trị lên 2, nhưng khi nhấn lần thứ 3, mình sẽ reset giá trị biến về 1. Nghĩa là biến sẽ chỉ có 2 giá trị 1 hoặc 2. Nếu bằng 1 thì cho 8 led sáng, bằng 2 thì cho 8 led tắt.
     Sau đây là lưu đồ thuật toán cho ý tưởng trên.

Code được viết trong chương trình chính như dưới đây.

 
unsigned char bt_num = 0; 
 while(1)
 {
   /*Dem so lan nhan nut*/
   if(BT1==0)
   {
     delay_ms(10);   /*Chong nhieu*/
     if(BT1==0)
     {
       while(BT1==0);  /*Cho nut nhan dc nha*/
       bt_num ++; /*tang gia tri bien dem so lan nhan*/
       if(bt_num > 2)
              bt_num =1; /*Khi nhan hon 2 lan, 
                 reset gia tri bien dem ve 1
                               */
      }
   }
          /*Xu ly gia tri nhan nut*/
   if(bt_num == 1)
  P2 = 0;  /*bat 8 led sang*/
   if(bt_num == 2)
  P2 = 0xFF; /*tat 8 led */
 }
 

     Trên đây là cách sử dụng nút nhất với vi điều khiển 8051 của mình. Các bạn có thể tùy biến chương trình theo yêu cầu bài toán. Cái quan trọng là hiểu được yêu cầu bài toán để đưa ra thuật toán phù hợp.
     Chúc các bạn thành công!
     Website được thực hiện bởi: cửa hàng linh kiện điện tử Đức Long https://muabanlinhkien.net/






Thứ Hai, 29 tháng 2, 2016

Bài 1: Điều kiện cần đủ để mạch vi điều khiển 8051 hoạt động.

Chào các bạn!

     Trong một thời gian dài có cơ hội hỗ trợ kỹ thuật cho những người học tập, nghiên cứu về điện tử, mình nhận thấy có rất nhiều người khi mới bước đầu tìm hiểu về vi điều khiển 8051 (đặc biệt là các bạn sinh viên) thường mắc những lỗi cơ bản khi thiết kế mạch sử dụng vi điều khiển 8051 dẫn đến mạch không chạy. "Không chạy" ở đây mình muốn nói là bản thân vi điều khiển 8051 chưa thực hiện chương trình do chưa đáp ứng đủ những điều kiện cần thiết cho bản thân vi điều khiển chứ mình chưa nói đến việc không chạy do lỗi của mạch ngoại vi.
     Do vậy, trong loạt bài viết về vi điều khiển 8051 này, mình xin dành bài đầu tiên để giới thiệu khái quát một số tính năng của vi điều khiển 8051 và những điều kiện cần và đủ khi thiết kế mạch sử dụng vi điều khiển 8051.

I. Một Số Thông Số Kỹ Thuật Của Vi Điều Khiển 8051.

     Khi làm việc với bất kì một dòng vi điều khiển nào đó, các bạn nên tham khảo datasheet của nó để có được những thông số kỹ thuật và tính năng mà dòng vi điều khiển đó có để có thể giúp các bạn thiết kế ứng dụng tốt hơn, tránh được những sai sót. Sau đây mình xin nêu ra một số thông số như dung lượng bộ nhớ flash, ram, điện áp hoạt động, tần số thạch anh max của dòng vi điều khiển 8051. Cần chi tiết hơn, các bạn vui lòng tham khao datasheet.


Bảng 1.1: Một số thông số của VĐK 8051.

     Lưu ý là đối với dòng AT89S (AT89S51, AT89S52) thì tần số thạch anh lớn nhất là 33MHz.

II. Một Số Điều Kiện Cần Và Đủ Để Mạch VĐK 8051 Hoạt Động.

 1. Cung cấp đủ nguồn cho vi điều khiển.

     Đối với một thiết bị điện tử thì nguồn điện chính là một phần không thể thiếu để có thể hoạt động được. Vi điều khiển cũng vậy, đối với VĐK 8051 các bạn cần thiết kế một mạch cung cấp nguồn ổn định (Không bị nhiễu) để cấp cho vi điều khiển (chân 20 và 40 của AT89X51, AT89X52). Các bạn có thể sử dụng các IC ổn áp như 7805, LM2596, LM2576, AMS1117.... Sau đây, mình xin giới thiệu một mạch nguồn sử dụng IC ổn áp 7805 thường được dùng cho các mạch vi điều khiển.


Hình 2.1: Mạch nguồn dùng 7805.
     Khi thiết kế mạch nguồn thì các bạn nên thiết kế led báo nguồn như sơ đồ trên để khi chạy chúng ta sẽ biết được mạch đã có nguồn hay chưa. Khi mạch đã có nguồn (led báo nguồn sáng), các bạn nên kiểm tra thêm, dùng đồng hồ đo volt đo trên 2 chân 40 và 20 của vi điều khiển đã có điện áp trong khoảng 4.5V - 5V hay chưa, nếu chưa có, cần kiểm tra lại.

2. Mạch dao động và Reset.

     Vi điều khiển muốn hoạt động được cần có một nguồn tạo dao động. Trong các mạch vi điều khiển thường sử dụng thạch anh để tạo dao động.
     Mỗi VĐK có một chân gọi là chân RESET, đối với dòng AT89X51, 52 thì chân RESET là chân số 9. Đây là chân mà khi được đưa lên mức 1 (5V) VĐK sẽ rơi vào trạng thái reset, do vậy để VĐK hoạt động, chân này cần được nối qua một trở 4.7k - 10k xuống mass để khi bình thường, trạng thái trên chân 9 (RESET) là mức 0, trạng thái chip hoạt động. Khi cần một nút nhấn để reset mạch, các bạn nên mắc một nút nhấn nối giữa chân 9 và nguồn dương.
     Sau đây, mình xin giới thiệu mạch dao động dùng thạch anh và mạch reset thường được dùng cho vi điều khiển 8051.

Hình 2.2: Mạch dao động và reset.

    Các bạn chú ý là khi các bạn không có mạch dao động thạch anh hoặc chân số 9 của vi điều khiển vô tình bằng cách nào đó bị kéo lên mức 1 (5V) thì vi điều khiển sẽ không hoạt động, vậy nên khi mạch không chạy các bạn nên kiểm tra xem mạch dao động thạch anh và mạch reset đã đúng hay chưa.

3. Chân 31 (EA/VPP) của VĐK 8051.

     Khi các bạn thiết kế mạch vi điều khiển không sử dụng bộ nhớ ngoài để chứa chương trình (code) thực thi, các bạn cần nối chân (EA/VPP) này lên nguồn dương (5V). Đây là chân chọn bộ nhớ lưu giữ chương trình thực thi của vi điều khiển. Khi các bạn nối lên +5V là các bạn đã chọn thực thi chương trình từ bộ nhớ flash bên trong VĐK. Do vậy các bạn cần chú ý tới chân này khi thiết kế mạch ứng dụng VĐK 8051.

4. Trở treo cho PORT P0.

     Đối với VĐK 8051, khi các bạn sử dụng chân của port P0 để điều khiển thì các bạn phải sử dụng trở treo cho các chân port P0. Thường sử dụng trở băng 10k cho 8 chân của port P0.

5. Đưa ra các chân mạch nạp.

     Đây không phải là điều kiện để mạch hoạt động, nhưng mình đưa thêm lưu ý này vào đây, để khi thiết kế mạch, các bạn vẽ thêm các chân mạch nạp để trong quá trình test code sẽ nạp trực tiếp onboard (chỉ dùng được với dòng 89S có hỗ trợ chuẩn nạp ISP) sẽ tiện lợi hơn rất nhiều là khi các bạn cứ phải tháo chip ra vào, dễ làm gãy chân chip.

     Trên đây là một số lưu ý cho các bạn khi mới bắt đầu làm việc với dòng VĐK 8051. Đặc biệt là các bạn sinh viên khi lấy mạch được chia sẻ trên mạng có mô phỏng bằng proteus. Các bạn lưu ý là trong proteus không có 2 chân nguồn 20, 40 đưa ra ngoài (nó đã được ngầm hiểu đã nối nguồn), không cần mạch dao động hay reset vẫn mô phỏng được. Do đó khi các bạn lấy mạch mô phỏng về muốn làm chạy thì các bạn phải thêm đầy đủ các mạch mình đã nói ở trên. Mình gặp nhiều trường hợp sinh viên nhờ kiểm tra sao mạch làm đúng trên mạng mà vẫn không chạy? Mình kiểm tra thấy chân 20, 40 bỏ trống. Hỏi ra mới biết các bạn thấy mạch mô phỏng không có nên không vẽ :D.
     Chúc các bạn thành công!






Chủ Nhật, 28 tháng 2, 2016

Bài 2: GPIO với 8051: Điều khiển led đơn.

 I. Mở Đầu.

Chào các bạn!

     Một trong những bài học căn bản khi các bạn bước đầu tìm hiểu về một dòng vi điều khiển nào đó là bài học về GPIO (điều khiển vào/ra với các chân của vi điều khiển). Bài học này giúp cho các bạn bước đầu cảm thấy hứng thú để tiếp tục theo đuổi niềm đam mê lập trình vi điều khiển và đây cũng là bài học cơ bản giúp các bạn hiểu về cách xuất tín hiệu/nhận tín hiệu trên các chân của vi điều khiển.
     Cũng với mục đích như vậy, hôm nay mình xin gửi đến các bạn bài viết hướng dẫn điều khiển led đơn với vi điều khiển 8051. điều khiển led đơn xin được cắt nghĩa ở đây là dùng vi điều khiển xuất tín hiệu để bật/tắt led (1 hoặc nhiều led), hoặc có thể xây dựng hiệu ứng sáng cho nhiều led tùy vào mục đích của người dùng.

II. Nguyên Lý Điều Khiển LED.

     Để điều khiển được led, ngoài kiến thức về lập trình(Software), các bạn cũng cần có kiến thức về phần cứng (Hardware) để khi nhìn sơ đồ mạch có thể hiểu được khi nào thì led sẽ sáng và khi nào led sẽ tắt. 
     Có những mạch khi xuất mức 0 (0V) ra chân của vi điều khiển thì led sáng, nhưng cũng có những mạch khi xuất mức 1(5V) ra chân của vi điều khiển thì led mới sáng. Nhưng cho dù có ở mạch nào thì để điều khiển led đơn sáng thì phải tuân thủ nguyên tắc led sáng khi có dòng điện chạy qua led, nghĩa là phải có sự chênh lệch áp giữa hai cực Anot và Katot của led. Mình xin giới thiệu 2 dạng mạch điện điều khiển led đơn dùng vi điều khiển như sau.
                                
                                   
         Hình 1.1: Led sáng khi xuất mức 0                           Hình 1.2: Led sáng khi xuất mức 1

     Mình xin giải thích sơ đồ hình 1.1. Như mình đã nói để led sáng thì cần làm sao cho có dòng điện chạy qua led, nghĩa là có sự chênh lệch áp giữa 2 cực Anot, Katot của led. Nhìn vào hình 1.1 ta thấy cực Anot của led được nối qua trở 330R lên nguồn 5V, vậy để có dòng điện chạy qua led ta cần xuất mức 0 (0V) ra chân của vi điều khiển, khi đó led sẽ sáng, và để tắt led ta sẽ xuất mức 1(5V) ra chân của vi điều khiển, khi đó sẽ không có dòng chạy qua led và led sẽ tắt. Dòng chạy qua led không được quá lớn nên chúng ta cần phải sử dụng trở hạn dòng để tránh cháy led như trên 2 sơ đồ đã cho. Sơ đồ hình 1.2 chắc mình không cần giải thích nữa :D.
     Thôi, nói lan man như vậy đủ rồi, bây giờ đi vào chủ đề chính, điều khiển led đơn với 8051. Trước hết mình xin giới thiệu sơ đồ nguyên lý mình sử dụng. Đây cũng chính là sơ đồ nguyên lý điều khiển led đơn trên Kit 8051 Basic. Chi tiết về Kit này các bạn có thể xem tại đây.

III. Viết Chương Trình.

     1. Các bạn mở Keil C và tạo một project để viết chương trình điều khiển led đơn theo sơ đồ trên. Bạn nào chưa biết tạo project với Keil C có thể tham khảo bài viết: Hướng dẫn tạo project với Keil C.
     2. Phần đầu chương trình cũng như bao chương trình C khác, mình gọi thư viện và define các macro chân điều khiển led.

//su dung thu vien
#include <at89x52 .h>
//Define macro port dieu khien led
#define  LED_PORT   P2
//Define macro chan dieu khien led
#define   LED1           P2_0
#define  LED2    P2_1
#define  LED3    P2_2
#define  LED4    P2_3
#define  LED5    P2_4
#define  LED6    P2_5
#define  LED7    P2_6
#define  LED8    P2_7

Việc sử dụng lệnh #define này giúp cho việc quản lý bảo trì code dễ hơn, ví dụ, khi bạn vẫn sử dụng chương trình này cho một mạch khác, có led nối vào chân khác của vi điều khiển, bạn chỉ cần thay thế code ở phần define này. Và việc đặt tên bằng define này cũng giúp cho người khác khi đọc code của bạn viết sẽ dễ hiểu hơn.

     3. Bật/Tắt Led trên 1 chân.

     Để bật/tắt led trên 1 chân nào đó, chúng ta xuất tín hiệu điều khiển (mức 0 hoặc 1) ra trực tiếp chân đó. Ví dụ như trên sơ đồ, led D1 được nối vào chân P2_0, vì vậy để bật led D1 sáng mình xuất mức 0 ra chân P2_0 và để tắt led D1 mình xuất mức 1 ra chân P2_0. Vì chân P2_0 được define ở trên bằng tên LED1, do đó lệnh bật tắt led trên chân này như sau.

//chuong trinh chinh
void main (void)
{
 while(1)
 {
  /*Bat led 1*/
  LED1 = 0;
  /*Tat led 1*/
  LED1 = 1;
 }
}

     Như đoạn code trên thì led sẽ sáng rồi tắt và cứ lặp lại mãi mãi như vậy (do nằm trong while(1)), nghĩa là led nhấp nháy mãi mãi. Nhưng chương trình nếu chỉ như vậy thì các bạn sẽ không quan sát được hiện tượng nhấp nháy, bởi vì led sáng/tắt trong thời gian quá nhanh (cỡ đơn vị us nên mắt người không thể quan sát được hiện tượng nhấp nháy).
     Vậy làm sao để quan sát được hiện tượng nhấp nháy led này? Có một cách mà mọi người vẫn hay sử dụng, đó là sử dụng hàm trễ (delay). Hàm trễ là hàm có chức năng ra lệnh cho vi điều khiển thực hiện một công việc gì đó nhiều lần để khi làm xong công việc đó thì kéo dài một khoảng thời gian mà người lập trình mong muốn. Ý tưởng được đưa ra ở đây là sau khi bật led sáng sẽ cho vi điều khiển làm một công việc gì đó nhiều lần bằng hàm delay, để mắt người quan sát được led sáng, sau đó tắt led và cũng gọi hàm delay, để mắt người quan sát được led tắt, vậy là quan sát được hiện tượng led nhấp nháy. Nội dung hàm delay thường được viết như sau.

/*
Function name: delay_ms
parameter in:  time delay
return:        no
*/
void delay_ms(unsigned int time)
{
 unsigned int i,j;
 for(i=0;i<time;i++)
  for(j=0;j<125;j++);
}

     Để sử dụng hàm delay_ms ở trên rất đơn giản, các bạn muốn vi điều khiển trễ (delay) một khoảng thời gian bao nhiêu ms, các bạn chỉ gọi hàm và truyền tham số là thời gian trễ bằng đơn vị ms vào hàm. Ví dụ mình muốn trễ 1s = 1000ms mình sẽ gọi hàm như sau: delay_ms(1000);
     Vì vậy để led D1 nhấp nháy với chu kì 2s(nghĩa là led sáng trong 1s và led tắt trong 1s) mình sẽ sửa lại chương trình chính như sau.

//chuong trinh chinh
void main (void)
{
 while(1)
 {
  /*Bat led 1*/
  LED1 = 0;
  delay_ms(1000);   //goi ham delay voi time = 1000ms
  /*Tat led 1*/
  LED1 = 1;
  delay_ms(1000);   //goi ham delay voi time = 1000ms
 }
}

      4. Bật/Tắt 8 Led.

     Để bật/tắt cùng lúc 8 led thì có nhiều cách, có thể các bạn dùng 8 lệnh thao tác với 8 chân để bật tắt, hoặc có thể dùng cách xuất dữ liệu ra Port. Cách dùng xuất dữ liệu ra tầng chân để điều khiển 8 led thì mình sẽ không dùng, vì nó sẽ làm dài chương trình ra, vì vậy mình sẽ sử dụng cách xuất dữ liệu ra port, cụ thể ở sơ đồ trên là xuất dữ liệu ra port P2, được define bằng tên LED_PORT.
     Lệnh xuất dữ liệu ra port P2 như sau.

LED_PORT = giá_tri; //tuong duong voi: P2 = gia_tri;
     Các bạn nên hiểu giá trị ở đây bây giờ sẽ là giá trị của 8 bit (8 chân port P2), do vậy nó sẽ có giá trị trong khoảng 0-255(hệ thập phân) hay 0x00-0xFF hệ số hexa.
     Như vậy chương trình bật/tắt 8 led được viết như sau.

//chuong trinh chinh
void main (void)
{
 while(1)
 {
  /*Bat 8 led*/
  LED_PORT = 0x00;   
  delay_ms(1000);   //goi ham delay voi time = 1000ms
  /*Tat 8 led */
  LED_PORT = 0xFF;
  delay_ms(1000);   //goi ham delay voi time = 1000ms
 }
}

     5. Xây dựng các hiệu ứng khác.

     Để xây dựng các hiệu ứng khác như 1 led sáng từ trái sang phải, hoặc phải sang trái, hoặc led sáng đuổi....Các bạn nên sử dụng 1 biến 8 bit để chứa giá trị của led, sau đó xuất giá trị của biến này ra port điều khiển led, sau đó thay đổi giá trị tùy theo hiệu ứng mình muốn và lại tiếp tục xuất ra port điều khiển led.
     Sau đây, mình xin giới thiệu các bạn đến chương trình 1 led sáng từ trái sang phải. Các hiệu ứng khác các bạn tự tìm cách thay đổi nhé.
     Ý tưởng: Dùng 1 biến 8 bit có giá trị ban đầu 0x80, nghĩa là 7 led sáng, 1 led tắt. Nhưng khi mình xuất ra port điều khiển, mình sẽ xuất giá trị đảo của biến trên. Sau đó sử dụng lệnh dịch phải bit để dịch bit 1 sang phải để tạo hiệu ứng 1 led sáng từ trái sang phải. Chương trình như sau.

//chuong trinh chinh
void main (void)
{
    unsigned char led_value = 0x80; //bien chua gia tri sang cua led
    while(1)
       {
 /*Xuat giá tri ra port de lam sang led*/
 LED_PORT = ~led_value;
 delay_ms(1000);   //goi ham delay voi time = 1000ms
 /*dich phai 1 bit*/
 led_value >>= 1;
 if(led_value == 0)
   led_value = 0x80;
       }
}

     Mình xin giải thích lại đoạn chương trình trên như sau:
     Đầu tiên, minh khai báo biến led_value  có giá trị 0x80. (Dạng nhị phân 8 bit: 1000 0000).
     Sau đó mình xuất ra P2 giá trị đảo của led_value  nghĩa là P2 = 0x7F = 0111 1111 (Led D8 sáng).
     Gọi hàm delay_ms để có thể nhìn thấy led sáng.
     Dịch phải 1 bit giá trị của biến led_value: led_value >>= 1; sau lệnh này, giá trị của led_value là:
led_value = 0x40 = 0100 0000.
     Kiểm tra xem giá trị của biến led_value có bằng 0 hay không, giá trị của biến led_value = 0 khi đã dịch phải đủ 8 lần, nếu chưa bằng 0, nhảy đến lệnh xuất giá trị đảo của biến led_value ra P2, nếu bằng 0 thì reset lại giá trị của biến led_value để chạy lại từ đầu.

     Các bạn có thể tải toàn bộ chương trình và mạch mô phỏng trên Proteus tại link sau.
http://www.mediafire.com/download/4teo6u5s5593zca/Bai_1_Led_don.rar

Chúc các bạn thành công!





Thứ Bảy, 27 tháng 2, 2016

[Hướng Dẫn] Cài đặt KeilC V9.01 + Crack

Chào các bạn!

Hôm nay mình xin hướng dẫn các bạn cài đặt và crack Keil C uVision 4 bản dùng cho vi điều khiển 8051.
Các bạn có thể tải bộ cài đặt + Crack đi kèm tại đây.
Sau khi tải về, bạn giải nén ra sẽ thấy thư mục KeilC4, thư mục này chứa file cài đặt c51v901 và file crack keygen.exe.

I. Cài đặt: Các bạn làm theo các bước sau.

1. Chạy file cài đặt c51v901 (nên click chuột phải và chọn "Run as administrator"). Thư mục cài đặt xuất hiện như hình sau. Các bạn chọn "Next" để tiếp tục.

2. Tick chọn "agree to all the term of ..." và nhấn "Next" để tiếp tục.

3. Kiểm tra lại đường dẫn cài đặt và nhấn "Next" để tiếp tục.

4. Các bạn điền đầy đủ các thông tin như hình dưới và nhấn "Next" để tiếp tục.


5. Các bạn chờ một lúc để phần mềm tự động chạy cài đặt như hình dưới.

6. Sau đó, các bạn nhấn "Finish".

Như vậy là đã cài đặt xong Keil C V9.01 cho 8051, để sử dụng mà không bị giới hạn dung lượng code, chúng ta sẽ crack phần mềm này.

II. Crack.

1. Các bạn mở Keil C lên và vào File --> License Management... như hình sau.

2. Hộp thoại License Management xuất hiện, các bạn bôi đen và copy mã code CID như hình sau.

3. Các bạn chạy file crack keygen.exe (nên click chuột phải và chọn "Run as administrator" và nên cho nho âm lượng loa máy tính của bạn cho dễ chịu :D ). Các bạn chọn các thông số như sau.
           Target: C51
           CID:    Paste mã CID vừa copy được ở bước 2 phía trên vào.
           Nhấn: Generate và copy mã license và được tạo ra.


4. Quay trở lại hộp thoại License Management và làm như sau:
              Paste mã license vừa copy được ở bước 3 phía trên vào ô New License ID code (LIC)
              Sau đó nhấn: Add LIC.

5. Kết quả hộp thoại báo như sau là các bạn đã crack thành công. Nhấn Close để kết thúc.


Như vậy là mình đã hướng dẫn các bạn cài đặt và crack trình biên dịch Keil C V9.01 (cho 8051).
Trong các bài tiếp theo, mình sẽ hướng dẫn các bạn tạo Project và lập trình cho dòng vi điều khiển 8051 với Keil C.
Chúc các bạn làm việc và học tập thật tốt!