Trong bài này chúng ta sẽ ứng dụng GPIO để lập trình 8051 led trái tim với các hiệu ứng khác nhau. Các bạn sẽ hiểu thêm về thuật toán sử dụng GPIO dạng output sau khi học xong bài này
Bài 5 trong Serie Học lập trình 8051 từ A tới Z
Led trái tim là gì?
Led trái tim là một sản phẩm mà thời mình học luôn là sản phẩm đầu tiên nhập môn lập trình 8051. Có một lời nguyền là cặp đôi nào yêu nhau mà tặng led trái tim thì y như rằng là chia tay :D.
Nói vui vậy thôi, led trái tim rất phù hợp để training việc sử dụng GPIO một cách linh hoạt. Vậy nên mình dùng nó để hướng dẫn các bạn trong bài này.
Một vài hình ảnh:
Mô phỏng trên proteus
B1: Lấy linh kiện:
B2: Tiến hành vẽ mạch
Do vi điều khiển này có 4 cổng vói 32 chân, ta sẽ tối đa cắm được 32 LED
Khá nhiều chân nên ta sẽ đặt tên từng chân tương ứng với LED nhé
Ta vào Terminals mode → Default đặt vào các chân từ P0 trở đi
Sau đó ta sẽ nối chân
Bây giờ ta sẽ tiến hành đặt tên nhé, nháy đúp vào từng chân và đặt tên lần lượt từ 1 → 32
Cứ tiếp tục cho đến khi bạn đánh xong chân của tất cả các cổng từ P0, P1, P2, P3
Bước tiếp theo chúng ta sẽ lấy LED để vẽ thành hình trái tim
- Quan trọng nhất là 2 bóng LED đầu tiên, các bạn đặt thẳng hàng với nhau, và có thể bỏ tên đi để đỡ bị rối mắt
- Tiếp theo là công đoạn công phu nhất – sắp xếp LED thành một hình trái tim (các bạn chú ý sắp xếp đúng chiều xoay theo kim đồng hồ của các bóng LED nhé)
- Ta kết nối các đầu âm của LED với vi điều khiển, do đó ta đánh số chân âm LED thứ nhất là 1 để kết nối với chân P0.0.
+ Để đánh số thì ta nối ra một đoạn dây nhỏ ở mỗi chân
+ Chọn Wire Label Mode để đánh nhãn cho các chân bóng LED
- Ta kết nối các đầu dương của LED với nguồn: Terminals Mode → POWER
+ Đặt nguồn thẳng hàng và nối với chân dương của bóng LED 1
+ Các chân dương của các bóng LED còn lại ta nối vào chân dương nguồn đó sao cho gọn gàng và đẹp mắt
- Như vậy, ta đã kết nối xong các cực dương của 32 bóng LED với nguồn. Trong thực tế, chúng ta có thể thêm điện trở vào nguồn để giảm dòng chảy qua LED. Hoặc LED sáng yếu / không sáng, ta có thể thêm các đệm dòng để LED sáng mạnh hơn.
- Tiếp theo, ta tiến hành lập trình để LED sáng theo các hiệu ứng mong muốn
Lập trình hiệu ứng cho led trái tim
Nguyên tắc: Vì chúng ta mắc theo hiểu hút dòng nên led nào sáng thì bật chân điều khiển của nó = 0 và tắt đi ta bật chân điều khiển của nó = 1
Thiết lập chương trình trên Keil C
Đây là chương trình đơn giản nhất
B1: Mở trình biên dịch KEIL C lên. Tạo một Project mới, đặt tên: ledTraiTim.
Sau đó chọn Atmel. Chọn AT89C51
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 các dấu + để mở rộng các con IC của các hãng. Ở đây ta lập trình cho
AT89C51 của hãng Atmel
Khi chọn chip thì ngay lập tức cái bảng hiện ra 1 số tính năng của chíp các bạn có thể nhìn
thấy. 8051 based Fully Static 24Mhz … . Nhap OK được cửa sổ như sau:
Chọn No. Chọn Yes chỉ làm cho file lập trình của bạn thêm nặng .
B2: Tạo một file nguồn
- Rồi lưu nó lại với đuôi .C nhé
B3: Add file ledTraiTim.c vào Project đã tạo lúc đầu
- Sau đó, bấm Close nhé các bạn
B4: Tạo file dạng hex. Nhấn chuột phải vào Target 1
- Chọn Options for Target sẽ hiện ra một bảng
- Chọn OUTPUT, nhấn chọn Create HEX File
- Nhấn OK
B5: Tiến hành lập trình:
Code của chương trình bóng LED nhấp nháy:
B6: Nhấn Rebuid / Nhấn F7 để dịch ra file HEX
B7: Tiến hành mô phỏng trên Proteus
- Nháy đúp vào vđk trên Proteus
- Chọn để lấy file HEX vừa tạo ra
- Nhấn OK
- Kết quả mô phỏng trên Proteus:
- 32 bóng LED sáng – tắt liên tục
Hiệu ứng tăng dần
Tương tự như hiệu ứng đầu tiên, chúng ta tiến hành code theo nhu cầu:
- Kết quả mô phỏng trên Proteus:
- Các bóng led được bật lên đúng theo chiều thuận kim đồng hồ
Các bạn có thể thử với chiều ngược chiều kim đồng hồ
Hiệu ứng giảm dần
- Code trên KEIL C:
- Kết quả mô phỏng trên Proteus:
- Các bóng LED tắt dần theo chiều thuận kim đồng hồ
Tương tự chúng ta cũng có thể làm cho các bóng LED tắt dần theo chiều ngược chiều kim đồng hồ:
Hiệu ứng sáng sole nhỏ giọt 😊
Các bạn có thể sáng tạo theo ý thích của bản thân
- Gợi ý code:
- Kết quả mô phỏng trên Proteus
Full code mạch led trái tim
Chúng ta sẽ ghép toàn bộ các hiệu ứng trên, ta sẽ được một chương trình với nhiều hiệu ứng, mỗi hiệu ứng thực hiện 5 lần:
#include <REGX51.H> unsigned int i, j, k; void delay(int time) { while (time--); } void nhapnhay() { P0 = P1 = P2 = P3 = 0; delay(10000); P0 = P1 = P2 = P3 = 0xff; delay(100000); } void sangdanledthuan() { unsigned char M[] = { 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 }; unsigned char N[] = { 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00 }; P0 = P1 = P2 = P3 = 0xff; for (i = 0; i < 8; i++) { P0 = M[i]; delay(10000); } for (i = 0; i < 8; i++) { P1 = M[i]; delay(10000); } for (i = 0; i < 8; i++) { P2 = M[i]; delay(10000); } for (i = 0; i < 8; i++) { P3 = M[i]; delay(10000); } } //sang dan het cac led theo chieu thuan void sangdanlednguoc() { //unsigned char M[]={0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00}; unsigned char N[] = { 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00 }; P0 = P1 = P2 = P3 = 0x00; for (i = 0; i < 8; i++) { P3 = N[i]; delay(10000); } for (i = 0; i < 8; i++) { P2 = N[i]; delay(10000); } for (i = 0; i < 8; i++) { P1 = N[i]; delay(10000); } for (i = 0; i < 8; i++) { P0 = N[i]; delay(10000); } } //sang dan het cac led theo chieu nghich void tatdanledthuan() { unsigned char M[] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; //unsigned char N[]={0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff}; P0 = P1 = P2 = P3 = 0x00; for (i = 0; i < 8; i++) { P0 = M[i]; delay(10000); } for (i = 0; i < 8; i++) { P1 = M[i]; delay(10000); } for (i = 0; i < 8; i++) { P2 = M[i]; delay(10000); } for (i = 0; i < 8; i++) { P3 = M[i]; delay(10000); } } // tat theo chieu thuan kim dong ho void tatdanlednguoc() { //unsigned char M[]={0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff}; unsigned char N[] = { 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff }; P0 = P1 = P2 = P3 = 0x00; for (i = 0; i < 8; i++) { P3 = N[i]; delay(10000); } for (i = 0; i < 8; i++) { P2 = N[i]; delay(10000); } for (i = 0; i < 8; i++) { P1 = N[i]; delay(10000); } for (i = 0; i < 8; i++) { P0 = N[i]; delay(10000); } } // tat theo chieu nguoc kim dong ho void solenhogiot() { int i, j, k = 0x00; for (i = 7; i >= 0; i--) { for (j = 0; j <= i; j++) { P0 = (0x01 << j) | k; P1 = (0x01 << j) | k; P2 = (0x01 << j) | k; P3 = (0x01 << j) | k; delay(10000); } k = P0; k = P1; k = P2; k = P3; } } // so le nho giot void main() { while (1) { for (i = 0; i < 5; i++) nhapnhay(); for (i = 0; i < 5; i++) sangdanledthuan(); for (i = 0; i < 5; i++) sangdanlednguoc(); for (i = 0; i < 5; i++) tatdanledthuan(); for (i = 0; i < 5; i++) tatdanlednguoc(); for (i = 0; i < 5; i++) solenhogiot(); } }
Ngoài ra: các bạn có thể tham khảo thêm các hiệu ứng khác:
https://drive.google.com/file/d/1rzT1Jhh1_jc6jK2C5wuatcFdsw8SQvkE/view?usp=sharing
Kết
Hi vọng sau bài này các bạn có thể làm được một mạch led trái tim để tặng gấu. Ngoài ra các bạn có thể tham khảo các code của những cao nhân khác để hoàn thiện bộ hiệu ứng nhìn pro hơn.
Tiếp tục tới bài sau trong serie nhé! Đừng quên gia nhập Hội Anh Em Nghiện Lập trình để giao lưu và học hỏi nhé!!!