Mô phỏng hiệu ứng 8 LED đơn với PIC16F877A XC8 (P2)

Mô phỏng hiệu ứng 8 LED đơn với PIC16F877A XC8 (P2)


Chào các bạn trong bài đăng này mình sẽ hướng dẫn các bạn tăng mức độ khó của PORJECT lên khó hơn 1 tý so với bài đăng trước nếu như bài đăng trước chúng ta chỉ dùng lại ở việc chớp tắt LED và sáng xen kẻ thì trong bài đăng này mình sẽ giới thiệu với các bạn về Đuổi LED (Chaser LED), sáng dồn, dịch trái, dịch phải, sáng dần, tắt dần… Đây là những hiệu ứng được sư dụng rộng rãi trong các các mạng LED trái tim hay biển quảng cáo…

Chú ý tất cả các project được viết code trên phần mềm Mplab XC8 và mô phỏng trên phần mềm Proutes 8.1.

Sau đây mình sẽ giải thích cho các bạn cụ thể về từng hiệu ứng trong bài đăng này.

1. Dịch phải và dịch trái.

Để dịch phải thì ta phải cho giá trị ban đầu của PORTB là :

PORTB = 0X01;

Sau đó chúng ta sử dụng lệnh DỊCH PHẢI để dịch LED :

PORTB = PORTB <<1;

Lệnh này chỉ dịch được 1 bit nên nếu muốn dịch nhiều bit hơn thì ta phải sử dụng vòng lặp FOR để dịch nhiều lần. Trong bài này mình dịch 8bit nên code sẽ viết như sau :

For(i=0;i<8;i++)

{

PORTB = PORTB<<1;

}

Như vậy thì ban đầu i=0 sau đó tăng I lên và mỗi lần tăng lên thì PORTB sẽ dịch qua 1 bit.

Tương tự lệnh DỊCH TRÁI thì chỉ cần sử dụng lệnh như sau :

For(i=0;i<8;i++)

{

PORTB = PORTB>>1;

}

Từ hai lệnh trên chúng ta có thể dịch 2 hoặc 3 led 1 lần, chỉ cần thay đổi giá trị ban đầu cho PORTB và tăng số bit cần dịch là được. Ví dụ dịch 1 lần 2 LED qua phải thì giá trị ban đầu cần nạp cho PORTB là PORTB = 0X03 và dịch qua 2 bit thì PORTB = PORTB<<2.

2. Sáng dần và tắt dần.

__delay_ms(300);

PORTB = 0X00;
for(i=0;i<9;i++)
{
__delay_ms(300);
PORTB = (PORTB<<1) | 0X01;
}
// chase off left
__delay_ms(300);
for(i=0;i<9;i++)
{
__delay_ms(300);
PORTB = PORTB<<1;
}

3. Sáng dồn.

CD=0X00000000;
for ( J=8;J>0;J--)
{
D=0X00000001;
for(I=0;I<J;I++)
{
Y=CD+D;
PORTB = (Y);
__delay_ms(300);
D=(D<<1);
}
CD=Y;
}

- Đây là ảnh mô phỏng proteus.

- Đây là code chương trình.

#include <xc.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define _XTAL_FREQ 8000000

// CONFIG

#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)

#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)

#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)

#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)

#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)

#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)

#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)

#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

void GPIO_init(void);// goi ham xuat nhap

void main (void)

{

    GPIO_init(); //

    unsigned char i,I,J,CD,D,Y,X;

    while(1)

    {

        // left

        PORTB = 0X01;

        for(i=0;i<8;i++)

        {

           __delay_ms(300);

            PORTB = PORTB<<1;

        }

        // right

        __delay_ms(300);

        PORTB = 0X80;

        for(i=0;i<8;i++)

        {

            __delay_ms(300);

            PORTB = PORTB>>1;

        }

        // left 2

        PORTB = 0X03;

        for(i=0;i<4;i++)

        {

            __delay_ms(300);

            PORTB = PORTB<<2;

        }

        // right 2

        PORTB = 0XC0;

        for(i=0;i<4;i++)

        {

            __delay_ms(300);

            PORTB = PORTB>>2;

        }

        // chase left

        __delay_ms(300);

        PORTB = 0X00;

        for(i=0;i<9;i++)

        {

           __delay_ms(300);

           PORTB = PORTB>>1;

           PORTB = PORTB | 0X80;

        }

        // chase right

       __delay_ms(300);

        PORTB = 0X00;

        for(i=0;i<9;i++)

        {

           __delay_ms(300);

           PORTB = PORTB<<1;

           PORTB = PORTB | 1;

        }

        // chase on left

        __delay_ms(300);

        PORTB = 0X00;

        for(i=0;i<9;i++)

        {

            __delay_ms(300);

            PORTB = (PORTB<<1) | 0X01;

        }

        // chase off left

        __delay_ms(300);

        for(i=0;i<9;i++)

        {

            __delay_ms(300);

            PORTB = PORTB<<1;

        }

        // chase right on and off

        __delay_ms(300);

        X=0X00000000;

        for(I=0;I<8;I++)

        {

           X=(X<<1)+0X01;

           PORTB = X;

           __delay_ms(300);

        }

        for(I=0;I<8;I++)

        {

           X=(X>>1);

           PORTB = X;

           __delay_ms(300);

        }

        // don 1

          __delay_ms(300);

        CD=0X00000000;

        for ( J=8;J>0;J--)

        {

        D=0X00000001;

        for(I=0;I<J;I++)

        {

        Y=CD+D;

        PORTB = (Y);

        __delay_ms(300);

        D=(D<<1);

        }

        CD=Y;

        }

        // don 2

        __delay_ms(300);

        CD=0X00;

        for ( J=4;J>0;J--)

        {

        __delay_ms(300);

        D=0X03;//0x03

        for(I=0;I<J;I++)

        {

        __delay_ms(100);

        Y=CD+D;

        PORTB = (Y);

        __delay_ms(300);

        D=(D<<2);

        }

        CD=Y;

        }

        }

    }

void GPIO_init(void)

{

    TRISB = 0X00; // cho porta la  output

    PORTB = 0X00; //

}

Bình Luận
Cùng danh mục: Vi điều khiển - Lập trình

Cơ sở công suất và năng lượng tiêu thụ trên MCU

29/07/2023 21:21:12 / Lượt xem: 387 / Người đăng: biendt

Công suất và năng lượng tiêu thụ của MCU ảnh hưởng đến các quyết định thiết kế về nguồn, thời gian sử dụng pin, và kể cả nhiệt độ hoạt động trong các ứng dụng nhúng. Nhất là khi đối mặt với các ứng dụng được cung cấp năng lượng từ nguồn pin,

Giải thích cơ chế các lệnh SET BIT, CLEAR BIT và TOGGLE trong lập trình vi điều khiển

15/09/2022 08:10:32 / Lượt xem: 970 / Người đăng: biendt

Giải thích các lệnh SET BIT, CLEAR BIT và TOGGLE thường được dùng trong lập trình vi điều khiển. Lệnh SET BIT là lệnh cài đặt 1 bit mong muốn trong thanh ghi cho nó có giá trị logic 1 và không làm thay đổi giá trị các bit còn lại của thanh ghi đó. Lệnh CLEAR BIT là lệnh cài đặt 1 bit mong muốn trong thanh ghi cho nó giá trị logic 0 và không làm thay đổi giá trị các bit còn lại của thanh ghi đó. Lệnh TOGGLE BIT là lệnh cài đặt 1 bit mong muốn trong thanh ghi cho nó giá trị logic 0 nếu trước đó nó có giá trị logic 1 và ngược lại, đồng thời không làm thay đổi giá trị các bit còn lại của thanh ghi đó.

Chia sẻ chương trình đọc ghi thẻ SD bằng MSP430 G2553 phục vụ lưu trữ

17/08/2022 06:20:30 / Lượt xem: 713 / Người đăng: biendt

Chương trình sử dụng vi điều khiển chính là MSP430G2553 (có thể sử dụng vi điều khiển khác cùng họ MSP430) kết nối với module đọc/ghi thẻ nhớ SD card là MODULE MICRO SD CARD để lưu trữ dữ liệu, đọc dữ liệu…Chuẩn bị : 1 KIT MSP430G2553, 1 Module SD Card, 1 Thẻ nhớ SD card : Micro SD <= 2GB hoặc Micro SDHC <= 32GB

Hướng dẫn thiết kế mạch vi điều khiển đơn giản

07/06/2022 06:18:47 / Lượt xem: 780 / Người đăng: biendt

Thiết kế mạch cho vi điều khiển là một việc làm không hề đơn giản đối với những người mới bắt đầu. Có thể bạn phải đọc hàng trăm trang datasheet và tài liệu thiết kế tham khảo, các sơ đồ mạch thiết kế mẫu, các chỉ dẫn layout để có thể hoàn thiện được thiết kế của mình một cách tốt nhất. Hướng dẫn này sẽ chỉ ra những điểm chung mà các bạn cần lưu ý khi thiết kế mạch vi điều khiển

Thiết kế mạch chống nhiễu cho Vi điều khiển (Chíp lập trình hoặc IC)

05/05/2022 06:05:35 / Lượt xem: 1961 / Người đăng: biendt

Có mấy phương pháp cho mạch chống nhiễu vi điều khiển : .Sử dụng cách ly quang: để cách ly giữa tín hiệu điều khiển từ VĐK xuất ra và mạch công suất 220v.Sử dụng mạch snubber khi điều khiển tải bằng relay.Sử dụng linh kiện điện tử chính hãng...Sử dụng mạch lọc nguồn AC 220v trước khi cấp cho bộ nguồn 5V nuôi VĐK...Chống nhiễu khi viết code