Thứ Sáu, 22 tháng 1, 2016

BÀI 12 : ĐẾM TỪ 0 ĐẾN 99 SỬ DỤNG 2 NÚT NHẤN PIC16F887 XC8

Chào các bạn trong bài đăng trước mình đã hướng dẫn các bạn đến từ 0 đến 9 và từ 9 về 0 sử dụng 2 nút nhấn 1 nút nhấn tăng và 1 nút nhấn giảm và trong bài này chúng ta cũng làm tương tự nhưng lần này là từ 0 đến 99 nha.
Các bạn chú ý nếu không có thời gian chống dội phím thì khi nhấn giá trị trên LED sẽ không như chúng ta mong muốn có nghĩa là nó sẽ tăng 1 lúc nhiều số hoặc ngược lại hoặc khi nhấn nút sẽ không có tác dụng gì. Và thêm 1 chú ý nữa cũng rất quan trọng khi các bạn sử dụng PORTA là PORT xuất thì không sao nhưng khi sử dụng PORTA là PORT nhập thì phải tắt chế độ ADC của nó đi nếu không các bạn sẽ không điều khiển nút nhấn như ý muốn của mình được ! Và đển tắt chế độ ADC của nó đi thì chúng ta phải cho thanh ghi ANSEL = 0 các bạn tự tra Datasheet của thanh ghì này nha và coi thử tại sau chúng ta lại cho giá trị thanh ghi ANSEL  = 0 nha. Trong PIC16F887 thì có 2 thanh ghi liên quan đến ADC là ANSEL và ANSELH nhưng ở đây mình chỉ sử dụng 2 chân là RA0 và RA1 nên chỉ cần cho 1 bit ANS0 và ANS1 của thanh ghi ANSEL bằng 0 thì chúng ta có thể sử dụng 2 chân này với chức năng là I/O và chúng ta sẽ cấu hình như sau :
ANSELbits.ANS0 = 0; // OFF ADC 
ANSELbits.ANS1 = 0; // OFF ADC 
Đây là phần quan trọng cần phải chú ý nếu không có lệnh trên thì chương trình của chúng ta sẽ không chạy đúng đâu nha !
- Đây là ảnh mô phỏng protues.
đếm từ 0 đến 99 sử dụng 2 nút nhấn
- Đây là code chương trình.
#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 8000000
#include <xc.h>
// CONFIG1
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)
void displayed(unsigned int digit);
unsigned char  const SEGMENT_MAP[10] = {0XBF,0X86,0XDB,0XCF,0XE6,0XED,0XFD,0X87,0XFF,0XEF};
void main(void) {
     ANSELbits.ANS0 = 0; // OFF ADC 
     ANSELbits.ANS1 = 0; // OFF ADC 
     TRISC = 0;           //Set PortB to all outputs
     PORTC = 0;
     TRISAbits.TRISA0 = 1;             //Set PortC.0 as input
     TRISAbits.TRISA1 = 1;
     TRISDbits.TRISD0 = 0;
     TRISDbits.TRISD1 = 0;
     char digit=0;
     while(1)
     {
     //displayed(digit);
     if (!RA0)        //Check if switch SW1 is closed
     {
     __delay_ms(100);
     if(!RA0)       //Check if switch SW1 is still closed
     {
     digit++;
     if (digit==100)
     digit=0;
     __delay_ms(10); //wait for 100ms
     }
     }
     else
     {
     displayed(digit);
     }
     if (!RA1)        //Check if switch SW1 is closed
     {
     __delay_ms(100); //wait for 100ms
     if (!RA1)       //Check if switch SW1 is still closed
     {
     digit--;
     if (digit==0)
     digit=99;
     __delay_ms(10); //Delay 1 second
     }
     }
     else
     {
     displayed(digit);
     }
    }
}
void displayed(unsigned int digit)
{
     unsigned int one,ten;
     ten = (digit)/10;
     one = (digit)%10;

     RD0 = 0;
     PORTC = (SEGMENT_MAP[ten]);
     __delay_ms(10);
     RD0 = 1;

     RD1 = 0;
     PORTC = (SEGMENT_MAP[one]);
     __delay_ms(10);
     RD1 = 1;

}
- Link download project Click here


EmoticonEmoticon