PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cơ bản về vi điều khiển và PIC (http://www.picvietnam.com/forum/forumdisplay.php?f=8)
-   -   Giúp mình bài tập này với!!! (http://www.picvietnam.com/forum/showthread.php?t=7250)

akatsu 25-10-2010 01:28 PM

Giúp mình bài tập này với!!!
 
Mình vừa mới làm quen với PIC đang bị bí chỗ này.

mình dùng 1 chân RB1 làm nút nhấn. Khi bấm 10 lần RB1 thì led gắn ở chân RD1 sáng lên 1 lần.
Chỉ đơn giản như thế thôi. Nhưng mà do gà quá. Các pác giúp dùm e nhá

venderhak 26-10-2010 12:08 AM

Trả lời
 
Bài này khá đơn giản. Mình viết bằng ngôn ngữ ASSEMBLY, mình thực hành trên BOARD PICDEM 2+ 2006 (microchip) . Bạn có thể mô phỏng bằng PROTEUS để thấy trực quan hơn.
Cần chú ý các thanh ghi của mình, mình chọn nút nhấn RA4, LED đơn gắn ở chân RB0 (chip P18f4520), delay 1s , led sáng 1s rồi sẽ tắt.

p=18f4520
#include p18f4520.inc

udata
a res 1
b res 1
c res 1
d res 1

org 0000h
goto start
start
call init

dem10
call an10
decfsz a
goto dem10
bsf PORTB,0
call delay1s
bcf PORTB,0
return

an10
btfsc PORTA,4 ;kiem tra bam nut
goto an10
tha10
btfss PORTA,4
goto tha10
return

delay1s
movlw .4
movwf b
delay1s_1
movlw .250
movwf c
delay
call delayX
decfsz c
goto delay
decfsz b
goto delay1s_1
return

delayX
nop
decfsz d
goto delayX
return

init
movlw .10
movwf a
;chon portb lam port xuat
clrf PORTB
bcf TRISB,0
;chon porta lam input
clrf PORTA
bsf TRISA,4
bsf PORTA,4
return
end

Mong bạn cho ý kiến thêm. Chúc vui.

akatsu 26-10-2010 05:53 PM

hì. cám ơn bạn nhiều. bạn có chương trình C không. mình không học ASM nên đọc không hỉu lắm...hì

akatsu 26-10-2010 06:02 PM

mình định xây dụng 1 hàm quét phím theo kiểu int8
INT8 QUETPHIM0123()
{
Z = 0 ;
WHILE(BIT_TEST(INPUT_B(),Z))
{

Z++ ;
IF(Z == 2) Z = 0 ;//cái này là để xác định chỉ quét 2 nút nhấn RB0,RB1

}
WHILE(!BIT_TEST(INPUT_B(),Z))
{
}
RETURN Z ;


}
nếu như trong trường hợp bấm nút nào thì nhảy sang chương trình đó.

trong đó RB0 là chương trình bấm 10 lần. nhưng cách viết để đếm chân RB0 lên 10 lần mình không làm đc. Bạn nào cao thủ giúp mình nha

pk178 27-10-2010 12:22 AM

Trích:

Nguyên văn bởi akatsu (Post 39575)
Mình vừa mới làm quen với PIC đang bị bí chỗ này.

mình dùng 1 chân RB1 làm nút nhấn. Khi bấm 10 lần RB1 thì led gắn ở chân RD1 sáng lên 1 lần.
Chỉ đơn giản như thế thôi. Nhưng mà do gà quá. Các pác giúp dùm e nhá

Chương trình khá đơn giản, vấn đề là bạn phải đợi khi người dùng bấm xong (ấn xuống rồi nhả ra) thì biến đếm mới được tăng lên 1 đơn vị.

Giả sử phím bấm của bạn nối điện trở treo pull-up, khi đó nếu không bấm thì mức logic tại B1 là 1, nếu bấm thì mức logic tại B1 là 1, đoạn code tăng biến đếm như sau :

Code:

int i = 0; // Biến i sẽ là biến đếm

while(1){

if(input(PIN_B1) == 0)
while(input(PIN_B1) == 0); // Đợi cho người dùng nhả phím bấm
i++;
if(i == 10) output_high(PIN_D1);

}

............


xtravel 27-10-2010 01:17 AM

nếu nut nhấn trên chân RB4-RB7,ngoài cách dùng q0et bit ngõ vào ta có thế dùng ngắt,chuớng trình phục vụ ngắt chỉ làm việc đơn giản là thực hiện i++ nếu i = = 10 thì bật led tương ứng 1s...

hcmut.khoamaisi 27-10-2010 01:53 AM

cái này theo mình là phải dùng ngắt ngoài thì mới chương trình chính xác!

akatsu 28-10-2010 03:51 PM

đúng vậy...phải dùng ngắt ngoài..mình đã thử code và thấy nó chạy loạn lên hết.lúc thì bấm đến 9 đã nhảy.lúc bấm đến 2 đã nhảy. mình dùng Easy KIT

pk178 28-10-2010 09:16 PM

Cái việc nó nhảy loạn là do thuật toán chưa tốt, bạn tìm hiểu thêm về các phương pháp chống rung bàn phím nhé.

Mình vẫn bắt phím theo cách trên, chạy ngon lành, ko có vấn đề gì cả (phím bấm của mình chống rung bằng phần cứng rồi :D)

akatsu 29-10-2010 04:56 PM

#include <16F877A.h>
#include <def_877a.h>
#device adc=8
#FUSES NOWDT, HS, PUT, PROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
//#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8)
#use fast_io(b)
int8 i=0;
void densang();
void reset();
#int_rb
void ngatngoai()
{
if ((RBIF)&&(RBIE))
{
if(RB0==0)
{//while(RB0==0);
i++;
if(i==10)
{
i=0;
densang();
}
}
if(RB1==0)
{
reset();
}
}

}





void main()
{
set_tris_b(0);
set_tris_d(0xff);
enable_interrupts(int_rb);
enable_interrupts(global);
ext_int_edge(H_to_L);

while(true)
{
}

}
void densang()
{
output_high(PIN_D0);
}
void reset()
{
i=0;
output_low(pin_d0);
}


đây là code e mới viết. các cao thủ xem jup e xem có sai sót j k nhá!!!e cám ơn

tdm 30-10-2010 10:06 PM

Trích:

Nguyên văn bởi akatsu (Post 39704)
#include <16F877A.h>
#include <def_877a.h>
#device adc=8
#FUSES NOWDT, HS, PUT, PROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
//#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8)
#use fast_io(b)
int8 i=0;
void densang();
void reset();
#int_rb
void ngatngoai()
{
if ((RBIF)&&(RBIE))
{
if(RB0==0)
{//while(RB0==0);
i++;
if(i==10)
{
i=0;
densang();
}
}
if(RB1==0)
{
reset();
}
}

}
}




void main()
{
set_tris_b(0);
set_tris_d(0xff);
enable_interrupts(int_rb);
enable_interrupts(global);
ext_int_edge(L_to_H);

while(true)
{
}

}
void densang()
{
output_high(PIN_D0);
}
void reset()
{
i=0;
output_low(pin_d0);
}


đây là code e mới viết. các cao thủ xem jup e xem có sai sót j k nhá!!!e cám ơn

enable_interrupts(int_rb);//chỉ ngắt khi các pin rb4,rb5,rb6,rb7 tác động.
set_tris_b(0);//các chân portb là chân xuất dữ liệu.(nên phím không có tác dụng)
set_tris_d(0xff);//các chân portd là chân nhập dữ liệu.
sửa bài này như sau:
Code:

#include <16F877A.h>
#include <def_877a.h>
#device adc=8
#FUSES NOWDT, HS, PUT, PROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
//#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use fast_io(b)
int8 i=0;
void densang();
void reset();
#int_rb
void ngatngoai()
    {
  if((RBIF)&&(RBIE))
  {
        if(RB4==0)
        {
        delay_ms(10);//chong rung phim
        if(RB4==0)
          {
            i++;
            if(i==10)
              {
              i=0;
                densang();     
              }
          while (RB4==0)//chờ phím nhả
          {
          }
          delay_ms(10);//chong rung phim
          }
        }
        //*******************************
        else if(RB5==0)
        {
        delay_ms(10);//chong rung phim
        if(RB5==0)
          {
          reset();
        while (RB5==0)//chờ nhả phím
          {
          }
          delay_ms(10);//chong rung phim
          }
        }

void main()
{
set_tris_b(0xf0);//rb4...rb7 là pin nhập
set_tris_d(0xfe);//pinD0 là pin xuất dữ liệu
enable_interrupts(int_rb);
enable_interrupts(global);
ext_int_edge(H_to_L);
reset();
while(true)
{
}

}
void densang()
      {
      output_high(PIN_D0);
      }
void reset()
      {
      i=0;
      output_low(pin_d0);
      }


tdm 30-10-2010 10:38 PM

1 Attachment(s)
file mô phỏng:

akatsu 31-10-2010 11:44 AM

mình cám ơn..mình đã viết theo cách mới nghĩ ra và mạch chạy thấy cũng ok rùi..hihi.cám ơn bạn tmd nhiều nha...bạn có mail k?cho mình xin đi.có gì mình cùng trao đổi.hi


Múi giờ GMT. Hiện tại là 04:25 AM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam