BÀI 07: GIAO TIẾP VỚI LCD

tháng 4 22, 2018
BÀI 07: GIAO TIẾP VỚI LCD
1.Giới thiệu về LCD

LCD là  một màn hình nhiều điểm ảnh, có thể coi là một led ma trận lớn, tuy nhiên chúng ta sẽ không cần đi vào điều khiển từng điểm ảnh mà chúng ta sẽ điều khiển qua lệnh. Có nhiều loại LCD, trong hướng dẫn này mình sẽ dùng loại 16x2. Trước tiên, hãy xem cấu tạo của nó.


Có hai cách để làm việc với LCD là gửi lệnh và gửi dữ liệu. Chúng ta sẽ lần lượt tìm hiểu hai cách này.

2. Gửi lệnh ra LCD


Một số lệnh khởi tạo LCD thường dùng.


3. Gửi dữ liệu ra LCD


Bước 1 thường là mặc định, các bước sau tương tự như việc gửi lệnh vào LCD. 
Tiếp theo, chúng ta sẽ thực hành 1 số thao tác với LCD. Vẽ mạch mô phỏng như sau:


Đầu tiên chúng ta sẽ thực hiện gửi 1 lệnh ra LCD, hàm như sau:


void LCD_Cmd(unsigned char cmd)
{
 RS = 0; 
 LCD_DATA = cmd;
 EN = 0;
 EN = 1;
 Delay_ms(2);
}

Tiếp theo là gửi dữ liệu, đầu tiên gửi một kí tự ra LCD
void LCD_Chr_Cp(char c)
{
 RS = 1;
 LCD_DATA = c;
 EN = 0;
 EN = 1;
 Delay_ms(1);
}
Chúng ta cũng có thể gửi một chuối ra LCD
void LCD_Out_String(char *str)
{
 unsigned char i=0;
 while(str[i]!=0)
  {
   LCD_Chr_Cp(str[i]);
   i++;
  }
 
}
Mặc định khi gửi lệnh hay dữ liệu, LCD sẽ hiển thị nó ở vị trí dòng 0 cột 0, chúng ta có thể xuất lệnh hay dữ liệu đến vị trí tùy ý bằng hàm LCD_Goto_xy() như sau:
LCD_Goto_xy(unsigned char x, unsigned char y, char c)
{
 unsigned char cmd;
      //  [1;0]  [1;1]
 cmd = (x == 1 ? 0x80 : 0xc0) + y - 1;
 LCD_Cmd(cmd);
 //Out character
 LCD_Chr_Cp(c);
}
Cuối cùng, khi chuỗi đang được hiển thị, chúng ta có thể dịch trái hoặc dịch phải với câu lệnh như hình dưới:

Để trở về trạng thái ban đầu, làm như sau:


Các bạn có thể tham khảo chương trình dưới đây:

/**
***********************************************************************
// File Name: LCD 16x2
// Author:  luonngduyhuynh2801@gmail.com
// Date: 
//Tap Lenh
  0x01 clear 
  0x02 Di chuyen con tro ve dau man hinh
  0x06 Di chuyen con sau ki tu
  0x0C Bat hien thi va tat con tro
  0x0E Bat hien thi va bat con tro
  0x80 move poiter ve dau dong 1
  0xC0 move poiter ve dau dong 2
  0x38 giao tiep 8 bit, 2 line, font 5x7
  0x28 giao tiep 4 bit, 2 line, font 5x7
  0x18 dich trai
  0x1c dich phai
  
  
//SET DDRAM address
  DB7  DB6  DB5  DB4  DB3  DB2  DB1  DB0
  1   [AD] [AD] [AD] [AD] [AD] [AD] [AD]
***********************************************************************/ 
#include "main.h"
#include "..\Lib\Delay.h"
sbit RS = P2^0;
sbit EN = P2^1;
#define LCD_DATA P3


void LCD_Cmd(unsigned char cmd)
{
 RS = 0; 
 LCD_DATA = cmd;
 EN = 0;
 EN = 1;
 Delay_ms(2);
}

void LCD_Chr_Cp(char c)
{
 RS = 1;
 LCD_DATA = c;
 EN = 0;
 EN = 1;
 Delay_ms(1);
}

void LCD_Out_String(char *str)
{
 unsigned char i=0;
 while(str[i]!=0)
  {
   LCD_Chr_Cp(str[i]);
   i++;
  }
 
}

//function set
void LCD_Init()
{
 LCD_Cmd(0x30);
 Delay_ms(3);
 LCD_Cmd(0x30);
 Delay_ms(1);
 LCD_Cmd(0x30);
 
 LCD_Cmd(0x38);  //8bit 2line font 5x7
 LCD_Cmd(0x01);
}

LCD_Goto_xy(unsigned char x, unsigned char y, char c)
{
 unsigned char cmd;
      //  [1;0]  [1;1]
 cmd = (x == 1 ? 0x80 : 0xc0) + y - 1;
 LCD_Cmd(cmd);
 //Out character
 LCD_Chr_Cp(c);
}

//
void main()
{
 Delay_ms(100);
 LCD_Init();
 //bat hien thi va con tro
 LCD_Cmd(0x0E);
 LCD_Chr_Cp('A');
 LCD_Out_String("Hello");
 while(1)
 {

 }
}
Hàm Delay() các bạn tự viết nhé, mình xóa mất rồi:))

BÀI 06: GIAO TIẾP VỚI NÚT NHẤN

tháng 4 20, 2018
BÀI 06: GIAO TIẾP VỚI NÚT NHẤN
1.Đọc đầu vào cơ bản
Việc đầu tiên chúng ta cần làm là đọc dữ liệu đầu vào ở một chân là mức 0 hay 1. Chúng ta thực hiện một bài toán đơn giản như sau: Đọc dữ liệu từ một chân vi điều khiển và xuất dữ liệu ra một chân khác.
Mạch nguyên lí như sau:


Chân 3.7 khi chưa nhấn nút sẽ có điện áp vào 5V, khi nhấn nút sẽ là 0V. LED nối với chân P2.0, LED sáng khi chân P2.0 ở 0V, tắt khi chân P2.0 ở 5V. Chương trình đọc và xuất dữ liệu như sau:
#include <regx52.h>

sbit LED = P2^0;
sbit BUTTON = P3^7;

int main()
{
 while(1)
 {
  LED=BUTTON;
 }
}
Đây là 1 chương trình đơn giản, khi nhấn nút thì chân P3.7=0V => chân P2.0=0V dẫn đến LED sáng.
Ngược lại khi không nhấn nút, chân P3.7=5V => chân P2.0=5V dẫn đến LED tắt.

2.Đọc đầu vào và xử lí nút nhấn
Bài toán 1: Chúng ta sử dụng 2 nút nhấn để điều khiển 1 đèn LED. Nhấn nút ON thì đèn sáng, nhấn nút OFF thì đèn tắt.
Mạch nguyên lí như sau:
Chân 3.7 tương ứng nút ON, 3.6 tương ứng nút OFF.
Chương trình như sau:

#include <regx52.h>

sbit LED = P2^0;
sbit ON  = P3^7;
sbit OFF = P3^6;
int main()
{
 LED=1;
 while(1)
 {
  if (ON==0)  //Nhan nut ON
  {
   LED=0;   //LED sang
  }
  if (OFF==0)  //Nhan nut OFF
  {
   LED=1;   //LED tat
  }
 }
}
Trong thực tế, chúng ta hay gặp hiện tượng "Dội phím" (nút nhấn dao động liên tục mức 0-1). Vi điều khiển có thể hiểu là rất nhiều lần nhấn-thả liên tiếp. Để khắc phục vấn đề này, khi đọc  trạng thái nút nhấn, chúng ta delay 1 khoảng để xác định chính xác nút được nhấn hay chưa. Viết lại chương trình như sau:


#include <regx52.h>

sbit LED = P2^0;
sbit ON  = P3^7;
sbit OFF = P3^6;
void Delay(int time);
int main()
{
 LED=1;
 while(1)
 {
  if (ON==0)  //Nhan nut ON
  {
   Delay(20);
   LED=0;   //LED sang
  }
  if (OFF==0)  //Nhan nut OFF
  {
   Delay(20);
   LED=1;   //LED tat
  }
 }
}

void Delay(int time)
{
 int i,j;
  for(i=0; i<time; i++)
  for(j=0; j<125; j++); 
}

Bài toán 2: Dùng 1 nút nhấn để điều khiển LED, nhấn 1 lần thì LED sáng, nhấn lần tiếp theo thì LED tắt.


Cách 1 : Dùng hàm While() để chờ chuyển mức
Sau khi chúng ta phát hiện dữ liệu xuống mức 0, chúng ta sẽ dùng vòng lặp while để chờ cho đến khi dữ liệu thoát khỏi mức 0 để xác nhận nút đã được nhấn. Lúc đó ta có thể thực hiện các chức năng khác tương ứng với việc nhấn nút.



Mạch nguyên lí như sau:


Chương trình như sau:

#include <regx52.h>

sbit LED = P2^0;
sbit BUTTON  = P3^7;
void Delay(int time);
int main()
{
 LED=1;
 while(1)
 {
  if (BUTTON==0)
  {
   Delay(20);
   if (BUTTON==0)
   {
    while(BUTTON==0){}
     LED=!LED;
   }
  }
 }
}

void Delay(int time)
{
 int i,j;
  for(i=0; i<time; i++)
  for(j=0; j<125; j++); 
}

Tuy nhiên, khi làm việc với nhiều nút nhấn, cách này không phù hợp mà nên sử dụng cách 2.

Cách 2 : So sánh dữ liệu trước và sau để phát hiện chuyển mức.



Ý tưởng: Chúng ta so sánh giữa mức ngay trước đó và mức mới. Nếu có sự sai khác giữa mức mới và mức ngay sau đó thì đồng nghĩa với việc có sự thay đổi về giá trị nút nhấn. Tùy thuộc vào mục đích của người lập trình chọn sườn lên hay sườn xuống để thực hiện lập trình theo ý muốn. Ở đây, mình chọn sườn xuống của nút nhấn để thực hiện.
Mạch nguyên lí như sau:


Chương trình:

#include <regx52.h>

sbit LED = P2^0;
sbit BUTTON  = P3^7;
bit BUTTON_OLD;
void Delay(int time);

int main()
{
 LED=1;
 while(1)
 {
  if (BUTTON==0)
  {
   Delay(20);
   if ((BUTTON==0)&&(BUTTON_OLD==1))
   {
     LED=!LED;
   }
  }
  //Cap nhat trang thái moi cua nut nhan
  BUTTON_OLD=BUTTON;
  Delay(20);
 }
}

void Delay(int time)
{
 int i,j;
  for(i=0; i<time; i++)
  for(j=0; j<125; j++); 
}
Good Luck!

BÀI 05: LẬP TRÌNH LED MATRIX VỚI 8051

tháng 4 17, 2018
BÀI 05: LẬP TRÌNH LED MATRIX VỚI 8051

I. Cấu tạo

 Hình trên là nguyên lí và cấu tạo của một con led ma trận 8x8, với 8 hàng và 8 cột. Để làm sáng 1 LED, chúng ta cần cấp điện áp VCC và GND vào 2 chân theo nguyên lí bàn cờ vua - vì vậy tốn 2 chân của vi điều khiển để điều khiển một con LED. Với tổng cộng 16 chân của LED matrix , theo cách bình thường chúng ta chỉ điều khiển được 16/2=8 con LED. Mà LED matrix có tất cả 64 LED, cho nên người ta sử dụng phương pháp quét led - giống như đã áp dụng với led 7 đoạn.

II. Phương pháp quét led
 Chúng ta sẽ điều khiển 8 led theo hàng 1 hoặc cột 1, sau đó đến hàng 2 hoặc cột 2,.. cứ thế cho đến hàng 8 hoặc cột 8. Vì tốc độ sáng tắt rất nhanh, nên do sự lưu ảnh ở mắt sẽ tạo thành 1 hình ảnh hoàn chỉnh.
 Khoảng thời gian quét được gọi là 1 chu kì quét. Lấy nghịch đảo sẽ có được tần số quét, thông thường khoảng 60Hz là ổn, tuy nhiên khuyến khích 120 Hz.
 Các loại màn hình cũng dùng phương pháp này, tần số quét được gọi là tần số làm tươi, reset frame. Màn hình có tần số làm tươi càng cao thì có khả năng thực hiện nhiều khung hình hơn, chuyển động mượt mà hơn.

III. Mạch nguyên lí


PORT 2 được dùng để điều khiển 8 hàng LED, PORT 3 dùng để điều khiển 8 cột LED.  PORT 2 cấp giá trị theo chân, PORT 3 được dùng đẻ xuất dữ liệu ra LED. Đèn LED sẽ sáng khi chân tương ứng ở PORT 3 có giá trị bằng 0.

IV. Chương trình điều khiển LED Matrix 8x8
 Ví dụ hiển thị chữ H (quét theo cột).
Đầu tiên các bạn cần lấy được 8 bit mã nhị phân tương úng với các trạng thái bật tắt của LED để tạo thành font chữ H, sau đó có thể đổi sang mã hex cho gọn. Phẫn mã font này xuất ra P2 và mình sẽ đưa vào 1 mảng dữ liệu như sau:

unsigned char code chuH[]={0x00,0x00,0xE7,0xE7,0xE7,0xE7,0x00,0x00};
Tiếp theo là hàm Delay để làm trễ, nếu không mắt sẽ không kịp nhìn thấy.
void Delay (unsigned int time)
{
 while(time--);
} 
Trong vòng lặp chính, xuất dữ liệu ra cổng P2, bật chân P3.0, sau đó delay cho mắt kịp nhìn, tắt P3.0.... cứ thế đến P3.7 là hết 1 chu kì quét.
#include<REGX52.H>

unsigned char code chuH[]={0x00,0x00,0xE7,0xE7,0xE7,0xE7,0x00,0x00};
void Delay (unsigned int Time);

void main (void)
{
 unsigned char i;
 while(1)
 {
  for (i=0; i<8; i++)
  {
   P2 = chuH[i];
   P3 = 0x01<<i;
   Delay(60);
   P3 = 0x00;
 }
}

void Delay (unsigned int time)
{
 while(time--);
} 

Các bạn có thể làm tương tự với các kí tự khác. Và mở rộng trên Led matrix có kích thước lớn hơn.

BÀI 04: LẬP TRÌNH LED 7 ĐOẠN VỚI 8051

tháng 4 15, 2018
BÀI 04: LẬP TRÌNH LED 7 ĐOẠN VỚI 8051


I. Cơ bản về LED 7 đoạn
Trong các thiết bị, để báo trạng thái hoạt động của thiết bị đó cho người sử dụng với thông số chỉ là các dãy số đơn thuần, thường người ta sử dụng "LED 7 đoạn". Chẳng hạn khi muốn hiển thị nhiệt độ phòng, hiển thị số lượng sản phẩm được kiểm tra sau một công đoạn nào đó...

1. Cấu tạo
LED 7 đoạn có cấu tạo bao gồm 7 led đơn có dạng thanh xếp theo hình dạng số 8 và có thêm một led đơn hình tròn nhỏ thể hiện dấu chấm tròn ở góc dưới. 8 led đơn trên LED 7 đoạn có Anode(cực +) hoặc Cathode(cực -) được nối chung với nhau vào một điểm. Nếu LED 7 đoạn có Anode(cực +) chung, điểm chung này được nối với VCC, led chỉ sáng khi tín hiệu điều khiển ở các chân điều khiển trạng thái sáng tắt của các led đơn ở mức 0. Nếu LED 7 đoạn có Cathode(cực -) chung, điểm chung này được nối với Ground (hay Mass), led chỉ sáng khi tín hiệu điều khiển ở các chân điều khiển trạng thái sáng tắt của các led đơn ở mức 1.
Vì LED 7 đoạn chứa bên trong các led đơn, do đó khi kết nối cần đảm bảo dòng qua mỗi led đơn trong khoảng 10mA-20mA để bảo vệ led. Nếu kết nối với nguồn 5V có thể hạn dòng bằng điện trở 330 Ohm trước các chân nhận tín hiệu điều khiển. Sơ đồ vị trí các led được trình bày như hình dưới:


2. Kết nối với vi điều khiển
Ngõ nhận tín hiệu của led 7 đoạn có 8 đường, vì vậy có thể dùng 1 Port nào đó của vi điều khiển để điều khiển để điều khiển led 7 đoạn . Như vậy led 7 đoạn nhạn một dữ liệu 8 bit từ vi điều khiển để điều khiển hoạt động của từng led đơn trong nó, dữ liệu được xuất ra điều khiển led 7 đoạn được gọi là "mã hiển thị led 7 đoạn". Có hai kiểu mã hiển thị led 7 đoạn: mã dành cho led 7 đoạn Anode chung và mã dành cho led 7 đoạn Cathode chung. Chẳng hạn, để hiển thị số 1 cần làm cho các led ở vị trí b và c sáng, nếu sử dụng led 7 đoạn có Anode chung thì phải  đặt vào hai chân b và  c điện áp 0V (mưc 0), các chân còn lại phải đặt lên mức 5V(mức 1), nếu sử dụng led 7 đoạn Cathode chung thì hoàn toàn ngược lại.
Nếu kết nối mỗi một Port của Vi điều khiển với 1 led 7 đoạn thì tối đa kết nối được 4 led 7 đoạn. Mặt khác nếu kết nối như trên sẽ hạn chế khả năng thực hiện các công việc khác của Vi điều khiển. Cho nên cần phải kết nối, điều khiển nhiều led 7 đoạn với số lượng chân điều khiển từ vi điều khiển càng ít càng tốt. Có hai giải pháp: một là sử dụng các IC chuyên dụng cho việc hiển thị led 7 đoạn, hai là kết nối nhiều led 7 đoạn vào cùng một đường xuất tín hiệu hiển thị.

3. Bảng mã hiện thị LED 7 đoạn
Để thuận tiện, phần cứng được kết nối với 1 Port bất kì của vi điều khiển theo thứ tự sau: Px.0 nối chân a, Px.1 nối chân b, lần lượt cho đến chân Px.7 nối chân h.
Dữ liệu xuất ra có dạng nhị phân sau: hgfedcba

Bảng mã hiển thị led 7 đoạn Anode chung

                        Số hiển thị                 Mã  nhị phân          Mã thập lục phân                 
                          dp  g  f   e   d  c  b  a                      
                         0                              1  1  0  0  0  0  0  0                                     C0
                         1                              1  1  1  1  1  0  0  1                                     F9
                         2                              1  0  1  0  0  1  0  0                                     A4
                         3                              1  0  1  1  0  0  0  0                                     B0
                         4                              1  0  0  1  1  0  0  1                                     99
                         5                              1  0  0  1  0  0  1  0                                     92
                         6                              1  1  0  0  0  0  1  0                                     82
                         7                              1  1  1  1  1  0  0  0                                     F8
                         8                              1  0  0  0  0  0  0  0                                     80
                         9                              1  0  0  1  0  0  0  0                                     90






Bảng mã hiển thị led 7 đoạn Cathode chung

                       Số hiển thị                 Mã nhị phân            Mã thập lục phân                 
                         dp  g  f   e   d  c  b  a                     
                         0                              0  0  1  1  1  1  1  1                                     3F
                         1                              0  0  0  0  0  1  1  0                                     06
                         2                              0  1  0  1  1  0  1  1                                     5B
                         3                              0  1  0  0  1  1  1  1                                     4F
                         4                              0  1  1  0  0  1  1  0                                     66
                         5                              0  1  1  0  1  1  0  1                                     6D
                         6                              0  1  1  1  1  1  0  1                                     7D
                         7                              0  0  0  0  0  1  1  1                                     07
                         8                              0  1  1  1  1  1  1  1                                     7F
                         9                              0  1  1  0  1  1  1  1                                     6F


II. Điều khiển LED 7 thanh
1. Điều khiển 1 LED 7 thanh
  Hãy vẽ mạch mô phỏng như hình(ở đây dùng LED 7 thanh Anode chung).



 Dưới đây là chương chình điều khiển led hiển thị từ 0 đến 9 và ngược lại.



#include <regx52.h>
#define LED_PORT P2
             /* 0   1   2   3   4   5   6   7   8   9  */
unsigned char Code7Seg[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
void Delay(int time);
void tangdan();
void giamdan();

void main()
{
 while(1)
 {
  tangdan();
  giamdan();
 }
}

void Delay(int time)
{
 int i,j;
  for(i=0; i<time; i++)
  for(j=0; j<125; j++); 
}

void tangdan(unsigned int i)
{
 for (i=0; i<10; i++)
 {
  LED_PORT = Code7Seg[i];
  Delay(1000);
 }
}

void giamdan(unsigned int i)
{
 for (i=9; i>=0; i--)
 {
  LED_PORT = Code7Seg[i];
  Delay(1000);
 }
}
2. Điều khiển 2 LED 7 thanh đếm 00 -> 99


Ở bài toán điều khiển LED 7 thanh chúng ta có thể áp dụng theo bài toán bước 1 nối mỗi con LED 7 thanh vào 8 chân data độc lập. Tuy nhiên việc này sẽ gây lãng phí số chân điều khiển LED và limit số LED có thể điều khiển (4 chiếc). Với số LED tăng lên đủ lớn số chân cần cũng tăng lên rất nhiều. Để giải quyết bài này có một kỹ thuật nêu ra là kỹ thuật “Quét LED”.  
Kỹ thuật Quét LED thực hiện theo nguyên tắc một thời điểm chỉ bật một LED 7 thanh với dữ liệu nó cần hiển thị, các LED còn lại được tắt. Việc quét LED thực hiện luôn phiên sáng các LED với yêu cầu trên. Có một hiện tượng hay xảy ra với những người mới thực hiện lập trình quét LED là hiện tượng “bóng ma” đó là hiện tượng xuất hiện các bóng mờ LED không mong muốn do quá trình điều khiển. Quá trình quét LED chuẩn được thực hiện theo các bước sau:
1.     Xuất ra mã hiển thị.
2. Cấp nguồn cho LED muốn hiển thị.
3. Trễ 1 khoảng thời gian để duy trì sáng.
4. Cắt nguồn LED vừa hiển thị.
Mạch mô phỏng như sau:


Chương trình điều khiển 2 LED 7 thanh



#include<REGX52.H> 
sbit LED1 = P3^0;
sbit LED2 = P3^1;
#define LED_PORT P2
                                                /* 0     1    2    3    4    5    6    7    8    9  */
unsigned char Code7Seg[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
void Delay(int time);

void main (void)
{
 unsigned char i;
 unsigned int  j;
 LED1 = 0;
 LED2 = 0;
 while(1)
 {
  /* Hien thi so i chay tu 00 den 99 */
  for(i = 0; i < 100; i++)
  {
   /* Voi moi so i hien thi 200 lan */
   for (j = 0; j < 200; j++)
    {
     /* Hien thi phan chuc cua so */
     LED_PORT = Code7Seg[i/10];
     LED1 = 1;
     Delay(100);
     LED1 = 0;
     /* Hien thi phan don vi cua so */
     LED_PORT = Code7Seg[i%10];
     LED2 = 1;
     Delay(100);
     LED2 = 0;
     /* Ket thuc hien thi phan don vi */
    }
  }
 }
}

void Delay(int time)
{
 while(time--);
}

Trên đây chúng ta đã thực hiện theo quy trình 4 bước quét LED:
P2 = LED7SEG[i/10]; // Xuất dữ liệu LED
LED1 = 1;           // Bật LED hiển thị
Fn_Delay(100);      // Trễ một khoảng thời gian
LED1 = 0;           // Tắt LED đang hiển thi
Ở đây ngoài vòng for thực hiện đếm từ 00-99 chúng ta cần thêm một vòng for cho biến j chạy từ 0-200 để đảm bảo mỗi số được hiển thị trong một khoảng thời gian đủ lâu để chúng ta có thể nhìn thấy. 

3. Điều khiển 4 LED 7 thanh đếm từ 0000->9999

 Mạch mô phỏng như sau:



Chương trình điều khiển 4 LED 7 thanh.


#include<REGX52.H>
sbit LED1 = P3^0;
sbit LED2 = P3^1;
sbit LED3 = P3^2;
sbit LED4 = P3^3;
#define LED_PORT P2
                                                   /* 0     1    2    3    4    5    6    7    8    9  */
unsigned char Code7Seg[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
void Delay (unsigned int Time);

void main (void)
{
 unsigned char i;
 unsigned int  j;
 LED1 = 0;
 LED2 = 0;
 LED3 = 0;
 LED4 = 0;
 while(1)
 {
  /* Hien thi so i chay tu 0000 den 9999 */
  for(i = 0; i < 10000; i++)
  {
   /* Voi moi so i hien thi 400 lan */
   for (j = 0; j < 400; j++)
   {
    /* Hien thi phan nghin cua so */
    LED_PORT = Code7Seg[i/1000];
    LED1 = 1;
    Delay(100);
    LED1 = 0;
 
    /* Hien thi phan tram cua so */
    LED_PORT = Code7Seg[(i%1000)/100];
    LED2 = 1;
    Delay(100);
    LED2 = 0;

    /* Hien thi phan chuc cua so */
    LED_PORT = Code7Seg[(i%100)/10];
    LED3 = 1;
    Delay(100);
    LED3 = 0;
    
    /* Hien thi phan don vi cua so */
    LED_PORT = Code7Seg[i%10];
    LED4 = 1;
    Delay(100);
    LED4 = 0;
   }
  }
 }
}

void Delay (unsigned int time)
{
 while(time--);
} 
Chúc các bạn thành công!

Bài 03: LẬP TRÌNH HIỆU ỨNG LED VỚI 8051

tháng 4 14, 2018
Bài 03: LẬP TRÌNH HIỆU ỨNG LED VỚI 8051

I. Sơ đồ mạch 
 Các bạn vẽ mạch nguyên lí như sau:


II. Viết chương trình
1. Khai báo thư viện
    Đầu tiên phải thêm thư viện <regx52.h> vào project. Thư viện này chứa các cài đặt cấu hình vi điều khiển 89C52

2. Hàm main()

    Đây là hàm chính của chương trình, trong hàm chính, tất cả các hàm con sẽ chạy trong vòng lặp while(1). Vòng lặp while(1) cho phép các hàm trong nó sẽ chạy mãi mãi miễn là được cấp nguồn.

void main()
{
 while(1)
 {
 }
}


3. Hàm Delay()
    Hàm này được dùng để tạo một độ trễ tùy ý. Nó sẽ tạm dừng việc thực thi mã chính trong một thời gian khi nó được gọi.
    Vòng lặp for  đầu tiên sẽ chạy với số lượng thời gian tùy thuộc vào tham số được truyền cho nó và  vòng lặp thứ hai chạy 125 lần cho mỗi lần lặp của lần đầu tiên. Có một cách khác để tạo độ trễ thời gian bằng cách sử dụng bộ định thời bên trong vi điều khiển( mình sẽ giới thiệu sau).


void Delay(int time)
{
  int i,j;
  for(i=0; i<time; i++)
  for(j=0; j<125; j++); 
}

4. Lập trình điều khiển theo Port của vi điều khiển

 8051 là vi điều khiển 8 bit, chúng ta có thể xuất dữ liệu output theo cả Port với điều kiện các Pin cùng chung 1 Port. Các bạn chỉ cần gán dữ liệu cho Port đó, ví dụ:
P2=0x55;
0x55 là mã thập lục phân, đổi ra nhị phân dữ liệu trên Port 2 như sau: 01010101 với chiều tương ứng từ P2.7 đến P2.0.
 Một số toán tử dùng để xử lí các Bit:
  • Toán tử | và &
Toán tử | là toán tử OR bit, toán tử & là toán tử AND bit. Các toán tử này được thực hiện theo bảng sau:
0    |   0   =   0
0    |   1   =   1

1    |   1   =   1
0   &   0   =   0
0   &   1   =   0
1   &   1   =   1
Đây là 2 toán tử hay được sử dụng để tác động đến một vài bit trong một Port. Toán tử | thường được dùng để đưa một Pin lên mức 1, toán tử & thường được dùng để đưa một Pin về mức 0. Ví dụ:
P2 = P2 | 0x01;  /*Đưa pin P2.0 lên mức 1*/
P2 = P2 & 0xFE; /*Đưa pin P2.0 về mức 0*/
  • Toán tử >> và <<. Đây là 2 toán tử dùng để dịch bit. Các bạn xem ví dụ sau để hiểu rõ 2 toán tử này:
0x01 << 1 = 0x02; /*00000001 --> 00000010*/
0x10 >> 1 = 0x08; /*00010000 --> 00001000*/


Sau khi nắm được các toán tử này, các bạn có thể dùng để lập trình những hiệu ứng nháy led khác nhau như: sáng dần, tắt dần, nhỏ giọt,....


5, Chương trình mẫu

#include <regx52.h>
#define LED_PORT P2

void Delay();
void Fn_Nhap_Nhay();
void Fn_Tat_dan();
void Fn_Sang_dan();
void Fn_Lan_luot();
void Fn_Nho_giot();

void main()
{
 while(1)
 {
  Fn_Nhap_Nhay();
 } 
}

void Delay(int time)
{
 int i,j;
  for(i=0; i<time; i++)
  for(j=0; j<125; j++); 
}
void Fn_Nhap_Nhay()
{
 LED_PORT = 0x55;
  while(1)
  {
   LED_PORT = ~LED_PORT;
   Delay(200);
  }
}

void Fn_Tat_dan()
{
 unsigned char i;
 LED_PORT = 0xff;
 for (i=0; i<8; i++)
 {
  LED_PORT=LED_PORT<<1;
  Delay(200);
 }
}

void Fn_Sang_dan()
{
 unsigned char i;
 LED_PORT = 0x00;
  for (i=0; i<8; i++)
  {
   LED_PORT = (LED_PORT<<1)|1;
   Delay(200);
  }
  
}

void Fn_Lan_luot()
{
 unsigned char i;
 LED_PORT = 0x00;
 for (i=0; i<8; i++) 
 {
   LED_PORT = 0x01<<i;
   Delay(200);
 }
}

void Fn_Nho_giot()
{
 unsigned char i, j, K = 0x00;
 LED_PORT = 0x00;
 for (i=7; i>=0; i--)
 {
  for (j=0; j<=i; j++)
  {
   LED_PORT = (0x01 <<j)|K;
   Delay(200);
  }
  K = LED_PORT;
 }
}
 

Bài 02: HƯỚNG DẪN TẠO PROJECT VỚI PHẦN MỀM PROTEUS

tháng 4 13, 2018
Bài 02: HƯỚNG DẪN TẠO PROJECT VỚI PHẦN MỀM PROTEUS

I. Phần mềm cần cài đặt
1. Đã cài phần mềm mô phỏng Proteus
2. Chuẩn bị file.hex 

II. Tiến hành tạo project

Bước 1: Khởi động phần mềm, chọn FileNew Project (hoặc bấm Ctrl+N)



Bước 2: Đổi tên Project và chọn đường dẫn. Click Next


Bước 3: Chọn Create a schematic from the selected template DEFAULT → Click Next



Bước 4: Chọn Do not create a PCB layout → Chọn Next



Bước 5: Chọn No Firmware Project → Click Next



Bước 6: Chọn Finish



Sau khi tạo xong project, chúng ta sẽ vẽ mạch và chạy mô phỏng.

Bước 7:  Để lấy linh kiện, chọn hình chữ P hoặc phím tắt P.




Bước 8: Hộp thoại Pick Devices hiện ra. Trong phần Keywords, các bạn nhập tên linh kiện. Trong ô Results, chọn linh kiện mình cần. Sau đó nhấn OK



Bước 9:  Sau khi lấy xong linh kiện, các bạn chọn linh kiện muốn vẽ và đặt vào phân vùng kẻ xanh bên phải.


Một số thao tác trong Proteus:
- Di chuyển linh kiện: Chuột phải vào linh kiện → chọn Drag Object
-Thay đổi thông số linh kiện: Chuột phải vào linh kiện →Édit Properties hoặc Ctrl+E
-Xóa linh kiện: Chuột phải  → Delete Object
-Xoay phải 90 độ: Chuột phải →Rotate Clockwise
-Xoay trái 90 độ: Chuột phải →Rotate Anti-Clockwise
-Xoay 180 độ: Chuột phải →Rotate 180 degrees
-Lật linh kiện theo trục x: Chuột phải →X-Mirror
-Lật linh kiện theo trục y: Chuột phải →Y-Miror
-Zoom mạch: Sử dụng lăn chuột

Bước 10: Để nối dây, các bạn rê chuột đến đầu chân linh kiện cần nối, dấu chéo 'x' xuất hiện, hãy click chuột và di chuyển đến chân linh kiện cần nối và click lần nữa. Ta có mạch sau:



Chú ý: biểu tượng GND và VCC lấy ở "Terminals Mode"


Vậy là mình đã giới thiệu xong cách tạo project  để mô phỏng bằng phần mềm Proteus. Chúc các bạn thành công!


Bài 01: HƯỚNG DẪN TẠO PROJECT 8051 VỚI KEIL C.

tháng 4 12, 2018
BÀI 01: HƯỚNG DẪN TẠO PROJECT 8051 VỚI KEIL C.

I. Phần mềm cần cài đặt
1. Đã cài Keil C và Crack.

II. Tiến hành tạo Project

Bước 1: Khởi động phần mềm, chọn Project New uVision Project



Bước 2: Hộp thoại hiển thị, các bạn chọn vị trí lưu và đặt tên Project (ở đây mình lưu với tên GPIO), chọn Save.


Bước 3: Cửa sổ "Select Device for Target" xuất hiện, trong thẻ Data base các bạn chọn Atmel AT89C52OK.


Bước 4: Trong hộp thoại tiếp theo, click No. Để tạo một file mới chọn "New" hoặc bấm Ctrl+N




Bước 5: Sau đó bấm Save hoặc Ctrl+S




Bước 6: Lưu file mới vừa tạo dưới dạng file.c (ở đây mình lưu là main.c). Bấm Save. Kết quả như hình:



Bước 7: Add file main.c vừa tạo vào Project bằng cách: Click chuột phải vào Source Group 1, chọn Add Files to Group 'Source Group 1'..




Bước 8: Cửa sổ hiển thị, click vào file main.c →Add và tắt cửa sổ.



File "main.c" đã được add vào project.





Bước 9: Thiết lập cho project để xuất ra file.hex sau khi build để nạp cho vi điều khiển. Click vào biểu tượng Target Options...


Trong tab Output, tick vào Create HEX File. Sau đó bấm OK.




Bước 10: Viết 1 đoạn code đơn giản, sau đó bấm vào biểu tượng Build hoặc F7.





Quan sát kết quả ở tab Output




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