Thứ Sáu, 8 tháng 7, 2016

Bài 7: Giao tiếp với LED 7 thanh sử dụng 8051

Trước hết mình xin trình bày sơ qua về cấu tạo và nguyên lý hoạt động của LED 7 thanh như sau:


Led 7 đoạn được sử dụng khi các dãy số không đòi hỏi quá phức tạp, chỉ cần hiện thị số là đủ, chẳng hạn led 7 đoạn được dùng để hiển thị nhiệt độ phòng, trong các đồng hồ treo tường bằng điện tử, hiển thị số lượng sản phẩm được kiểm tra sau một công đoạn nào đó…

Cấu trúc và mã hiện thị dữ liệu của LED 7 thanh:

-Dạng form chuẩn:
-Dạng anot chung:
-Dạng cathode chung:
Điều khiển LED 7 thanh thật ra là ta điều khiển 8 led đơn cấu tạo nên nó( LED thứ 8 là dấu chấm), tạo thành các giá trị dữ liệu mà chúng ta mong muốn. Do vậy ta cần biết được mã hexa của từng kí tự để khi lập trình chúng ta được dễ dàng hơn.

Đối với dạng led anode chung, chân COM phải có mức logic là 1, vì vậy chân COM sẽ được nối lên nguồn, các LED sẽ sáng khi các chân a-f, dp ở mức logic là 0. Ta có bảng sau:

Chữ số
Mã Logic gfedcba
Mã hexa
0
1000000
0x40
1
1111001
0xF9
2
0100100
0x24
3
0110000
0x30
4
0011001
0x19
5
0010010
0x12
6
1000010
0x02
7
1111000
0xF8
8
0000000
0x00
9
0010000
0x10


Đối với dạng Cathode chung, chân COM sẽ có mức logic 0 nên được nối đất, các chân a-f, dp ở mức logic 1 thì LED sẽ sáng. Ta có bảng như sau:

   
Chữ số
Mã logic gfedcba
Mã hexa
0
0111111
0x3F
1
0000110
0x6
2
1011011
0x5B
3
1001111
0x4F
4
1100110
0x66
5
1101101
0x6D
6
1111100
0x7c
7
0000111
0x7
8
1111111
0x7F
9
1101111
0x6F



Để giao tiếp được với LED 7 thanh chúng ta cần làm những thao tác sau:

+ Tạo void delay()
+ Khai báo thư viện cho các chữ số 0-9.
+ Tạo ra một vòng lặp cho phép đưa ra một PORT nào đó giá trị của các chữ số.

Mạch nguyên lý sử dụng led 7 thanh dương chung như sau:

Code như sau:

#include <reg51.h>
#include <stdio.h> 

delay(int time) // Ham delay
{
int i,j;
  for(i=0;i<time;i++)
   for(j=0;j<1275;j++);
}

void main()
{
char num[]={0x40,0xF9,0x24,0x30,0x19,0x12,0x02,0xF8,0x00,0x10}; // Gia tri hex tuong ung cua cac chu so tu 0-9
int c;
while(1)
{
for(c=0;c<10;c++) // cho c chay tu 0 den 9.
{
P2=num[c]; 
delay(200); // delay 0.2s
}
}
}

Mạch nguyên lý sử dụng led 7 thanh âm chung như sau:
Code như sau:

#include <reg51.h>
#include <stdio.h>

delay(int time) // Ham delay()
{
int i,j;
  for(i=0;i<time;i++)
   for(j=0;j<1275;j++);
}

void main()
{
char num[]={0x3F,0x6,0x5B,0x4F,0x66,0x6D,0x3D,0x7,0x7F,0x6F}; // Gia tri Hex tuong ung tu 0-9
int c;
while(1)
{
for(c=0;c<10;c++)
{
P2=num[c]; 
delay(200);
}
}
}

Như vậy chúng ta đã hình thành nên cơ sở để dụng LED 7 thanh cho nhiều mục đích khác như điều khiển LED 7 thanh bằng KEY, đồng hồ số, đo nhiệt độ.....


Bài tới mình xin hướng dẫn các bạn điều khiển LED 7 thanh bằng KEY, rất mong được các bạn theo dõi và ủng hộ!

Thứ Ba, 5 tháng 7, 2016

Bài 6. Giao tiếp với Key đơn

Như tiêu đề của bài, lần này chúng ta sẽ tương tác với Key đơn sử dụng họ vi điều khiển 8051.

Key đơn thật ra là tập hợp các nút ấn, nhưng có cách nối đặc biệt để đảm bảo giá trị khởi điểm của các chân ra ở trạng thái bình thường sẽ luôn ở mức cao, khi nút ấn đượg ấn xuống thì sẽ xuống trạng thái thấp.

Mục đích của bài này là khi ấn một nút ấn thì có một LED tương ứng sáng trong 1s rồi tắt trong khi các LED khác vẫn không sáng. Để làm được yêu cầu này trước hết ta cần khai báo tên LED, tên Key tương ứng với các chân trên vi điều khiển( Lưu ý nếu các bạn dùng P0 làm chân I/O thì cần lắp thêm điện trở kéo nhé) như sau:

sbit LED0=P3^0; // Dinh nghia cho chan p3.0 co ten la LED0
sbit LED1=P3^1;
sbit LED2=P3^2;
sbit LED3=P3^3;

sbit KEY0=P2^0; // Dinh nghia cho chan p2.0 co ten la KEY0
sbit KEY1=P2^1;
sbit KEY2=P2^2;
sbit KEY3=P2^3;

Hàm delay() được phát biểu như sau:

void delay(unsigned int time )
{
    unsigned int i;
   unsigned int j;

  for( i=0; i<time; i++ )
  for( j=0; j<1275; j++ );
}

Mình xin khái quát qua thuật toán như sau:

+ Khai báo trạng thái ban đầu là key và led đều mức cao, tức chưa ấn key và LED đều tắt.
+ Khi ấn Key0 thì LED0 sáng trong 1s rồi tắt, 3 đèn còn lại đều tắt.
+ Khi ấn Key1 thì LED1 sáng trong 1s rồi tắt, 3 đèn còn lại đều tắt.
+ Khi ấn Key2 thì LED2 sáng trong 1s rồi tắt, 3 đèn còn lại đều tắt.
+ Khi ấn Key3 thì LED3 sáng trong 1s rồi tắt, 3 đèn còn lại đều tắt.

Để làm được yêu cầu như trên, chúng ta cần sử dụng hàm if(điều kiện)...Mình xin trích qua code main như sau:

void main(void)
 {
   KEY0=KEY1=KEY2=KEY3=1;  // GIA TRI BAN DAU CUA KEY DON
   LED0=LED1=LED2=LED3=1; // TAT CA LED DEU TAT
   while (1)
   {
      if(KEY0==0) // KEY0 duoc nhan
      {
LED0=0; // LED0 sang
delay(1000); // 1s delay
LED0=1=LED1=LED2=LED3; // tat ca led cung tat
}
      if(KEY1==0)
      {
LED1=0;
delay(1000);
LED1=LED2=LED3=LED0=1;
}
      if(KEY2==0)
      {
LED2=0;
delay(1000);
LED0=LED1=LED2=LED3=1;
}
      if(KEY3==0)
      {
LED3=0;
delay(1000);
LED0=LED1=LED2=LED3=1;
}
}
   
 }
Mạch nguyên lý như hình sau:


Từ những dòng code trên, chúng ta có thể mở rộng ra trong nhiều trường hợp khác, ví dụ như ấn key0 thì led1 sáng hoặc cùng một lúc 3 leds sáng ... trường hợp khác là ấn cùng lúc 2 key thì sẽ như thế nào. Mình xin giới thiệu các bạn dòng code cho các yêu cầu sau:
+ ấn 1 key thì một led sáng trong 1s.
+ ấn 2 key thì 2 led sáng trong 1s.
+ ấn 3 key thì 3 led sáng trong 1s.
+ ấn 4 key thì 4 led sáng trong 1s.

#include <reg51.h>
#include <stdio.h>

sbit LED0=P3^0;
sbit LED1=P3^1;
sbit LED2=P3^2;
sbit LED3=P3^3;

sbit KEY0=P2^0;
sbit KEY1=P2^1;
sbit KEY2=P2^2;
sbit KEY3=P2^3;

void delay(unsigned int time )
{
    unsigned int i;
   unsigned int j;

  for( i=0; i<time; i++ )
  for( j=0; j<1275; j++ );
}

void main(void)
 {
   KEY0=KEY1=KEY2=KEY3=1;  // GIA TRI BAN DAU CUA KEY DON
   LED0=LED1=LED2=LED3=1; // TAT CA LED DEU TAT
   while (1)
   {
      if(KEY0==0)
      {
LED0=0;
delay(1000);
LED0=LED1=LED2=LED3=1;
}
      if(KEY1==0)
      {
LED1=0;
delay(1000);
LED1=LED2=LED3=LED0=1;
}
      if(KEY2==0)
      {
LED2=0;
delay(1000);
LED0=LED1=LED2=LED3=1;
}
      if(KEY3==0)
      {
LED3=0;
delay(1000);
LED0=LED1=LED2=LED3=1;
}
      if(KEY0=KEY1==0)
      {
LED0=LED1=0;
delay(1000);
LED0=LED1=LED2=LED3=1;

}
      if(KEY2=KEY1==0)
      {
LED2=LED1=0;
delay(1000);
LED0=LED1=LED2=LED3=1;
}
      if(KEY2=KEY3==0)
      {
LED2=LED3=0;
delay(1000);
LED0=LED1=LED2=LED3=1;
}
      if(KEY0=KEY1=KEY2=0)
      {
LED0=LED1=LED2=0;
delay(1000);
LED0=LED1=LED2=LED3=1;
}
      if(KEY3=KEY1=KEY2=0)
      {
LED1=LED2=LED3=0;
delay(1000);
LED0=LED1=LED2=LED3=1;
}
}
   
 }
Bài tiếp theo mình xin giới thiệu với các bạn về KEYPAD MATRIX, đây là một dạng nâng cao của KEY đơn, keypad matrix có rất nhiều ứng dụng trong thực tế, ví dụ như mạch khóa điện tử, máy tính mini, .....
Rất mong được các bạn ủng hộ!

Thứ Tư, 29 tháng 6, 2016

Bài 5.1: Giao tiếp với LEDs đơn nâng cao

Lần này mình sẽ hướng dẫn các bạn tương tác với LEDs đơn nhưng với quy mô là cả một PORT, đây là một bài nâng cao hơn so với bài 5 vừa rồi.

Trước hết, ta quay lại tìm hiểu cấu trúc của một PORT của 8051 gồm những gì ?

Các PORT xuất/nhập của 8051 bao gồm port 0 tại địa chỉ 80H, port 1 ở địa chỉ 90H, port 2 ở địa chỉ A0H và port 3 ở địa chỉ B0H. Các port 0, 2, 3 không được dùng để xuất/nhập nếu ta sử dụng thêm bộ nhớ ngoài hoặc có một số đặc tính đặc biệt của 8051 được sử dụng( như ngắt, port nối tiếp...). P1.2 đến P1.7, ngược lại luôn luôn là các đường xuất/nhập đa mục đích hợp lệ.

Tất cả các port đều được định địa chỉ từng bit nhằm cung cấp khả năng giao tiếp mạnh. Tức mỗi port là một byte, gồm 8 bits, ở đây tương đương với 8 chân xuất/nhập của từng port. Để làm việc với cả port, ta chỉ cần nhớ tên của port và giá trị mong muốn của port( dạng hexa hoặc nhị phân đều được).
Ví dụ ở đây là cho chân P1.0 lên mức cao và các chân còn lại của port 1 ở mức thấp, ta có thể khai báo trong C như sau:

P1=00000001 // ở dạng nhị phân
Hoặc P1=0x01 // ở dạng hexa

Như vậy chúng ta đã có thể tương tác trực tiếp được với từng bit của một port cũng như cả port của 8051.

Ví dụ về tương tác với port 2 của 8051:

Sơ đồ nguyên lý như sau:

Ví dụ đầu tiên mình sẽ cho cả cổng P2 cùng tắt cùng sáng, code như sau:

#include <REGX52.H>

void delay( unsigned int );

void main()
{
while(1)
{
P2 = 00000000; // gia tri hexa là 0x00
delay(100); trễ 0.1s
P2 = ~P2;
delay(100);
}
}

//ham delay( mS )
void delay( unsigned int time )
{
    unsigned int i;
 unsigned int j;

for( i=0; i<time; i++ )
for( j=0; j<1275; j++ );
}

Ở ví dụ này, P2 được thiết lập ở giá trị 0x00, tức tất cả các bits được để ở mức 0 hết, với các mắc anot chung thì LED sẽ sáng khi các bit ở mức 0. Hàm P2=~P2 là hảm lật trạng thái của cả port P2, vì vậy ta thu được cả port 2 nhấp nháy.

Ở ví dụ tiếp theo, mình sẽ làm cho từng led của port sáng lên và khi sáng tất cả các đèn thì cả port sẽ cùng sáng và tắt:

#include <REGX52.H>

void delay( unsigned int );

void main()
{
while(1)
{
P2 = 11111110;
delay(100);
P2= 11111101;
delay(100);
P2 = 11111011;
delay(100);
P2 = 11110111;
delay(100);
P2 = 11101111;
delay(100);
P2 = 11011111;
delay(100);
P2 = 10111111;
delay(100);
P2 = 01111111;
delay(100);
P2 = 11111111;
delay(100);
                P2 = ~P2;
                delay(100);
}
}

//ham delay( mS )
void delay( unsigned int time )
{
    unsigned int i;
 unsigned int j;

for( i=0; i<time; i++ )
for( j=0; j<1275; j++ );
}

Các port khác chúng ta có thể làm tương tự, các bạn có thể tùy biến các bit để tạo thành hiệu ứng mà các bạn mong muốn.
Chúc các bạn thành công!

Thứ Ba, 28 tháng 6, 2016

Bài 5: Giao tiếp với LED đơn

Tiếp nối bài 4 lần trước, lần này mình xin hướng dẫn các bạn giao tiếp với LED đơn như sau:
Trước hết, ta cần hiểu về một cấu trúc của port Xuất/Nhập (Output/Input)

1. Cấu trúc của một port xuất/nhập:

Dưới đây là cấu trúc của một port xuất nhập. Việc ghi đến 1 chân của port sẽ nạp dữ liệu vào bộ chốt của port( Port Latch),ngõ ra Q của bộ chốt điều khiển một transistor trường và transistor này nối với các chân của port. Khả năng fanout( số lượng đầu vào logic của một cổng nhiều hay ít) của các port 1, 2 và 3 là 4 tải vi mạch TTL loại Schottky công suất thấp( LS  ) còn của port 0 là 8 tải loại LS.

Lưu ý là điện trở kéo lên( pull up ) sẽ không có ở port 0( trừ khi port này làm nhiệm vụ của bus địa chỉ/ dữ liệu đa hợp ) do vậy chúng ta cần lắp điện trở kéo bên ngoài cho port 0.
Giá trị của điện trở này phụ thuộc vào đặc tính ngõ vào của thành phần nối với chân của port( thông thường sẽ là 4k7 đến 10k).



2. Chu kì máy của 8051

Đối với CPU để thực hiện một lệnh bất kì thì mất một chu kì đồng hồ này được coi như các chu kì máy. Đối với họ 8051 thì độ dài chu kì máy phụ thuộc vào tần số bộ dao động thạch anh được nối vào hệ thống 8051. Bộ dao động thạch anh cùng với mạch điện trên chip cung cấp xung đồng hồ cho CPU của 8051. Tần số của thạch anh nối với 8051 dao động trong khoảng 4MHz đến 30MHz phụ thuộc vào tốc độ chíp và nhà sản xuất. Thường xuyên nhất là bộ dao động thạch anh với tần số 10.0592MHz được sử dụng làm cho hệ thống 8051 tương thích với cổng nối tiếp của PC IBM. Trong 8051, một chu kì máy kéo dài 12 chu kì dao động. Do vậy, để tính toán chu kì máy ta lấy 1/12 tần số của thạch anh, sau đó ta lấy giá trị ngịch đảo để tìm đc thời gian của một chu kì máy.
Ví dụ chu kì máy với trường hợp thạch anh là 11.0592MHz được tính như sau:
11.0592/12=921.6KHz, Chu kì máy là 1/921.6kHz=1.085uS.

3, Giao tiếp với LED đơn.

Mạch nguyên lý được vẽ trên Proteus như sau:


Code như sau:
#include<reg52.h>           // file header cua 89c52

sbit LED = P2^0;            // dinh ngia chan p2.0 co ten la LED

void Delay(void);           // ham Delay

void main (void)
{
    while(1)                // vong lap vo han
    {
        LED = 0;            // LED ON
        Delay();            // ham delay 1s
        LED = 1;            // LED OFF
        Delay();
    }
}

void Delay(void)      
{
    int j;
    int i;
    for(i=0;i<10;i++)
    {
        for(j=0;j<10000;j++)  // 1s delay
        {
        }
    }
}
Như vậy là chúng ta đã tương tác xong với LED đơn sử dụng 8051, bài tiếp theo sẽ là bài nâng cao hơn từ bài này, đó là mạch trái tim sử dụng 8051. Mong các bạn theo dõi và ủng hộ.

Thứ Tư, 22 tháng 6, 2016

Bài 4. Hướng dẫn mô phỏng trên Proteus và cách nạp chương trình cho họ 8051

Bài này mình sẽ hướng dẫn các bạn dùng Keil C để dịch sang file .hex dùng cho mô phỏng mạch trên Proteus. Công cụ chúng ta cần là Keil C và Proteus 8.4.

File .hex là gì ?

Hex ở đây được viết tắt bởi từ hexadecimal có nghĩa là hệ cơ số 16 hay hệ thập lục phân. Khi bạn viết code và nạp chương trình cho vi điều khiển thì không đơn thuần là nạp những "câu lệnh" bạn viết ra đưa vào vi điều khiển, mà phải thông qua trình biên dịch (Code Vision, Keil C...đều là trình biên dịch) "dịch" lại những gì mình viết và tạo ra một chuỗi kí tự gồm những chữ (từ A đến F) và số (từ 0 đến 9) thuộc hệ thập lục phân. Những chữ số này nạp vào vi điều khiển thì vi điều khiển mới "hiểu" được. Những chữ số này được đóng gói và lưu lại thành một file có đuôi mở rộng là ".hex".

Tại sao lại dịch sang file .hex là không phải là file với định dạng khác? 

Vi điều khiển chỉ có khả năng làm việc với các tập lệnh dưới định dạng là ở cơ số 16, vì vậy ta cần một file .hex để nạp vào vi điều khiển, qua đó thì vi điều khiển mới hoạt động được.

1. Hướng dẫn dùng Keil C để dịch ra file .hex
Để bắt đầu viết code cho một dự án nào đó, các bạn mở Keil C lên  và chọn Project/ New uVision Project. Màn hình tiếp theo các bạn điền tên project rồi chọn OK.
Ở màn hình tiếp theo, các bạn chọn vi điều khiển mà các bạn đang dùng, ở đây mình chọn là AT89S52.
Ở màn hình tiếp theo, đây là lựa chọn không bắt buộc, các bạn có thể đồng ý thêm file STARTUP.A51( Đây là một file trích xuất từ hệ thống, được viết bằng hợp ngữ). File này không ảnh hưởng gì đến chương trình của bạn nên các bạn có thể bỏ chọn.

Ở màn hình tiếp theo, ta bắt đầu thêm file C cho project bằng cách chọn chuột phải vào ô Source Group 1 và chọn Add new item to.... Nếu các bạn đã soạn thảo file .c hay .h từ trước đó mà muốn nhập vào project thì các bạn có thể chọn Add existing items to... và chọn các file đã soạn trước đó.

Các bạn gõ tên cho file c và ấn Add.
Màn hình tiếp theo là phần soạn thảo code, ngôn ngữ dùng ở đây là C. Mình có viết qua chương trình nhấp nháy LEDs như sau:

#include<reg52.h>           // thu vien cua 89s52
sbit LED = P2^0;            // dinh nghia chan P2.0 co ten la LED
void Delay(void);           // ham delay
void main (void)
{
    while(1)                // vong lap vo han
    {
        LED = 0;            // LED ON
        Delay();
        LED = 1;            // LED OFF
        Delay();
    }
}

void Delay(void)
{
    int j;
    int i;
    for(i=0;i<10;i++)
    {
        for(j=0;j<10000;j++) // delay 1ms
        {
        }
    }

Các bạn nên ấn nút lưu lại thường xuyên đề phỏng những trường hợp không may.
Khi các bạn soạn thảo xong thì ta tiến hành dịch sang file .hex như sau:
Chọn Flash/ Configure Flash tools
Ở ô Target các bạn chọn giá trị Xtal cho phù hợp, ở đây mình chọn là 12MHz.
Tiếp theo bên tab Output các bạn tích chọn ô Create HEX file, format các bạn để ở mặc định. Một tùy biến ở đây các bạn có thể chọn thư mục sẽ chứa file .hex để sau này dễ tìm kiếm.

Tiếp theo, để tiến hành dịch chương trình sang file hex, các bạn ấn Project/ Build target. Nếu không có lỗi gì thì sẽ có thông báo là 0 error 0 warning và đã tạo xong file hex ở trong thư mục mà ở trên các bạn đã chọn.
 Như vậy ta đã tiến hành xong việc dùng Keil C để dịch sang file .hex dùng cho mô phỏng trên proteus cũng như dùng để nạp chương trình vào IC sau này.

2. Mô phỏng trên Proteus

Các bạn mở Proteus lên, tiến hành vẽ mạch như bình thường.

Để nạp file hex cho vi điều khiển, ta chuột phải vào IC rồi chọn Edit Properties. Ở ô program file, ta ấn vào icon Open rồi dẫn đến file hex ta vừa tạo ở trên rồi chọn OK. Để tiến hành mô phỏng, ta ấn vào Debug/ Run Simulation hoặc ấn vào icon run ở góc dưới bên trái màn hình.

3. Nạp chương trình cho 8051 bằng mạch nạp ISP

Công cụ cần thiết là mạch nạp ISP( http://banlinhkien.vn/goods-493-mach-nap-89-avr-usbasp-usbisp.html ) và chương trình nạp progisp1.72 ( https://www.fshare.vn/file/ZP4AFQ9O5H/ )

Dao diện của progisp như sau:

Các bạn tiến hành chọn đúng chip mình đang dùng, ở đây là AT89S52. 
Chữ PRG ISP sẽ sáng lên khi phần mềm đã nhận đc mạch nạp:
Các bạn chọn Load Flash rồi dẫn đến file hex vừa tạo ở trên. Rồi ấn Auto, nếu thành công sẽ có thông báo sau: 
Erase, Write Flash, Verify Flash, Successful Done.
Lưu ý là các bạn phải nối đúng các chân của mạch nạp với vi điều khiển nhé:


Chúc các bạn thành công! Bài tiếp theo mình sẽ hướng dẫn các bạn về lập trình 8051 từ cơ bản đến nâng cao. Mong các bạn theo dõi và ủng hộ!









Thứ Hai, 20 tháng 6, 2016

Bài 3: Hướng dẫn cài đặt Keil C

1. Cài đặt:

Các bạn vào trang này rồi điền các thông tin cần thiết để tiến hành tải về Keil C for 8051 familes:
https://www.keil.com/demo/eval/c51.htm.

Link sau là file Keygen.rar

https://www.mediafire.com/?pj1iof9f98ddahd

Sau khi tải về đươc file .exe thì ta tiến hành cài đặt:

Các bạn ấn Next để tiếp tục:


Các bạn ấn Next để máy tính bắt đầu cài đặt


Kết thúc quá trình cài đặt như sau. Các  bạn nhấn finish để kết thúc quá trình cài đặt:


2. Kích hoạt bản quyền:

Tại sao lại phải kích hoạt bản quyền??

--> Vì bản dành cho dùng thử( Evalution Version) chỉ hỗ trợ dịch sang file .hex với kích thước tối đa là 2000h. Vì vậy, nếu chương trình của chúng ta mà lớn hơn thì phiên bản này sẽ không dịch sang file .hex được.

Các bạn mở Keil C lên, chọn File/License Managerment.
Các bạn Copy dòng code CID( Computer ID), Bạn mở file keygen tải được ở trên :
Bạn paste dòng CID vào ô CID, target là C51(họ 8051). Rồi ấn generate, ta thu được dòng License ID, các bạn copy dòng code này rồi paste vào ô New License ID code trên màn hình License Managerment trên Keil C. Rồi ấn Add LIC. Nếu thành công sẽ có màn hình như sau:
Chúc các bạn thành công!
Bài sắp tới mình sẽ hướng dẫn các bạn cách sử dụng Keil C để tiến hành dịch file .hex để dùng trong mô phỏng Proteus.