PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Các ngôn ngữ lập trình khác (CCS C, HT PIC,...) (http://www.picvietnam.com/forum/forumdisplay.php?f=12)
-   -   CCS C for PIC16F877A (http://www.picvietnam.com/forum/showthread.php?t=357)

tungtot_vl 01-10-2007 04:53 PM

ai giải thích cho mình cái này nhỉ
khi dùng : unsigned char font[] = {...}; thì chương trình báo lỗi không đủ RAM
khi dùng : unsigned char const font[] = {...}; thì chương trình hết báo lỗi và dung lượng RAM giảm xuống rất nhiều.
mong giúp đỡ

nbchien 02-10-2007 03:28 PM

Sao luồng này trầm thế nhỉ. Lâu lâu không thấy các cao thủ post bài cho bọn đàn em học tập với nhỉ

thaithienanh 03-10-2007 12:43 AM

Trích:

Nguyên văn bởi tungtot_vl (Post 11721)
ai giải thích cho mình cái này nhỉ
khi dùng : unsigned char font[] = {...}; thì chương trình báo lỗi không đủ RAM
khi dùng : unsigned char const font[] = {...}; thì chương trình hết báo lỗi và dung lượng RAM giảm xuống rất nhiều.
mong giúp đỡ

:) Với cách khai báo thứ nhất sẽ có ý nghĩa là một mảng biến có kiểu ký tự cho nên dung lượng Ram lúc này sẽ tốn rất đáng kể.

Còn với cách khai báo thứ hai sẽ chỉ là một mảng các hằng số kiểu ký tự mà thôi cho nên việc bạn nhìn thấy dung lượng Ram giảm xuống rất nhiều là điều bình thường :)

thaithienanh 03-10-2007 01:06 AM

1 Attachment(s)
Trích:

Nguyên văn bởi nbchien (Post 11566)
Cảm ơn bác nhh đã trả lời câu hỏi của em. Bác có thể viết tiếp 1 chương trình đếm số xung đưa vào PIC trong 1 thời gian nhất định (1s chẳng hạn) để em và mọi người cùng tham khảo được không ạ?

Ừhm với câu hỏi này bạn có thể tham khảo qua ví dụ của anh Linh :)

thongtr 08-10-2007 02:50 AM

1 Attachment(s)
Em vừa mới viết xong ct hiển thị LCD 4 bit! có hiệu ứng chữ chạy rất hay!! em post lên cho các pác tham khảo nhé! và góp ý cho em nhé!

#include <16F877A.h>
#include <DEFS_16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#define use_portb_lcd TRUE
#include <lcd.c>
const unsigned char line1[]={'H','E','L','L','O',' ','P','I','C','V','N','!','#'};
const unsigned char line2[]={'Y','H',':','T','H','O','N','G','T','R','0','6', '0','1','@',\
'Y','A','H','O','O','.','C','O','M','#'};

void main(void)
{ while(true)
{
int I=0,y=0,k=0,z=0;
delay_ms(100); // tao tre 100ms cho LCD khoi dong
lcd_init();
lcd_gotoxy(1,1);
while (line1[y]!='#')
{
lcd_putc(line1[y]);
delay_ms(200);
y++;
}
lcd_gotoxy(1,2);
while (i<16)
{
lcd_putc(line2[I]);
i++;
delay_ms(200);
}
i=2;

while (line2[z]!='#')
{
lcd_init();
lcd_gotoxy(1,1);
y=0;
while (line1[y]!='#')
{
lcd_putc(line1[y]);
y++; }

lcd_gotoxy(1,2);
k=i+16;
for(z=i;z<k;z++)
{lcd_putc(line2[z]);}
delay_ms(400);
i++;
}
}
}

Nguoidumuc204 11-10-2007 09:14 AM

Mình thấy khai báo mảng của bạn hơi phức tạp , sao không khai báo là

const unsigned char line1[]={"Hello PICVIETNAM#"};
const unsigned char line2[]={"YH :xxx"};

vậy thì đơn giản, dễ hiểu và kết quả vẫn vậy.

và hàm lcd_init(); chỉ cần dùng một lầm duy nhất là đủ,như vấy sẽ không làm cho lcd bị nháy khi hiển thị các câu khác nhau. Nếu muốn xóa trắng màn hình thì chỉ việc dùng lệnh lcd_putc("\f");

Nguoidumuc204 11-10-2007 09:29 AM

Có cao thủ nào có thể cho em biết công thức liên hệ giữa Resolution và Overflow trong con PIC 16F877A không?
Em dùng thạch anh 4Mhz, timer0 , Resolution : 8us, Overflow : 2ms. Nhưng em không hiểu chúng liên hệ với nhau thế nào.
Em mới ra nhập làng VDK nói chung và Pic nói riêng,mong các bác giúp đỡ.

Nguoidumuc204 11-10-2007 11:16 AM

Trích:

Nguyên văn bởi Nguoidumuc204 (Post 11990)
Có cao thủ nào có thể cho em biết công thức liên hệ giữa Resolution và Overflow trong con PIC 16F877A không?
Em dùng thạch anh 4Mhz, timer0 , Resolution : 8us, Overflow : 2ms. Nhưng em không hiểu chúng liên hệ với nhau thế nào.
Em mới ra nhập làng VDK nói chung và Pic nói riêng,mong các bác giúp đỡ.


Chờ cả buổi mà chẳng bác nào tra lời,đi ăn xin nhiều nơi mới hiểu ra, thôi thì cứ POST lên cho anh em nào chưa rõ thì coi.

Timer0 là bộ định thời có khoảng chia cho trước , các khoảng chia theo 2 lũy thừa 1 2 4 8 ... ( tùy theo chip )

Ví dụ ở câu hỏi trên của em thì câu lệnh
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4); // Prescale 4us,Overflow 2us

có nghĩa là :
cứ 4us ( 4 xung đồng hồ ) ==> 1 xung timer
cứ 255 xung timer ( 8 bit ) ==> 1 lần tràn
==> timer sẽ tràn từ 0xFF -> 0x00 trong khoảng thời gian 4 x 255 = 1020 us

Sangcao 11-10-2007 02:57 PM

Bác nào giúp em với:! Em muon truyền 1 tín hiệu 4 - 20mA bằng dây dẫn khoảng cách 1000m, đang định sd 485 nhưng nghe có vẽ ko ổn lắm, sợ nhiễu. tín hiệu thu về cũng là 4-20mA. Ko biết bác nào có cánh hay hơn ko thì giúp mình với! cảm ơn nhiều nhé!

vandungevn 11-10-2007 05:03 PM

Timer có nhiều kiểu chia tần, dùng chia trước và sau (prescale và postscale)
là chia trước và chia sau, có nhiều cách đặt tỉ lệ cho Timer từ 1:1 - 1:256 tức là cách chia này giúp cho ta nhận được xung kích vào Timer sẽ được chậm đi n lần ( 1:n ) so với 1Tcy (Fosc/4), và như vậy ta sẽ được xung kich chậm hơn:
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_4); // 4Mhz => dùng dao động nội, chế độ prescal 1:4 => clock cho Timer0 la Fosc/4/4 = Fosc/16.
Khi này ta có Fosc/4 => Tcy = 1us. Ttimer0 = Fosc/16 => 4us
Timer0 tràn 8 bit => 4x8bit = 1024us.
8 bit có 256 trạng thái chứ không phải 255 trạng thái, do đó x256,

Còn cách thứ 2 Postscale (Only Timer2) thì nó sẽ đếm số lần tràn của Timer2,
Nghĩa là
1:2 - 2 làn tràn cho ra 1 lần xung .....
1:16 - 16 làn Timer2 tràn
giả sử Áp dụng với Timer2 thay Timer0 ở trên và với postscale 1:8 ta sẽ thu được đầu ra là : 4x256x8 = 8192 us

cooloo 12-10-2007 12:59 AM

Trích:

Nguyên văn bởi nhh (Post 2109)
Chương trình này làm nhấp nháy con led ở chân RB0 1s sáng, 1s tắt.
Code:

#include<16F877A.h>
#fuses NOWDT,PUT,HS,NOPROTECT
#use delay(clock=10000000)
main()
{
while(true)
        {
        output_high(PIN_B0);
        delay_ms(1000);
        output_low(PIN_B0);
        delay_ms(1000);
        }
}

Trên đây:
Code:

#include<16F877A.h>
Khai báo con PIC bạn sử dụng, file này chương trình viết sẵn nhằm khai báo các bit, thanh ghi quan trọng trong con pic này.Các bạn có thể vào thư mục cài đặt C:\Program Files\PICC\Devices\16F877A.h để xem nó khai báo được những gì trong đó!
Code:

#fuses NOWDT,PUT,HS,NOPROTECT
Thiết lập các config
Code:

#use delay(clock=10000000)
Khai báo tần số dao động cấp cho PIC
Code:

output_high(PIN_B0)
Xuất ra chân RB0 mức logic 1 (tức 5V), do khi thực hiện hàm này đã bao hàm luôn việc tác động lên thanh ghi TRISB (dùng chọn chân I/O) do vậy ta không cần viết lệnh chọn chân I/O nữa.
Code:

output_low(PIN_B0)
Ngược lại
Code:

delay_ms(1000)
Tạo trễ khoảng thời gian theo mili giây là 1000 (tức 1s)
Chú ý hàm này chỉ có tác dụng khi có khai báo tần số dao động cấp cho PIC

Và bây giờ thử làm cho tất cả 8 led nối với portB chớp tắt 1s xem nào!Phải chăng ta sẽ làm như sau (Viết trong vòng lặp while):
Code:

{
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
output_high(PIN_B3);
output_high(PIN_B4);
output_high(PIN_B5);
output_high(PIN_B6);
output_high(PIN_B7);
delay_ms(1000);
output_low(PIN_B0);
output_low(PIN_B1);
output_low(PIN_B2);
output_low(PIN_B3);
output_low(PIN_B4);
output_low(PIN_B5);
output_low(PIN_B6);
output_low(PIN_B7);
delay_ms(1000);
}

Viết như thế này thì quá dài và thiếu chính xác nữa, có cách nào khác hay hơn không ? Sao ta không xuất đẩy hẳn portB lên mức cao,tạo trễ 1s rồi ép cho nó xuống mức thấp,tạo trễ 1s cùng một lúc nhỉ !
Bài tiếp theo sẽ đưa ra câu trả lời....
http://www.freewebtown.com/nhhao/PIC...201s%20RB0.GIF

Bạn ơi , khi mình compile cái code như trên thì nó báo lỗi warning về thiếu "void" . Mình bỏ thêm : void main(void) vào thì nó mới chạy .
Những function : delay() , rs232(), i2c thì tìm ở đâu vậy ???

thanco112 12-10-2007 02:43 AM

Hỏi về PWM
 
Oe oe, các bác lừa em nhá. Các bác bảo là tập trung mổ xẻ phần PWM làm em đọc mãi hết hai mấy trang mà thấy có mỗi 2 bài liên quan. Bác nào biết về phần này thì chỉ bảo em với ạ.

Em đang có một con step motor 4 dây (đỏ, xám- đen, vàng). Em đang tìm cách điều khiển nó (chạy, dừng, đảo chiều) nhưng mà chưa biết làm thế nào cả. Các bác cho em hỏi:

1. Em dùng 16f877 điều khiển nó có được không?
2. Cần phải có những kiến thức gì để điều khiển nó?

Bác nào có tài liệu về phần này bằng tiếng Việt thì share cho em với ạ.

Em cám ơn các bác ạ!!!!

nhh 12-10-2007 09:01 AM

Tất nhiên dùng 16F877 được, phí phạm nữa là đằng khác.

Tài liệu tiếng Việt về stepper motor, bạn vào phần điều khiển motor trong diễn đàn này tìm.

Stepper motor của bạn nếu công suất bé có thể dùng ULN lái.
Tham khảo điều khiển stepper motor ở đây:http://www.interq.or.jp/japan/se-inoue/e_step.htm
http://www.interq.or.jp/japan/se-ino...ture/step1.jpg

Nguoidumuc204 12-10-2007 09:41 AM

output_high(pin_xx);
output_low (pin_xx);

Hai câu lệnh trên chỉ làm cho chân ra xx là cao hay thấp, ứng với mức logic 1 hoặc 0.trong bài trên ta muốn cho sáng tất một port thì chỉ càn câu lệnh :
Code:

void main (void )
{
  set_tris_b(0);      // cả port B là port ra
  set_tris_c(0);    // cả port C là port ra
  port_b(0x00);    // khởi tạo giá trị đầu port B là 0 ( Tất cả led đều tắt )
  port_c(0x00);  // khởi tạo giá trị đầu port B là 0 ( Tất cả led đều tắt )
  delay_ms(100);
  while(1)
  {
        port_b(0xff); 
        delay_ms(1000);
        port_c(0xff);
        delay_ms(1000);
  } 
}


vandungevn 12-10-2007 06:12 PM

Những function : delay() , rs232(), i2c thì tìm ở đâu vậy ???

bạn xem rõ hơn trong phần help của nó nhé, hoặc tạo new project = PIC Wizard xem trong đó có nói về Những function : delay() , rs232(), i2c ......!

manhckgtcck45 12-10-2007 10:28 PM

Các anh ơi giúp e với. Các anh có thể chỉ cho em cách sử dụng ngắt ngoài để đếm thời gian của sự thay đổi tín hiệu vào port B không?

thongtr 13-10-2007 12:13 AM

1 Attachment(s)
cá pac ơi giúp em!! em bi lỗi gì vậy!

nhh 13-10-2007 09:09 AM

Trích:

Nguyên văn bởi thongtr (Post 12048)
cá pac ơi giúp em!! em bi lỗi gì vậy!

Bạn không nhận thấy chương trình đòi dấu "}" à?

thongtr 13-10-2007 12:52 PM

1 Attachment(s)
mình cũng a thêm đấu } vào rồi nhưng cũng ko có tác dụng!! với lại mình đưa chuột tới đấu } cuối cùng đó thì nó hiện ra màu xanh và nhìn lên trên thì thấy màu xanh đó ứng với đấu { dưới hàm void main(void) !!!
mình cũng ko biết bị chuyện nữa!!

thongtr 13-10-2007 02:04 PM

1 Attachment(s)
Trích:

Nguyên văn bởi thongtr (Post 11866)
Em vừa mới viết xong ct hiển thị LCD 4 bit! có hiệu ứng chữ chạy rất hay!! em post lên cho các pác tham khảo nhé! và góp ý cho em nhé!

#include <16F877A.h>
#include <DEFS_16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#define use_portb_lcd TRUE
#include <lcd.c>
const unsigned char line1[]={'H','E','L','L','O',' ','P','I','C','V','N','!','#'};
const unsigned char line2[]={'Y','H',':','T','H','O','N','G','T','R','0','6', '0','1','@',\
'Y','A','H','O','O','.','C','O','M','#'};

void main(void)
{ while(true)
{
int I=0,y=0,k=0,z=0;
delay_ms(100); // tao tre 100ms cho LCD khoi dong
lcd_init();
lcd_gotoxy(1,1);
while (line1[y]!='#')
{
lcd_putc(line1[y]);
delay_ms(200);
y++;
}
lcd_gotoxy(1,2);
while (i<16)
{
lcd_putc(line2[I]);
i++;
delay_ms(200);
}
i=2;

while (line2[z]!='#')
{
lcd_init();
lcd_gotoxy(1,1);
y=0;
while (line1[y]!='#')
{
lcd_putc(line1[y]);
y++; }

lcd_gotoxy(1,2);
k=i+16;
for(z=i;z<k;z++)
{lcd_putc(line2[z]);}
delay_ms(400);
i++;
}
}
}

Chương trình này minh mô phỏng chạy rồi nhung sao khi cho chạy thực tế khì ko dc!!
Mình đã mắc mạch theo sơ đồ này!! (chỉ có thay thạch anh 20M thôi!)

nhh 13-10-2007 02:05 PM

1 Attachment(s)
Trích:

Nguyên văn bởi thongtr (Post 12063)
mình cũng a thêm đấu } vào rồi nhưng cũng ko có tác dụng!! với lại mình đưa chuột tới đấu } cuối cùng đó thì nó hiện ra màu xanh và nhìn lên trên thì thấy màu xanh đó ứng với đấu { dưới hàm void main(void) !!!
mình cũng ko biết bị chuyện nữa!!

- Bạn thiếu dấu ngoặc kép của line1[].

- Chưa include file lcd.c

- Chú ý phép gán = và phép so sánh bằng ==

Việc chạy mô phỏng đúng ko hẳn thực tế sẽ đúng nhưng chạy mô phỏng sai thì chạy trên mạch thật sai là cái chắc.

ghosttn 13-10-2007 05:21 PM

Xin loi vi chen ngang các anh
 
1 Attachment(s)
Em muon' cho 595 ra 8 bit 1 luc nhung lam mai khong duoc. Em sai ởi chỗ nào
do mới học em chỉ có thể nghĩ đơực như vậy thôi. các anh tối ưu code+ mạch hộ em với.
====================================

#include <16f877a.h>
#use delay(clock=4M)
int8 i;
void input_byte(){
for(i=0;i<=7;i++){
output_bit(pin_B0,0); //1.tao xung cho pin_sck
output_bit(pin_B1,i%=2);//2.dich du lieu vao luc pin_sck o trang thai suon
output_bit(pin_B0,1); //3.ket thuc xung tai pin_sck
}
}
void output_byte(){
output_bit(pin_B2,0); //1.tao xung clock cho pin_rck
delay_ms(100); //2.dung lai de xem
output_bit(pin_B2,1); //3.ket thuc xung tai pin_rck
}

void main(){
set_tris_b(0);
output_bit(pin_B4,0);//khoi dong 595 pin_/OE

while(1){
output_bit(pin_B3,1);//cho phep ghi du lieu pin_MR =1
input_byte();
output_byte();
output_bit(pin_B3,0);//all pin out 595= level low
}//end while
}// end main
==========================

thanco112 14-10-2007 01:12 AM

hỏi về ngắt
 
Các bác cho em hỏi về các loại ngắt của con 16f877 này với ạ. Tên của nó này, chế độ hoạt động của nó như thế nào (khi nào thì ngắt ấy ạ). Em gà, mới nghiên cứu pic, các bác giúp cho!

GLOBAL
INT_RTCC
INT_RB
INT_EXT
INT_AD
INT_TBE
INT_RDA
INT_TIMER1
INT_TIMER2
INT_CCP1
INT_CCP2
INT_SSP
INT_PSP
INT_BUSCOL
INT_EEPROM
INT_TIMER0

Thanks các bác nhiều

vandungevn 22-10-2007 02:45 PM

Hiển thị dùng 595 trên CCS
 
Dưới đây là một chương trình đưa một byte bằng 74hc595 dùng trên CCS

Code:

void display(unsigned char dataout)
{
        unsigned char temp;
        //dataout = 0xa4;
        output_low(pin_c0);
for(i=0;i<8;i++)
{     
        temp = dataout;
        temp = temp&0x80;
        if(temp==0x80)
        {
        output_high(pin_c1);    // Data
        }
        else
        {
        output_low(pin_c1);          // Data
        }
        output_high(pin_c0);        // Clock
        dataout *=2; 
        output_low(pin_c0);        // Clock
}
output_high(pin_c2);                // Latch
output_low(pin_c2);                // Latch
}

chúc bạn thành công.!

Yeu PIC 26-10-2007 07:06 PM

1 Attachment(s)
trong ct mình dùng hai file của bộ compiler: lcd.c và ds1307.c
khi biên dịch thành file .hex thì bị những lỗi về delay như thế này:
Nguyên nhân do đau vậy!

ngoctuan 26-10-2007 10:09 PM

hỏi về counter
 
chào các Bác, Em là thành viên mới , rất mong được chào đón. mong các bác chỉ cho Em về cuonter (Em đang làm đề tài mạch đếm sản phẩm ma chưa hiểu gì về cuonter) mong các bác chỉ dùm em .cám ơn các bác nhiều!

toanck86 03-11-2007 05:14 PM

em cũng muốn hỏi về counter, và cho hỏi đếm xung encoder bằng counter có được không nhỉ, bác nào làm về phần này cho em xin code & đề tài với

tungtot_vl 19-11-2007 03:25 PM

bác nào rành về timer cho em hỏi tí
em thấy các bài timer khi chương trình đã nhảy vào làm việc trong timer thì nó thực hiện lập đi lập lại trong timer mà không thoát ra ngoài. thế nếu em muốn thoát ra khỏi timer để thực hiện các lệnh khác ở ngoài vòng lập while thì làm thế nào hả các bác.
ý em muốn dùng timer như ngắt ngoài vậy các bác ạ. sau khi thực hiện ngắt xong thì thoát ra để thực hiện lệnh kế tiếp.

LeDuc 20-11-2007 03:45 AM

Chế độ ghi dịch cho cổng nối tiếp USART
 
Giúp em với ... em cần tiết kiệm chân của con Pic 887 , nên em muốn dùng cổng nối tiếp để truyền dữ liệu cho con 74LS164 qua 2 chân C6 va C7 của cổng nối tiếp quét 4 con led 7 đoạn , em viết mãi mà không được , mong các anh giúp đỡ .
đây là đoạn code em viết để quét 4 led 7 đoạn qua port D cua con pic ...Mong các anh sửa lại để có thể truyền dữ liệu qua 2 chân C6 va C7 giúp em ..
CODE :
Code:

/
#include <16f887.h>
#include <luutinh.h>

int8 i,a,b,k=0;
int8 so[4],led[]={0,1,2,3,4,5,6,7,8,9},quet[]={128,64,32,16};

#int_rtcc
void quetled()
{
  set_timer0(99);b=a;
  so[0]=a%10;a/=10;
  so[1]=a%10;a/=10;
  so[2]=a%10;a/=10;
  so[3]=a;  a=b;
  portD=(led[so[k]]+quet[k]);
  k++;
  if(k==4)k=0;
}
void xet_nhiet_do()
/*..................*/
void main()
{
  setup_timer_0(rtcc_internal|rtcc_div_128)
  set_timer0(99);
  setup_adc(adc_clock_internal);
  setup_adc_ports(all_analog);
  enable_interrupts(int_rctt);
  enable_interrupts(global):
  trisa=255;
  trisb=trisc=trisd=0;
  while(true)
  {
        if(xet_nhiet_do>31) che_do(1);
//................................
    }

nếu sử dụng cách quét led qua 1 con giai mã 7447 thi phải tốn đến 8 chân pic ở port D , em muốn sử dụng thanh ghi dịch 74ls164 để quét led qua 2 cổng nối tiếp .Nhưng kô biết trong CCS qui đinh code như thế nào cả . Rất mong các anh giúp đỡ ...

tungtot_vl 21-11-2007 10:06 AM

dùng ngắt trên các chân từ rc4 -> rc7 khi chạy thì báo lỗi invalid pri_processor diẻctive.
em thấy trong các ngắt có loại ngắt này nhưng khi khai báo sao nó không hiểu nhỉ.
Code:

#include<16f877a.h>
#fuses NOLVP,NOWDT,PUT,hs,NOPROTECT
#device 16F877*=16 ADC=8
#use delay(clock=20000000)
#use fast_io(a)
#byte porta=0x05
#use fast_io(b)
#byte portb=0x06
#use fast_io(c)
#byte portc=0x07
#use fast_io(d)
#byte portd=0x08
#use fast_io(e)
#byte porte=0x09
#bit ra0 = porta.0
#bit ra1 = porta.1
#bit ra2 = porta.2
#bit rc3 = portc.3
//======================================================
int u,t;
int16 count;
#INT_RC
void interrupt_RC()
{  int8 i,l,x,y;
  portb =0;
  for(i=0;i<24;i++)
      {
        portb = 0xff;       
        delay_ms(1000);
        portb = 0;
        delay_ms(1000);
      }
}



//=====================================================
 void main()
  {

      set_tris_b(0);
      set_tris_a(0);
      set_tris_c(0xff);
      set_tris_e(0);
      set_tris_d(0);
      enable_interrupts(global);
    enable_interrupts(int_RC);
    ext_int_edge(h_TO_l);
    // rc3 = 0;
      while(true)
        {

        }
 }
  //=============================================


namqn 21-11-2007 05:49 PM

Trích:

Nguyên văn bởi tungtot_vl (Post 12964)
dùng ngắt trên các chân từ rc4 -> rc7 khi chạy thì báo lỗi invalid pri_processor diẻctive.
em thấy trong các ngắt có loại ngắt này nhưng khi khai báo sao nó không hiểu nhỉ.
...

Tôi không hề thấy có ngắt trên các chân RC4 đến RC7 trong datasheet của PIC16F877A, mà chỉ thấy có ngắt trên các chân RB4 đến RB7 (port change interrupt). Bạn thấy ngắt trên các chân RC4 đến RC7 ở đâu, có thể cho chúng tôi biết được không?

Thân,

toanck86 21-11-2007 09:13 PM

Bác nào làm về counter rồi cho em ví dụ với. Sao khi khai báo cho timer0 ở chế độ counter rồi cho xung vào chân RA4 thì không thấy gì xảy ra nhỉ:(

namqn 21-11-2007 10:03 PM

Trích:

Nguyên văn bởi toanck86 (Post 12985)
Bác nào làm về counter rồi cho em ví dụ với. Sao khi khai báo cho timer0 ở chế độ counter rồi cho xung vào chân RA4 thì không thấy gì xảy ra nhỉ:(

Bạn muốn chuyện gì sẽ xảy ra? Bạn đã viết code để xử lý nó chưa? Lý do gì khiến bạn cho rằng không có chuyện gì xảy ra?

Thân,

Mr.Bi 01-12-2007 12:57 AM

Code:

#include <16F877A.h>
#include <DEFINE_16F877A.h>
#include <DEFINE_16F87x.h>
#fuses  NOWDT,XT,NOPROTECT,NOLVP,PUT
#use    delay(clock=4000000)

#use standard_io (B)
#use standard_io (A)

#define E            PIN_D0
#define RS          PIN_D1
#define RW          PIN_D2
#define LCD_D4      PIN_D4
#define LCD_D5      PIN_D5
#define LCD_D6      PIN_D6
#define LCD_D7      PIN_D7

#bit CANCEL    =0x05.1 // CANCEL = RA1
#bit OK              =0x05.0 // OK    = RA0

unsigned int8 key[] ; // mang luu cac so da nhap tu ban phim
const unsigned int8 num[11] = {'0','1','2','3','4','5','6','7','8','9'} ;
const unsigned int8 num_ss[11] = {' ','3','9','5','2','6','1','0'} ; // cac so dung de so sanh
unsigned int8 a = 0 ; // bien dem cac so nhap tu ban phim
unsigned int8 b = 0 ; // bien dem so lan sai ma

void LCD_Init ( void );                    // ham khoi tao LCD
void LCD_SetPosition ( unsigned int data );//Thiet lap vi tri con tro
void LCD_PutChar ( unsigned int data );    // Ham viet1kitu/1chuoi len LCD
void LCD_PutCmd ( unsigned int data ) ;    // Ham gui lenh len LCD
void tao_xung_E();                        // Xung kich hoat
void send_to_LCD( unsigned int data);      // Dat du lieu len chan Data

void delay_ms_INT(unsigned long i)
{ unsigned long k , j ;
  for(k=0;k<=i;k++) { for(j=0;j<=i;j++){;} }
}

void LCD_Init ( void )
{
    delay_ms(200); // thoi gian de LCD khoi dong

    output_low(RW);        // RW = 0
    output_low(RS);        // che do gui lenh

    send_to_LCD( 0x00 );
    output_high ( E ); output_low ( E ); delay_ms ( 10 );


    send_to_LCD( 0x03 );  /* init with specific nibbles to start 4-bit mode */
    output_high ( E ); output_low ( E ); delay_ms ( 3 ); // tao xung tren chan E
    output_high ( E ); output_low ( E ); delay_ms ( 3 );
    output_high ( E ); output_low ( E ); delay_ms ( 3 );

    send_to_LCD( 0x02 );  /* set 4-bit interface */
    output_high ( E ); output_low ( E ); delay_ms ( 3 ); // tao xung tren chan E


    LCD_PutCmd ( 0x2C );    /* function set (all lines, 5x7 characters) */
    LCD_PutCmd ( 0x0C);    /* display ON, cursor off, no blink */
    LCD_PutCmd ( 0x06 );    /* entry mode set, increment & scroll left */
    LCD_PutCmd ( 0x01 );    /* clear display */
}

void LCD_SetPosition ( unsigned int data )
{

    send_to_LCD( swap ( data ) | 0x08 );
    output_high ( E ); output_low ( E ); delay_ms ( 3 ); // tao xung tren chan E

    send_to_LCD( swap ( data ) );
    output_high ( E ); output_low ( E ); delay_ms ( 3 ); // tao xung tren chan E

}

void LCD_PutChar ( unsigned int data )
{
    output_high( RS ); //RS = 1
    output_low ( RW ); //RW = 0

    send_to_LCD( swap ( data ) );                        // gui 4 bit cao
    output_high ( E ); output_low ( E ); delay_ms ( 3 ); // tao xung tren chan E

    send_to_LCD( swap ( data ) );                        //gui 4 bit thap
    output_high ( E ); output_low ( E ); delay_ms ( 3 ); // tao xung tren chan E

}

void LCD_PutCmd ( unsigned int data )
{
    output_low(RS); // RS = 0
    output_low(RW); // RW = 0

    send_to_LCD( swap(data) );    // gui 4 bit cao
    output_high (E); output_low (E); delay_ms (3);

    send_to_LCD( swap(data) );    // gui 4 bit thap
    output_high (E); output_low (E); delay_ms ( 3 );
}


void send_to_LCD( unsigned int data )
{
    output_bit ( LCD_D4, data & 0x01 );
    output_bit ( LCD_D5, data & 0x02 );
    output_bit ( LCD_D6, data & 0x04 );
    output_bit ( LCD_D7, data & 0x08 );
}

void quetphim_hienthi()
{ PORTB = 0b111111110 ; if (RB4==0) { delay_ms_INT(50);           
                                      while(RB4==0) continue ;
                                      delay_ms_INT(20);
                                      LCD_PutChar('0') ; key[a++] = num[0];
                                    } ;
                        if (RB5==0) { delay_ms_INT(50);           
                                      while(RB5==0) continue ;
                                      delay_ms_INT(20);
                                      LCD_PutChar('3') ; key[a++] = num[3];
                                    } ;
                        if (RB6==0) { delay_ms_INT(50);           
                                      while(RB6==0) continue ;
                                      delay_ms_INT(20);
                                      LCD_PutChar('6') ; key[a++] = num[6];
                                    } ;
                        if (RB7==0) { delay_ms_INT(50);           
                                      while(RB7==0) continue ;
                                      delay_ms_INT(20);
                                      LCD_PutChar('9') ; key[a++] = num[9];
                                    } ;

  PORTB = 0b111111101 ; if (RB4==0) { delay_ms_INT(50);           
                                      while(RB4==0) continue ;
                                      delay_ms_INT(20);
                                      LCD_PutChar('1') ; key[a++] = num[1];
                                    } ;
                        if (RB5==0) { delay_ms_INT(50);           
                                      while(RB5==0) continue ;
                                      delay_ms_INT(20);
                                      LCD_PutChar('4') ; key[a++] = num[4];
                                    } ;
                        if (RB6==0) { delay_ms_INT(50);           
                                      while(RB6==0) continue ;
                                      delay_ms_INT(20);
                                      LCD_PutChar('7') ; key[a++] = num[7];
                                    } ;
  PORTB = 0b111111011 ; if (RB4==0) { delay_ms_INT(50);           
                                      while(RB4==0) continue ;
                                      delay_ms_INT(20);
                                      LCD_PutChar('2') ; key[a++] = num[2];
                                    } ;
                        if (RB5==0) { delay_ms_INT(50);           
                                      while(RB5==0) continue ;
                                      delay_ms_INT(20);
                                      LCD_PutChar('5') ; key[a++] = num[5];
                                    } ;
                        if (RB6==0) { delay_ms_INT(50);           
                                      while(RB6==0) continue ;
                                      delay_ms_INT(20);
                                      LCD_PutChar('8') ; key[a++] = num[8];
                                    } ;

}

#int_RB
void ngat_RB(void)
{ LCD_PutCmd(0x83); // dong1 cot 5
  while (OK && CANCEL) quetphim_hienthi(); // nut OK chua dc nhan

  if(CANCEL==0) {delay_ms_INT(20);            // nhan OK
                while(CANCEL==0) continue ;
                delay_ms_INT(20);
                goto THOAT ; };

  if(OK==0 ) {delay_ms_INT(20);            // nhan OK
              while(OK==0) continue ;
              delay_ms_INT(20);
              if (a==7)
                    {
                        if(key[1]!=num_ss[1]) {goto HERE ;};
                        if(key[2]!=num_ss[2]) {goto HERE ;};
                        if(key[3]!=num_ss[3]) {goto HERE ;};
                        if(key[4]!=num_ss[4]) {goto HERE ;};
                        if(key[5]!=num_ss[5]) {goto HERE ;};
                        if(key[6]!=num_ss[6]) {goto HERE ;};
                        if(key[7]!=num_ss[7]) {goto HERE ;};
                        LCD_PutCmd(0x01);
                        LCD_PutCmd(0x84);
                        LCD_PutChar('Y') ;
                        LCD_PutChar('E') ;
                        LCD_PutChar('S') ;
                        delay_ms(2000) ;
                       
          HERE :
                        LCD_PutCmd(0x01);
                        LCD_PutCmd(0x84);
                        LCD_PutChar('W') ;
                        LCD_PutChar('r') ;
                        LCD_PutChar('o') ;
                        LCD_PutChar('n') ;
                        LCD_PutChar('g') ;
                        LCD_PutChar('!') ;
                        b++;  // dem so lan sai ma
                      } ;
              if (a!=7){ LCD_PutCmd(0x01);
                          LCD_PutCmd(0x84);
                          LCD_PutChar('W') ;
                          LCD_PutChar('r') ;
                          LCD_PutChar('o') ;
                          LCD_PutChar('n') ;
                          LCD_PutChar('g') ;
                          LCD_PutChar('!') ;
                          b++; // dem so lan sai ma
                          delay_ms(2000) ;
                        } ;

              } ;
  THOAT :
  LCD_PutCmd(0x01);
  LCD_PutCmd(0xC4);
  LCD_PutChar('R') ;
  LCD_PutChar('e') ;
  LCD_PutChar('a') ;
  LCD_PutChar('d') ;
  LCD_PutChar('y') ;
  LCD_PutChar('!') ;

  RBIF = 0 ;
}


void main()
{ set_tris_A(0xFF); PORTA = 0xFF ;
  set_tris_B(0xF0); PORTB = 0xF0 ;
  set_tris_C(0x00); PORTC = 0;
  set_tris_D(0x00);

  LCD_Init(); // khoi tao LCD

  enable_interrupts(global);
  enable_interrupts(int_RB);
  ext_int_edge(H_to_L);

  LCD_PutCmd(0xC4);
  LCD_PutChar('R') ;
  LCD_PutChar('e') ;
  LCD_PutChar('a') ;
  LCD_PutChar('d') ;
  LCD_PutChar('y') ;
  LCD_PutChar('!') ;

  while(1) ;
}

cho em hỏi chút xíu !
- em khai báo biến đếm a toàn cục , như trên code
- ý định của em : mỗi lần nhấn phím thì mảng key[] sẽ tự nạp số vào & nạp theo thứ tự , vì vậy , sau mỗi lần nhấn phím , em cho key[a++]
- nhưng ko hiểu sao , cứ mỗi lần nhấn đúng mã số "3952610", thì ct cứ nhảy tới label HERE .. em nghi ngờ ngay chỗ so sánh mảng key[] và num_ss[] ;
- chắc chắn key[] có giá trị ko đúng như các số mình đã nhấn !
các anh thấy em phân tích vậy có đúng ko ?
- thứ nữa : sau mỗi lần chạy hết ct ngắt thì ko bit ct có thoát khỏi ngắt hay ko ? nhưng em nhấn phím trở lại thì LCD ko chịu hiện số nữa , chỉ khi nhấn từ 3 lần trở lên thì số mới hiện trở lại . LCD lúc ấy đang bận ? nhưng nó có làm gì đâu . Đến nhãn THOAT , chỉ việc hiện " Ready!" lên thui mà . Có lẽ tới chỗ này ct bị treo !?

Mr.Bi 03-12-2007 12:09 AM

uhm ! rùi .. cuối cùng mình cũng tìm ra lỗi .
- Đúng là ngay chỗ so sánh key[] & num_ss[] ấy !
phải là :
Code:


          if (key[0] != num_ss[1]) { goto HERE1 ; ) ;
          if (key[1] != num_ss[2]) { goto HERE1 ; ) ;
        .....

vì sao vậy ? mình đã bit ..nhưng có lẽ để các bạn mắc phải lỗi ngớ ngẩn như mình & tìm ra lời giải thì sẽ nhớ lâu hơn !
Còn cái chỗ : sau khi hết ct ngắt ,ct vẫn ko chịu thoát ra ngoài main() & đứng đợi while(1) ; cụ thể là khi bấm nút .. LCD vẫn ko hiển thị.. sau 3 lần nhấn só mới bắt đầu hiển thị --> mình vẫn chưa tìm đc nguyên nhân .! sẽ cố gắng chữa lỗi tiếp

lyha 22-12-2007 11:06 PM

các bác chỉ em cách tính step size với.

thongtr 30-12-2007 10:02 AM

các pác chỉ cho mình với! mình đang làm với con lm335 nhưng sao nhiệt độ của nó không có ổn định tới chênh lệch nhau tới 4 độ. các bác có cách gì chỉ cho mình với! mình đang dùng con 16F877a

Sangcao 31-12-2007 12:55 PM

lm35 để đo nhiệt độ cho vui thôi.phụ thuộc vào nhiều vấn đề, ko chỉ là do con lm35, AD của PIC, thuât toán của bạn.Bọn TQ nó thường dùng thuật toán tra bảng. nếu cần chính xác, ổn định thì bạn nên lhệ bác Cường Quay , mình ko nhớ là con gì, giá khoảng 40$ thì phải. bảo đảm ok luôn!

bean984 02-01-2008 10:28 AM

các bác cho em hỏi: làm thế nào để biết con slave đã nhận xong chuỗi ký tự? e dùng rs232 để truyền nhận giữa 2 con pic.
em cũng thử dùng hàm itoa để chuyển số int sang chuỗi và dùng hàm printf để truyền.
bên nhận em dùng hàm atol để chuyển chuỗi về dạng int16 rồi hiể thị. nhưng kết quả hiển thị lại không chính xác. cụ thể là sau chuỗi số là các ký tự lạ.
bác nào đã làm vấn đề này rồi xin chỉ giáo giúp em.
nếu có code thì tốt quá

picthanh 08-01-2008 11:46 PM

cộng ký tự thành chuỗi
 
các bác cho em hỏi trong CCS mình muốn cộng các ký tự riêng lẻ thành một chuỗi ký tự thì dùng lệnh gì? bài toán của em cụ thể như sau:dùng ma trận phím 4x3 để nhập các ký tự từ 0-9 sau đó cộng các ký tự này lại thành một chuỗi.Sau đó hiển thị chuỗi này lên LCD nhưng em làm hoài mà nó cũng không chạy, khi dịch chương trình thì cũng không thấy báo lỗi gì cả.Em đã thử cho hiện từng ký tự thì chương trình chạy rất ok! nhưng khi cộng các ký tự lai bằng lệnh "key=key+k;" thi ko chạy được.
em dùng con 16F877A ,thạch anh 20MHz

Code:

#include "D:\PIC PROGRAM\dk.h"
#include <KBD.C>
#include <lcd.c>

char k,*key;
void main()
{

  port_b_pullups(TRUE);
  setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
  setup_psp(PSP_DISABLED);
  setup_spi(FALSE);
  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  setup_timer_1(T1_DISABLED);
  setup_timer_2(T2_DISABLED,0,1);
  setup_comparator(NC_NC_NC_NC);
  setup_vref(FALSE);
  kbd_init();
  lcd_init();

lcd_putc('\f');
key=0;
while(1)
  {
      k=0;
      k=kbd_getc();
      key=key+k;    //lenh nay hinh nhu sai
          if(k!=0)
            {
                lcd_gotoxy(1,1);
                lcd_putc(key);
            }
    }
}

mong các cao thủ ra tay giúp đỡ !


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