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ải đáp giúp pic6f877A (http://www.picvietnam.com/forum/showthread.php?t=3550)

vietktqs_dragon 18-02-2009 01:26 AM

giải đáp giúp pic6f877A
 
mình mói làm quen với Pic.có 1 bài tập cho 4led 7 thanh hiện thị từ 0000->9999.mỗi 1s tăng 1 đơn vị
tuy nhiên mình mới code dc cho hiện thị số có 4 chứ số mình muốn.mong các bạn giúp đỡ
Code:

#include <16f877a.h>
#include <def_877a.h>
#device *=16 ADC=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP
#use delay(clock=20000000)
int8 led[4] = {0b11110111,0b00111011,0b11111101,0b00111110};
int8 Font[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

void hienthi(int16 count)
{
int8 a[4]={0};
int8 j;
a[3]=count/1000;
a[2]=(count/100)%10;
a[1]=(count/10)%10;
a[0]=count%10;

for (j=0;j<4;j++)
  {
  porta=led[j];
  portd=Font[a[j]];
  delay_ms(2);
 
  }

}
void main()
{

trisa=0x00;
porta=0xff;
trisd=0x00;
portd=0xff;
while(1)
{
hienthi(2009);
delay_ms(2);

}
}


mtuankct 03-03-2009 08:26 PM

Theo mình để thực hiện việc này thì bạn dùng một Timer để thực hiện vòng quét Led (hàm hiển thị của bạn) còn trong chuơng trình main bạn sẽ thay đổi dữ liệu để hiện được các số khác nhau.

xuanhiendk2 04-03-2009 12:40 PM

Trích:

Nguyên văn bởi vietktqs_dragon (Post 22690)
mình mói làm quen với Pic.có 1 bài tập cho 4led 7 thanh hiện thị từ 0000->9999.mỗi 1s tăng 1 đơn vị
tuy nhiên mình mới code dc cho hiện thị số có 4 chứ số mình muốn.mong các bạn giúp đỡ
Code:

#include <16f877a.h>
#include <def_877a.h>
#device *=16 ADC=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP
#use delay(clock=20000000)
int8 led[4] = {0b11110111,0b00111011,0b11111101,0b00111110};
int8 Font[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

void hienthi(int16 count)
{
int8 a[4]={0};
int8 j;
a[3]=count/1000;
a[2]=(count/100)%10;
a[1]=(count/10)%10;
a[0]=count%10;

for (j=0;j<4;j++)
  {
  porta=led[j];
  portd=Font[a[j]];
  delay_ms(2);
 
  }

}
void main()
{

trisa=0x00;
porta=0xff;
trisd=0x00;
portd=0xff;
while(1)
{
hienthi(2009);
delay_ms(2);

}
}


bạn nên đưa cả schematic lên để mọi người góp ý cho dễ. Mà chương trình của bạn hình như là hiển thị số 2009 lên 4 Led 7 đoạn đấy chứ có phải là hiển thị tăng dần từ 0000 đến 9999 đâu

nguyenluong 09-03-2009 06:04 PM

Trích:

Nguyên văn bởi vietktqs_dragon (Post 22690)
mình mói làm quen với Pic.có 1 bài tập cho 4led 7 thanh hiện thị từ 0000->9999.mỗi 1s tăng 1 đơn vị
tuy nhiên mình mới code dc cho hiện thị số có 4 chứ số mình muốn.mong các bạn giúp đỡ
Code:

#include <16f877a.h>
#include <def_877a.h>
#device *=16 ADC=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP
#use delay(clock=20000000)
int8 led[4] = {0b11110111,0b00111011,0b11111101,0b00111110};
int8 Font[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

void hienthi(int16 count)
{
int8 a[4]={0};
int8 j;
a[3]=count/1000;
a[2]=(count/100)%10;
a[1]=(count/10)%10;
a[0]=count%10;

for (j=0;j<4;j++)
  {
  porta=led[j];
  portd=Font[a[j]];
  delay_ms(2);
 
  }

}
void main()
{

trisa=0x00;
porta=0xff;
trisd=0x00;
portd=0xff;
while(1)
{
hienthi(2009);
delay_ms(2);

}
}


Bạn khởi tai ngắt Timer 1s, mỗi lần như vậy bạn tăng lên 1 đơn vị

sonduy1 04-08-2009 04:03 PM

vậy cho mình hỏi dùng timer ?
 
Trích:

Nguyên văn bởi mtuankct (Post 23190)
Theo mình để thực hiện việc này thì bạn dùng một Timer để thực hiện vòng quét Led (hàm hiển thị của bạn) còn trong chuơng trình main bạn sẽ thay đổi dữ liệu để hiện được các số khác nhau.

#INT_TIMER1
void ngat_timer1()
{ int time=0,count=0;
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_timer1(24280);
time++; // timer 1 tràn sau ==> 500 000 us = 0.5s
if(time==2) // 2* 500 000 =1s
{
count++;
if(count==1)
{ portb=bang_ma[n1];
output_low(pin_d0);//mo transistor để led7 doan dc cap 5v(dung anot chung)
}
if(count==2)
{ portb=bang_ma[n2];
output_low(pin_d1);//tuong tu o d0
}
if(count==3)
{ portb=bang_ma[n3];
output_low(pin_d3);//
}
if(count==4)
{ portb=bang_ma[n4];
output_low(pin_d4);//
}
count=0;
}
enable_interrupts(int_timer1);
enable_interrupts(global);
}



bác coi giup sau e thực hiên quét mà kô dc.

manhha2799 06-08-2009 01:51 AM

Trích:

Nguyên văn bởi sonduy1 (Post 28349)
#INT_TIMER1
void ngat_timer1()
{ int time=0,count=0;
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_timer1(24280);
time++; // timer 1 tràn sau ==> 500 000 us = 0.5s
if(time==2) // 2* 500 000 =1s
{
count++;
if(count==1)
{ portb=bang_ma[n1];
output_low(pin_d0);//mo transistor để led7 doan dc cap 5v(dung anot chung)
}
if(count==2)
{ portb=bang_ma[n2];
output_low(pin_d1);//tuong tu o d0
}
if(count==3)
{ portb=bang_ma[n3];
output_low(pin_d3);//
}
if(count==4)
{ portb=bang_ma[n4];
output_low(pin_d4);//
}
count=0;
}
enable_interrupts(int_timer1);
enable_interrupts(global);
}



bác coi giup sau e thực hiên quét mà kô dc.

Mấy dòng này bạn phải để trong void main() chứ:
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_timer1(24280);
enable_interrupts(int_timer1);
enable_interrupts(global);

Với lại hàm if, mấy cái sau bạn thử dùng else if xem sao. Chứ if thì có thể nó sẽ bị lẫn lộn đó.

sonduy1 06-08-2009 05:36 PM

The còn cái này thì sao ha bác
 
#include <16f877a.h>
#fuses HS,NOWDT
#use delay(clock=4000000)
#byte trisb=0x86
#byte portb=0x06
#BYTE TRISD=0X88
#BYTE PORTD=0X08


char bang_ma[10]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x9 0};
char n1,n2,n3,n4;
char sec,min,h;
#int_timer1
void ngat_TMR1()
{ int time,count;
set_timer1(15535);
time++;
if(time=1);//dc 1/2s
//<thuc hien cong viec>
{
count++;
if(count==1)
{ portb=bang_ma[N1];
OUTPUT_LOW(PIN_A0);
DELAY_MS(10);
OUTPUT_HIGH(PIN_A0);
}
if(count==2)
{ portb=bang_ma[N2];
OUTPUT_LOW(PIN_A1);
DELAY_MS(10);

}
if(count==3)
{ portD=bang_ma[N3];

OUTPUT_LOW(PIN_A4);DELAY_MS(10);
OUTPUT_HIGH(PIN_A4);
}
if(count==4)
{ portD=bang_ma[N4];
OUTPUT_LOW(PIN_A5);
DELAY_MS(10);
}
count==0;



}
time==0;
}
//SU DUNG HAM NGAT TIMER0 DE HIEN THI
#INT_TIMER0

void ngat_timer0()
{ int dem;

set_timer0(15536); //mac dinh gia tri ban dau cho TMR0

dem++;
if(dem==20) //20*50000=1s
{ dem=0;
sec++;
}
if(sec==60)
{ sec=0;
min++;
}
if(min==60)
{ min=0;
h++;
}
if(h==24)
{ h=0;
}
}





VOID main(void)
{ trisb=0x00;
portb=0xff;
TRISD=0X00;
PORTD=0XFF;
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
set_timer0(15536);
enable_interrupts(int_timer0);
enable_interrupts(global);


setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
set_timer1(15535);
enable_interrupts(int_timer1);
enable_interrupts(global);
N1=H/10;
N2=H%10;
N3=SEC/10;
N4=SEC%10;
while(1)
{

NGAT_TIMER0();
N1=H/10;
N2=H%10;
N3=SEC/10;
N4=SEC%10;
ngat_TMR1();

}
}



//em cho 4 led 7 doạn 2 led gắn với 2 port.và nguon` vao` 5v nối tới con trans tới các chân a0-a3.

dung h 07-08-2009 01:37 AM

bạn có thể tham khảo chương trình này:
đếm từ 0000->9999 sử dụng ngắt timer1 tao 1s
code:
Code:

#include<16f877a.h>
#fuses NOWDT,HS,NOPROTECT,NOLVP
#use delay(clock =20000000)
#use fast_io(b)
#use fast_io(d)
#byte portb=0x06
#byte portd=0x08

int8 a,b,c,d,dem=0;
int16 count=0;
const char code[]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

#int_timer1
void ngat_timer1()
{
  dem++;
  if(dem>19)
  {
  count++;
  dem=0;
  if(count>9999)
  count=0;
  }
  set_timer1(15535);
}

void chuyendoi(int16 x)
{
  a=(int8)(count%10);
  b=(int8)((count/10)%10);
  c=(int8)((count/100)%10);
  d=(int8)(count/1000);
}
void tre()
{
 int8 i;
 for(i=0;i<255;i++)
 {
 }
}
void quetled()
{
  portb=code[a];
  portd=0x01;
  tre();
  portb=code[b];
  portd=0x02;
  tre();
  portb=code[c];
  portd=0x04;
  tre();
  portb=code[d];
  portd=0x08;
  tre();
}

void main()
{
  set_tris_b(0x00);
  set_tris_d(0x00);
  set_tris_c(0x00);
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
  set_timer1(15535);
  enable_interrupts(int_timer1);
  enable_interrupts(global);
 
  while(true)
  {
  chuyendoi(count);
  quetled();
  output_c(code[a]);
  }
}

try to best!

sonduy1 07-08-2009 11:56 AM

gởi a !
 
Trích:

Nguyên văn bởi manhha2799 (Post 28377)
Mấy dòng này bạn phải để trong void main() chứ:
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
set_timer1(24280);
enable_interrupts(int_timer1);
enable_interrupts(global);

Với lại hàm if, mấy cái sau bạn thử dùng else if xem sao. Chứ if thì có thể nó sẽ bị lẫn lộn đó.

vậy nếu dùng else thì dùng sáo cho đúng hả a. !!...

silvadk2 06-08-2010 01:12 PM

trong bài của bạn Dung_h :
- Bạn có thể dùng hàm delay_ms(),delay_us() của ccs, không cần tạo hàm tre();
- Theo như bài bạn khai báo, chắc thạch anh sử dụng là 20Mhz. Như vậy công thức tính cho timer1 của bạn là : T= 20 x (66536-15535) x 1 x4/20000000 ~ 0.2s chứ không phải 1s.

semipower 06-08-2010 05:56 PM

Sửa lại như sau:
while (1)
{
i=0x1;
while (i != 0)
{
portb=i;
delay_ms(100);
i<<=1;
}
}

thanhdt2985 06-08-2010 06:36 PM

chương trình sáng dần
 
1 Attachment(s)
mình muốn chương trình này lặp lại mãi mãi .nhưng chỉ chạy được một lần là thôi
các ban sửa giúp mình nhé . thankyou!

#include<16f877a.h>
#use delay(clock=4000000)
#byte trisb=0x86
#byte portb=0x06
void main()
{
char i,j;
trisb=0x0;
while (true)
{
i=0x1;
j=i;
portb=0b00000000;
delay_ms(100);
while (portb!=0b11111111)
{
portb=i;
delay_ms(100);
i<<=1;
i|=j;
}
}
}

thanhdt2985 06-08-2010 06:40 PM

Trích:

Nguyên văn bởi semipower (Post 37822)
Sửa lại như sau:
while (1)
{
i=0x1;
while (i != 0)
{
portb=i;
delay_ms(100);
i<<=1;
}
}

cảm ơn bạn nhé!
bạn sửa lại giúp mình lần nữa nhé
mình ghi nhầm chủ đề. chương trình của mình là sáng dần chứ không phải là một điểm sáng chạy như vừa rồi
thanhk!

semipower 06-08-2010 09:55 PM

while (1)
{
i=1;
j=1;
PORTB=0;
while (j != 0)
{
__delay_ms(100);
PORTB=i;
j<<=1;
i+=j;
}
}


Múi giờ GMT. Hiện tại là 12:34 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