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)

sphinx9 09-08-2007 04:12 AM

mấy anh cho em hỏi xíu ạ tại seo khi em xài các lệnh
trisb=0;
rb0=1;
rb1=1;
rb2=1;
rb3=1;
hoặc các lệnh:
output_high(pin_b0);
output_high(pin_b1);
output_high(pin_b2);
output_hgh(pin_b3);
mà nếu em gắn ở các chân đó là led thì nó sáng lần lược ở rb0 rb1 rb2 rb3 chứ nó ko sáng ở cả 4 chân bật debug của protus lên thì
trisb=0b11110000 : cái này thì đúng rùi
portb=0b00001000 : còn cái này seo kì wá
nhưng nếu em lắp vào đó dộng cơ thì lại khác em lắp vào rb0 động cơ ocn2 mấy cái kia là led thì động cơ way led ở rb3 sáng còn ở rb1 rb2 tắt
nhưng nếu em xài lệnh
portb=0b00001111; thì nó lại sáng bình thường
mấy anh giải thích giùm em với
cám ơn

dvnccbmacbt 12-08-2007 12:09 AM

Chào mọi người! Em có 1 thắc mắc muốn hỏi : Với ngắt RB4-7 thì dòng lệnh ext_int_edge( H_to_L ) hình như không có tác dụng. Em thử bỏ hoặc thay thế bằng ( L_to_H ) thì thấy không có thay đổi gì. Hình như mặc định là H_to_L . Em có đọc trong datasheet PIC18f4550 thì chỉ thấy nói đến chọn cạnh lên xuống ở ngắt ngoài RB0, còn ở RB4-7 thì không thấy nói rõ. Em không hiểu rõ chỗ này. Mong mọi người chỉ bảo.

cuopbienquin 15-08-2007 05:05 PM

Mình mới học về PIC.Cho hỏi ADC module có chức năng gì,công dụng ntn trên PIC? Mình nghĩ cho một điện thế analog thì nó xuất ra tín hiệu digital.Mình đã có đọc đoạn code này nhưng chưa hiểu rõ :
Code:

#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#device 16F877*=16 ADC=8
#use delay(clock=10000000)
Int8 adc;
main()
{
setup_adc(adc_clock_internal);
setup_adc_ports(AN0);
set_adc_channel(0);
delay_ms(10);
while(true)
{
adc=read_adc();
output_B(adc);
}
}

Bạn nào đã đi trước thì giải thích giùm mình nhé,mình cần luôn file mô phỏng proteuss để hiểu rõ hơn.Cám ơn nhiều.Chúc vui.

thaithienanh 15-08-2007 11:15 PM

Ui sao hông có anh nào replay luồng này hết vậy
 
1 Attachment(s)
To @c828 : việc quét 2 led rất đơn giản, chắc là do bạn chưa nắm đuợc quét led là gì rồi, bây giờ mình sẽ cho bạn một ví dụ cơ bản nhất về quét led (có kèm file Proteus và notepad), sau đó thì bạn nghiền ngẫm code khoảng vài phút chắc sẽ hiểu thui :)

To @sphinx9 : Cách diễn giải câu hỏi của bạn hơi khó hiểu một chút nhưng mình cũng loáng thoáng hiểu đuợc và xin trả lời là : đó là điểm yếu của Proteus nên không cần thắc mắc và cũng không thể giải thích :o (mình nói thật đó đừng nghe giọng văn trả lời cụt ngủn mà hiểu lầm nhá :D )

To @dvnccbmacbt : Ngắt RB dùng để ghi nhận sự kiện "có sự thay đổi bất kỳ" trên các chân từ RB4 đến RB7 cho nên việc chọn sườn ngắt không có vai trò ý nghĩa ở đây :o

To @cuopbienquin : ADC = Analog Digital Convert như vậy ý nghĩa của nó là một bộ chuyển đổi từ tín hiệu "tương tự" sang giá trị "số" tương ứng. Tuỳ vào việc lựa chọn điện áp tham chiếu và độ phân giải mà giá trị cho ra sẽ khác, ví dụ khi ta lựa chọn là ADC=8 và Vref = 5V thì khi đó nếu tín hiệu đưa vào bộ ADC là 5V thì giá trị số trả ra là 11111111 (8bit) = 255, công thức tổng quát lúc này sẽ là :
Value (giá trị "số") = 255 (max value của 8 bit) * X (tín hiệu đưa vào) / 5 (Vref)
Bạn tham khảo thêm tại bài trước nhá link đây :
http://www.picvietnam.com/forum//sho...?t=357&page=17

cuopbienquin 17-08-2007 04:45 PM

PWm là bộ điều chế đọ rộng xung.Mình đang tìm hiểu cái module này nó hoạt độnh ntn?Mình đã đọc tổng quan về nó là dùng để điều khiển động cơ như tốc độ,tần số..
Mình muốn hiểu rõ hơn cấu trúc mạch ntn trong VDK PIC,kết nối với động cơ ra sao.BẠn nào đã tìm hiểu rồi thì hướng dẫn gíp mình nha.Mình đang rất cần.Chúc vui

huybo02 18-08-2007 09:57 AM

Trích:

Nguyên văn bởi cuopbienquin (Post 10727)
Mình mới học về PIC.Cho hỏi ADC module có chức năng gì,công dụng ntn trên PIC? Mình nghĩ cho một điện thế analog thì nó xuất ra tín hiệu digital.Mình đã có đọc đoạn code này nhưng chưa hiểu rõ :
Code:

#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#device 16F877*=16 ADC=8
#use delay(clock=10000000)
Int8 adc;
main()
{
setup_adc(adc_clock_internal);
setup_adc_ports(AN0);
set_adc_channel(0);
delay_ms(10);
while(true)
{
adc=read_adc();
output_B(adc);
}
}

Bạn nào đã đi trước thì giải thích giùm mình nhé,mình cần luôn file mô phỏng proteuss để hiểu rõ hơn.Cám ơn nhiều.Chúc vui.

ADC là chức năng chuyển đổi tín hiệu analog -> digital (Analog Digital Converter). Nó dùng 1 điện áp để so sánh (Vref) tùy độ phân giải mà điện áp này được chia là nhiểu mức khác nhau (2^n) với 16F877A ADC 10 bit tức Vref dc chia thành 2^10 = 1024 mức. Mỗi mức ADC cách nhau tương ứng với Vref/số mức. Vref = 5V thì mỗi mức ADC của 16F877 ứng với 5V/1024 = 4.88mV. Điện áp trên cổng AN sẽ được so sánh để ra được mức ADC tương ứng. 0V ứng với ADC =0, 4.88mV ứng với ADC =1...Kết quả được chứa trong 2 thanh ghi ADRESH:ADRESL.
Còn mạch cho code trên thì bạn mắc 1 cầu chia áp để đưa điện áp vào chân AN0 là được. Dùng biến trở cho gọn.
Còn PWM thì bạn đọc trong datasheet đó chương 8 phần CAPTURE/COMPARE/PWM MODULES và xem thêm bên ứng dụng điều khiển PID cho động cơ DC.

anh_gioi 21-08-2007 08:38 PM

[QUOTE][QUOTE]

cho em hỏi] về đo nhiệt độ dùng pic 16f877A với ạ.code này em copy của anh linhnc308.nhưng về lắp vẫn chưa chay.trong code nó bị báo lỗi
[QUOTE] // trisa = 0xFF;
// trisb = 0x01;
// trisd = 0x00;[QUOTE]
em nghĩ là nó khai báo cho cổng ra vào nên em đã thay nó bằng :
set_tris_a(0xff);
set_tris_b(0x01);
set_tris_d(0x00);
thế là nó hết báo lỗi,nhưng vẫn ko đc.em đã lắp mạch thật cho nó nhưng nó vẫn im lìm ko báo biếc gì cả(bứ lắm cơ!)
các anh cho em lời khuyên với.
note: đây là mạch và code em mượn của anh linhnc308,mong anh cố gắng giúp cho kẻ ngốc nghếch này.em đã lắp mạch đúng,và mặc dù em đã lấy file hex của anh nạp vào mà nó vẫn im lìm ạ,

anh_gioi 21-08-2007 08:44 PM

sao ko post file từ máy tính đc nhỉ? thui khi khác post sau vậy.lại vẫn dậm chân 1 chỗ.chán thật

cuopbienquin 22-08-2007 06:18 PM

Trích:

Nguyên văn bởi nhh (Post 2234)
Đây là chương trình dùng ngắt Timer0 định thì 1s.
Đầu tiên led ở chân RB0 sáng, sau 1s sẽ dịch sang trái, nghĩa là led 1 trên chân RB1 sáng , lần lượt như vậy cho các led trên portB và lặp lại mãi mãi.
Code:

//****************************************************
// Author  : nhh
// Date    : 02/04/06
// Hardware: PIC16F877A
//****************************************************
#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(b)
#byte portb=0x06
#define led pin_B0
int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void interrupt_timer0()
{
set_timer0(6);
++count;
if(count==2000)
  {
count=0;
a=a<<1;  // dich trai a 1bit
  }
if(a==256)
  {
a=1;
count=0;
  }
}
//Chuong trinh chinh
main()
{
set_tris_b(0);
enable_interrupts(global);
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
set_timer0(6);
count=0;
a=1;
while(true)
  {
portb=a;
  }
}

http://www.freewebtown.com/nhhao/PIC/Nhay LED PortB.GIF

Mình đang học về Timer .Theo bài này thì khi với thạch anh 4Mhz thì thời gian cho mồi dòng lệnh là 100us hay sau 100us thì timer sẽ báo tràn và quay trở lại 0. Có phải biến count là gán cho "mỗi dòng lệnh",nghĩa là khi count=2000 <=>delay 2000x100us= 20s chứ không phải 1s.
Tiếp theo ,về vấn đề thanh ghi pres_scaler ,mình không hiểu chế độ div _2,div_ 4 ảnh hưởng thề nào tới thời gian thực thi mỗi dòng lệnh,timer làm việc ra sao???Mình cũng có đọc chế độ hoạt động và xem block diagram mà chả hiểu gì cả.Mong các bạn giúp đỡ.Chúc vui

dtdat1909 28-08-2007 09:34 PM

không phải như bạn nghĩ đâu. mad thời gian định thời được tính theo công thức:
t=4*256*prescaler/Fosc
ở đây 4 hình như là số chu kỳ trong một lệnh đếm
prescaler là tỷ lệ mà ta quy định cho Timer, nó được xem là clock cho timer khi timer đếm(tần số dùng để đếm cho Timer bằng OSC/prescaler).
Fosc là tần số xung clock cung cấp cho mạch.
khi viết rtcc_div_2 có nghĩa là: tần số cung cấp cho bộ đếm Timer0 bằng
Fosc/2.

cuopbienquin 29-08-2007 09:16 PM

Đây là mã code mình viết ngắt đơn giản cho LCD.Khi nhấn button 1(RB4) thì LCD hiển thị chữ 'X' dòng 1,button 2 thì LCD hiển thị dòng 2 chữ 'K'.Nhưng khi chạy thì nó bào lỗi ở dòng "void main(void)" là 'A numeric expression must be here'

Code:

=============================================================================*/
#include <16F877A.h>
#include <DEFS_16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#define RS  RD0
#define RW  RD1
#define E  RD2
#define LCD PORTC
/*Ham yeu cau goi lenh dieu khien LCD*/
void comnwrt(void)
{
 RS = 0;
 RW = 0;
 E  = 1;
 E  = 0;
 delay_ms(1);
}
/*Ham yeu cau goi du lieu hien thi len LCD*/
void datawrt(void)
{
 RS = 1;
 RW = 0;
 E  = 1;
 E  = 0;
 delay_ms(1);
}
#int_RB
 void ngat_RB(void)
 {
  if(RBIE && RBIF)
    {
    if (RB4==0)
      {
      while(RB5==1)
      {
        LCD = 0x83;
        comnwrt();
        LCD = 'X';
        datawrt();
       
      }
      }
    if (RB5==0)
      {
      while(RB4==1)
      {
        LCD = 0xC3;
        comnwrt();
        LCD = 'K';
        datawrt();
       
      }
      }
    }
 
  void main(void)
    {
    set_tris_b(0b01100000);
    set_tris_c(0);
    set_tris_d(0);
    LCD = 0x38;      //  Hai hang, ma tran dot 5*7, 8 bit interface
    comnwrt();
    LCD = 0x0C;      //  Bat hien thi, tat con tro
    comnwrt();
      while(true)
      {
      }
    }


namqn 29-08-2007 11:56 PM

Khi chạy chương trình đó bạn nhận được thông báo lỗi đó? Thông báo lỗi đó xuất hiện ở đâu?

Nếu bạn chạy chương trình với phần cứng của bạn theo cách thông thường, chỉ có bộ vi điều khiển và LCD, bộ phận hiển thị duy nhất mà bạn có là màn hình LCD, làm cách nào bạn nhận được thông báo lỗi đó, khi LCD chưa hoạt động đúng.

Tôi đoán là bạn muốn nói khi biên dịch chương trình thì nhận được thông báo lỗi đó. Bạn xem thử các ví dụ mẫu của CCS C để biết người ta khai báo main() ra sao. Bạn cũng kiểm tra lại code xử lý ngắt RB của bạn, dường như bạn đang thiếu một dấu '}'.

Thân,

thaithienanh 30-08-2007 12:55 AM

Tội nặng, nặng tội
 
Bạn phạm phải trọng tội rùi chắc hình phạt phải là "tử hình" thui đó mà :D

Lỗi của bạn là thiếu một dấu móc khoá "}" ở cuối hàm, ngay trên void main ấy thêm vào là OK :D

Lần này tha lần sau là tử hình thiệt đó nghen :D .
Thân.

cuopbienquin 30-08-2007 12:42 PM

Cám ơn các bạn nhiều,mình đã biết sai rồi.Nhưng khi mô phỏng bằng Proteuss thì không như ý muốn,LCD cứ lặng thinh.Đây là mạch mô phỏng
http://i190.photobucket.com/albums/z...ieu/NEWLCD.jpg
code:#include <16F877A.h>
#include <DEFS_16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#define RS RD0
#define RW RD1
#define E RD2
#define LCD PORTC
/*Ham yeu cau goi lenh dieu khien LCD*/
void comnwrt(void)
{
RS = 0;
RW = 0;
E = 1;
E = 0;
delay_ms(1);
}
/*Ham yeu cau goi du lieu hien thi len LCD*/
void datawrt(void)
{
RS = 1;
RW = 0;
E = 1;
E = 0;
delay_ms(1);
}
#int_RB
void ngat_RB(void)
{
if(RBIE && RBIF)
{
if (RB4==0)
{
while(RB5==1)
{
LCD = 0x83;
comnwrt();
LCD = 'X';
datawrt();

}
}
if (RB5==0)
{
while(RB4==1)
{
LCD = 0xC3;
comnwrt();
LCD = 'K';
datawrt();

}
}
}
}

void main(void)
{
set_tris_b(0b00110000);
set_tris_c(0);
set_tris_d(0);
LCD = 0x38; // Hai hang, ma tran dot 5*7, 8 bit interface
comnwrt();
LCD = 0x0C; // Bat hien thi, tat con tro
comnwrt();
while(true)
{
}
}

Mình làm mạch này chủ yếu để hiểu cơ bản và tiếp tục làm phần kết hợp keypadphone và LCD ,mạch nhu cầu như sau
http://i190.photobucket.com/albums/z...eu/LCDkey2.jpg
Mình cần :nhấn phím trên keypad thì LCD sẽ hiển thị trên LCD và khi nhấn button thì nó xóa một ký tự hiển thị .Mình có tham khảo source code trong CCS nhưng chả biết dùng như thế nào,đây là code ứng dụng:
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)



#include <lcd.c>
#include <kbd.c>


void main() {
char k;

lcd_init();
kbd_init();

lcd_putc("\fReady...\n");

while (TRUE) {
k=kbd_getc();
if(k!=0)
if(k=='*')
lcd_putc('\f');
else
lcd_putc(k);
}
}

cuopbienquin 31-08-2007 11:13 AM

Xin lỗi mình pót bài này mà không thấy bác nào trả lời giùm .Có lẽ do nhiều luồng mới quá nên các bác không để ý.Hôm nay mình post lại vậy.Mình có cuốn Interfacing PIC nhưng viết bằng ASM,mà mình thì đang cần C.Không biết bác nào có sách Interfacing PICmaf viết bằng C khồng nhỉ?

thaithienanh 31-08-2007 09:36 PM

Bạn Cướp biển chuẩn bị chạy trước đi nhé, mình đã "lắp đạn vào súng" rùi đây này :cool:

Do bạn phạm các tội sau :
- Chưa khai báo cho phép ngắt RB ở void main : phải thêm vào đó 2 dòng : enable_interrupts(global);
enable_interrupts(int_RB);
- Ở trên mạch ứng dụng chẳng thấy điện trở treo lên nguồn đâu nữa

Tài liệu thì mình không có và rất ít đọc (do lười :p )

Nhưng góp ý thế này : muốn học từ Sample của CCS thì phải :

Bạn mở code cái Driver mà CCS hỗ trợ lên, đọc kỹ định nghĩa của các hàm mà Driver hỗ trợ (để khi dùng thì gọi ra trong chương trình), xem Driver đó sử dụng những chân nào của VDK, nối đúng chân mà dùng :)

cuopbienquin 31-08-2007 11:55 PM

chà mình đã chuẩn bị chạy rồi .mình biết sau khi mình post bài mình đã thiếu yêu cầu như bạn comment và vẽ lại mạch mô phỏng như bạn nhắc nhở.Nhưng vẫn cứ lặng thinh.Mong bạn và các bạn trong diễn đàn chạy thử lại và test giùm mình như bạn đã nói,và cùng correct lại mạch và code như yêu cầu mình mong muốn xem sao.Còn về ứng dụng trong CCS ,rất phức tạp.Mình muốn tự mình lập trình theo yêu cầu ,post code xem mình sai đúng chỗ nào,để sữa lỗi và tiện học hỏi luôn như vạy dễ hiểu hơn.Mong các bạn thông cảm .Chúc vui

thaithienanh 01-09-2007 12:24 AM

1 Attachment(s)
Đã test lại giúp bạn, tất cả đều ổn, mình gửi luôn cái hình để bạn xem lại, còn về code mình chỉ thêm đúng vào 2 câu mà mình đã nói ở trên :)

cuopbienquin 01-09-2007 05:02 PM

1 Attachment(s)
Mình thật sự cảm ơn bạn thaithienthanh rất nhiều về vấn đề này.Mình đã làm lại và chạy ngon lành.Nhưng để thực tế hơn mình đã làm một cái keypadcalulate thay cho mấy cái button .Mạch như sau:
http://i190.photobucket.com/albums/z...hdieu/LCD3.jpg
Code:#include <16F877A.h>
#include <DEFS_16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#define RS RD0
#define RW RD1
#define E RD2
#define LCD PORTC
/*Ham yeu cau goi lenh dieu khien LCD*/
void comnwrt(void)
{
RS = 0;
RW = 0;
E = 1;
E = 0;
delay_ms(1);
}
/*Ham yeu cau goi du lieu hien thi len LCD*/
void datawrt(void)
{
RS = 1;
RW = 0;
E = 1;
E = 0;
delay_ms(1);
}
#int_RB
void ngat_RB(void)
{
if(RBIE && RBIF)
{
//hang A
if ((RB0) && (RB4))
{
LCD = '7';
datawrt();


}
if (RB0 && RB5)
{

LCD = '8';
datawrt();


}
if (RB0 && RB6)
{

LCD = '9';
datawrt();


}
if (RB0 && RB7)
{

LCD = ':';
datawrt();


}
//Hang B
if ((RB1) && (RB4))
{
LCD = '4';
datawrt();


}
if (RB1 && RB5)
{

LCD = '5';
datawrt();


}
if (RB1 && RB6)
{

LCD = '6';
datawrt();


}
if (RB1 && RB7)
{

LCD = 'x';
datawrt();


}
//Hang C
if ((RB2) && (RB4))
{
LCD = '1';
datawrt();


}
if (RB2 && RB5)
{

LCD = '2';
datawrt();


}
if (RB2 && RB6)
{

LCD = '3';
datawrt();


}
if (RB2 && RB7)
{

LCD = '-';
datawrt();


}
//Hang D
if ((RB3) && (RB4))
{
LCD = 0x0C;
comnwrt();


}
if (RB3 && RB5)
{

LCD = '0';
datawrt();


}
if (RB3 && RB6)
{

LCD = '=';
datawrt();


}
if (RB3 && RB7)
{

LCD = '-';
datawrt();


}

}
}

void main(void)
{
set_tris_b(0b00001111);
set_tris_c(0);
set_tris_d(0);
portb=0;
portc=0;
portd=0;

enable_interrupts(global);
enable_interrupts(int_RB);
ext_int_edge(H_TO_L);
LCD = 0x38; // Hai hang, ma tran dot 5*7, 8 bit interface
comnwrt();
LCD = 0x0C; // Bat hien thi, tat con tro
comnwrt();

while(true)
{
}
}
Khi compile thì chương trình dịc ok nhưng khi mô phỏng mình lại thấy LCD tiếp tục đứng im .Hee, mong các bạn tiếp tục giúp đỡ cho trọn vẹn nha.
Mình làm về project này là để làm một cái smallcal có dạng như trên hình vẽ, mình cùng đang tìm hiểu thuật toán của nó,đây là thuật toán trong sách Interfacing PIC về các phép tình đơn giản:
Calculate result
IF key = ‘+’, Add
IF key = ‘-‘, Subtract
IF key = ‘x’, Multiply
IF key = ‘/’, Divide
Add Add Num1 + Num2
Load result, CALL Two digits
Subtract Subtract Num1 – Num2
IF result negative, load minus sign, CALL Display character
Load result, CALL Display character
Multiply
REPEAT
Add Num1 to Result
Decrement Num2
UNTIL Num2= 0
Load result, CALL Two digits
Divide
REPEAT
Subtract Num2 from Num1
Increment Result
UNTIL Num1 negative
Add Num2 back onto Num1 for Remainder
Load Result, CALL Display character
Load Remainder, CALL Display character
Two digits
Divide result by 10, load MSD, CALL Display character
Load LSD, CALL Display character
Mình viết bằng ASM thì được chứ còn CCS thì non tay lắm .Mong các bạn giúp đỡ mình hoàn thành project này.Cảm ơn nhiều.Chúc vui.

cuopbienquin 05-09-2007 11:26 AM

Đã lâu rồi mà không thấy các bác trả lời giùm nhỉ.mình sốt ruột quá

Mr.Bi 11-09-2007 06:49 PM

Chả có gì là im re hết bạn ah ! nó vẫn chạy đấy nhưng bạn ko nhìn thấy thui ! Lý do : chân Vss của LCD bạn đã mắc luôn vào Mass , mình chưa thử kiểu mới này nhưng .. mình đoán nó sáng ngời hoặc túi thui luôn . Nhà sx đưa cho ta chân Vss là để chỉnh độ sáng của LCD . BẠn phải mắc 1 con trở tinh chỉnh cỡ 5k vào đó , sau đó chỉnh độ sáng yếu đi thì mới thấy kí tự hiển thị đc chứ ! ĐÚng ko ?

cuopbienquin 11-09-2007 10:11 PM

thế ah,nhưng mình sữa lại như bạn nói mà không sáng.Vậy bạn có thể test giùm mình không?

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

Đừng nôn nóng : Bạn đang đi đúng hướng đấy , Không phải xoay vài 3 vòng là thấy ngay đâu ? Tui xoay phải cỡ 7 vòng cơ đấy . Xoay kiểm tra theo 2 chiều . Cứ coppy nguyên code hiển thị LCD vào , sau đó chỉnh độ sáng của LCD chắc chắn bạn sẽ thấy Kí tự . Tui cũng điên đầu cho cái LCD này cả buổi tối đó .

thaithienanh 12-09-2007 07:49 PM

Hix hix
 
2 Attachment(s)
Hix hix nghe hai bạn trao đổi với nhau mà đâu óc mình lùng bùng quá giờ mình hết hiểu gì hết luôn rồi :confused: . VSS nối với nguồn âm thì quá đúng rùi đâu có gì sai đâu :confused: , còn chân VEE thì ở một số LCD ta thấy nó còn có tên khác là V0 : chân này có tác dụng là điều chỉnh độ tương phản trên LCD, vì vậy ở chân này nguời ta thường đấu vào đó một biến trở để điều chỉnh điện áp, dao động trong khoảng từ 0 --> 5V, trong lúc test có thể đấu trực tiếp xuống nguồn âm cũng đuợc :o .

Còn về phần lý do tại sao cái LCD của bạn không hiển thị là do cà hai lỗi thiết kế phần cứng và phần mềm luôn :D , cụ thể ở đây là về cách quét phím : Như mình nhận thấy ý đồ của bạn ở đây là set PortB từ chân RB0 --> RB3 là ngõ ra, còn lại là ngõ vào, khi ấn nút thì trình sẽ trôi vào hàm ngắt, ở đó bạn sẽ test xem mức áp ở các chân của matrix mà suy ra phím nào đã bấm đúng không ;) => Ý đồ có những sai lầm như sau :D :

1. Set Port của bạn bị ngược, đây là cái sai cơ bản nhé ;)
2. Giải thuật quét phím này về cơ bản sai hoàn toàn bởi lẽ : khi bạn đã set chân là ngõ ra thì làm sao mà bạn có thể đọc đuợc giá trị từ nó về :D

Ở đây vì để cho bạn tự học, tự phát huy khả năng của mình là chính cho nên mình chỉ đưa ra cho bạn giải thuật để giải quyết vấn đề thui, tuyệt không thể trực tiếp viết code giùm bạn đuợc ;) :
- Cách quét phím : bạn thực hiện set Port có 4 ngõ ra và 4 ngõ vào : bây giờ ví dụ các chân ra là từ 1-->4, các chân vào là từ 5-->8 nhé, quy trình quét như sau :
Xuất áp ra chân 1 -> test áp ở chân 5 (gán giá trị cố định vào đó và kết hợp hiển thị LCD),6(...),7(...),8(...), đưa áp chân này về mức cũ ; Xuất áp ra chân 2 -> test áp ở 5(...),6(...),7(...),8(...) ; ..... như vậy bạn sẽ đuợc một ma trận phím quét và hiển thị ra LCD, => mấu chốt cách quét này là gì ?: đó là lợi dụng khả năng chủ động của mình khi cố ý xuất áp ra một chân và kiểm tra mức áp ở 4 chân còn lại => đây là cách quét phím cơ bản nhất :) .

Trong đó có một phím xoá cả màn hình bạn dùng lệnh : LCD=0x01;comnwrt() ;) ;

Còn về phép tính bạn có thể viết cho nó một hàm tính toán riêng : khai báo 4 biến là a,b,pheptinh,ketqua --> sau mỗi lần đọc đuợc giá trị từ phím về thì gửi giá trị vào hàm này và lựa chọn nhét vào biến a hay b (nhét vào a khi chưa ấn các phím phép tính +,-,… Và vào b sau khi đã ấn), công việc là phải sắp xếp các giá trị nhét vào này thành hai con số a và b hẳn hòi (như vậy a và b cũng cần có hàm con để thực hiện sắp xếp, gợi ý như sau :bạn dùng biến count trong này sau mỗi lần value đuợc đưa vào thì biến này sẽ thay đổi do đó dữ liệu căn theo đó mà sắp xếp), xong lúc này chỉ việc chờ phím "=" là ta sẽ đem a (+,-... căn cứ vào biến pheptinh) cho b để ra c sau đó đem c hiển thị lên LCD là xong :p .

Thú thật mình chưa làm cái này bao giờ nên chỉ thực hiện sơsài để có thể hướng dẫn đuợc cho bạn thui, có gì thiếu sót thì bỏ quá cho vậy, dưới đây là hình ảnh về phần cứng để bạn hiểu hơn :) :

Bạn sẽ thành công nếu như bạn cố gắng hơn nữa, phát huy tối đa khả năng của mình :), từ từ sẽ có kinh nghiệm, mong rằng sau này có dịp mình sẽ học hỏi lại :p

Thân.

thobnvn87 13-09-2007 12:13 PM

các bac ơi giup em voi đưoc khong ạ? em dang phai lam 1 bai tap: tim hieu ve net matrix xem no hoat dông the nào? ma chua biet lam ra sao day.bac nao biet giup em voi nha chieu nay em phai nop bai roi.thank cac bac nhieu

cuopbienquin 14-09-2007 01:20 PM

Bạn đọc ơ luồng này ở page 2 hay 3 gì có nói đó.Chúc vui

nbchien 21-09-2007 03:36 PM

Ngắt Timer0
Đây là chương trình dùng ngắt Timer0 định thì 1s.
Đầu tiên led ở chân RB0 sáng, sau 1s sẽ dịch sang trái, nghĩa là led 1 trên chân RB1 sáng , lần lượt như vậy cho các led trên portB và lặp lại mãi mãi.
Code:

//************************************************** **
// Author : nhh
// Date : 02/04/06
// Hardware: PIC16F877A
//************************************************** **
#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(b)
#byte portb=0x06
#define led pin_B0
int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void interrupt_timer0()
{
set_timer0(6);
++count;
if(count==2000)
{
count=0;
a=a<<1; // dich trai a 1bit
}
if(a==256)
{
a=1;
count=0;
}
}
//Chuong trinh chinh
main()
{
set_tris_b(0);
enable_interrupts(global);
enable_interrupts(int_timer0);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
set_timer0(6);
count=0;
a=1;
while(true)
{
portb=a;
}
}


Ai hiểu chương trình trên giải thích hộ em với ạ:
Thứ nhất khi nào hàm con interrupt_timer0() được gọi
Thứ hai, việc tính toán định thì 1s được tính như thế nào.
Thứ ba, biến a được khai báo là số nguyên 8bit. Phạm vi từ 0->255,làm sao bằng 256 đc.
Em mới học nên kô biết, mong mọi người chỉ giúp. Thanks!

nhh 22-09-2007 10:28 AM

Trích:

Thứ nhất khi nào hàm con interrupt_timer0() được gọi
Thứ hai, việc tính toán định thì 1s được tính như thế nào.
Thứ ba, biến a được khai báo là số nguyên 8bit. Phạm vi từ 0->255,làm sao bằng 256 đc.
1. Ngắt Timer0 được gọi khi Timer 0 bị tràn từ 0xff sang 0x00 với điều kiện phải có 2 khai cho phép ngắt timer 0 và ngắt toàn cục:
Code:

enable_interrupts(int_timer0);
enable_interrupts(global);

2. Việc tính toán thời gian tràn của Timer rất dễ, xem luồng "PIC6f877A từ dễ tới khó", hoặc tìm đâu đó trong diễn đàn này phần mềm "PIC Timer Calculator".

3. Biến a 8bit int, ko thể có giá trị 256 -> đúng vậy.
Code:

#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#byte PORTB = 0x06

int16 count;
int8 a;
//Chuong trinh ngat TMR0
#int_timer0
void interrupt_timer0()
{
  set_timer0(6);
  ++count;
  if(count == 2000)  // 2000*500us = 500000us = 1s
      {
        count=0;
        rotate_left(&a,1);
      }
}
//Chuong trinh chinh
void main(void)
{
  set_tris_b(0);
  enable_interrupts(int_timer0);
  setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
  enable_interrupts(global);
  set_timer0(6);// T_dinhthi = 2*(256 - 6)*1us = 500us
  a = 0x01;
 
  while(true)
  {
      PORTB = a;
  }
}

P/S: Khi post chương trình, bạn nên sử dụng thẻ CODE #.

nguyenvo 22-09-2007 12:13 PM

hi!các ban có chương trình hướng dẫn từ a-z của trình biên dịch asm không?thank

1322 23-09-2007 11:19 AM

help
 
Ban co the giup 123? tai sao minh bo cai program nay vao complier thu, tra loi rang, unknow device, try dung pcm, nghia la sao? minh dung ccs 3.2. xin vui long giup dum minh



Trích:

Nguyên văn bởi nhh (Post 2138)
Đây là 1 ví dụ nhỏ về ADC,chân RA0 lấy tín hiệu Analog từ biến trở và xuất giá trị số biến đổi tương ứng qua tám led nối ở portB
Code:

#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#device 16F877*=16 ADC=8
#use delay(clock=10000000)
Int8 adc;
main()
{
setup_adc(adc_clock_internal);
setup_adc_ports(AN0);
set_adc_channel(0);
delay_ms(10);
while(true)
{
adc=read_adc();
output_B(adc);
}
}

http://www.freewebtown.com/nhhao/PIC/ADC.GIF


nbchien 24-09-2007 04:01 PM

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 ạ?

funnyCat 24-09-2007 10:16 PM

Các bác cho em hỏi là trong CCS làm sao có thể sử dụng được mảng nhiều phần tử cho PIC16F877a(em muốn dùng mảng khoảng 128 phần tử, nhưng chỉ khai báo được khoảng 93-94 phần tử thì nó báo là ko đủ RAM)

funnyCat 24-09-2007 10:19 PM

À quên, em khai báo 4 mảng 60 phần tử thì lại được. Làm sao để gộp lại được thành 1 mảng nhỉ?

namqn 24-09-2007 10:36 PM

Trích:

Nguyên văn bởi funnyCat (Post 11577)
Các bác cho em hỏi là trong CCS làm sao có thể sử dụng được mảng nhiều phần tử cho PIC16F877a(em muốn dùng mảng khoảng 128 phần tử, nhưng chỉ khai báo được khoảng 93-94 phần tử thì nó báo là ko đủ RAM)

Trích:

Nguyên văn bởi funnyCat (Post 11578)
À quên, em khai báo 4 mảng 60 phần tử thì lại được. Làm sao để gộp lại được thành 1 mảng nhỉ?

Bạn đọc datasheet của PIC16F877A, hình 2-3 (bản đồ bộ nhớ thanh ghi) sẽ thấy vùng RAM mà người sử dụng có thể đọc/ghi tùy ý (công dụng chung) được chia thành 4 bank không liên tục. Do đó hai trường hợp mà bạn đã gặp là hợp lý. Bạn được phép có 4 mảng, mỗi mảng có tối đa 80 byte, chứ không thể có một mảng liên tục như bạn yêu cầu. Trình dịch cũng khó mà làm gì hơn được vì cấu trúc của RAM trong chip là như vậy. Các PIC18 có bộ nhớ RAM rộng rãi và liên tục hơn nhiều.

Thân,

nbchien 25-09-2007 03:03 PM

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 ạ?

Sao chẳng thấy ai có ý kiến j nhỉ? Các cao thủ đâu hết rồi!

vuongctho 26-09-2007 11:21 PM

em dang hoc lap trinh c cho pic, a nao co tai lieu tieng viet huong dan lap trinh css cho pic cho e xin voi!!!!hepl!

cho em hoi!em muon lam lich van nien viet phan mem bang ccs,cac "thay" nao da tung lam roi cho em biet minh lam ntn voi??huong dan em viet ccs cho mach nay voi!!!cam on!!!!

tungtot_vl 28-09-2007 08:28 AM

các anh ơi cho em hỏi cái này tí
em dùng ccs để lập trình cho bài led matrix. em mới mã hóa font cho vài từ thì chương trình đã báo là không đủ RAM.
thế làm cách nào để nâng cấp thêm RAM cho CCS hả các anh.
còn về phần cứng em cũng chưa biết dùng RAM gì cho đủ để mã hóa toàn bộ font cho đủ. còn cách giao tiếp với RAM ngoài thì thế nào em cũng chưa biết. các anh chỉ giúp em nhé.
vì em đang ở tp qui nhơn nên không có điều kiện họi hỏi mong các anh giúp đỡ

nhh 28-09-2007 09:33 AM

Trích:

Nguyên văn bởi tungtot_vl (Post 11649)
thế làm cách nào để nâng cấp thêm RAM cho CCS hả các anh.

Trình biên dịch chẳng liên quan gì đến RAM của chip cả.

Xin hỏi bạn dùng con pic nào? Với ứng dụng ko lớn thì 16F877A (887A) dùng thoải mái.

Nếu ko đủ thì bạn có thể lựa chọn chip có dung lượng lớn hơn, pic18F chẳng hạn.

namqn 28-09-2007 06:42 PM

Trích:

Nguyên văn bởi tungtot_vl (Post 11649)
các anh ơi cho em hỏi cái này tí
em dùng ccs để lập trình cho bài led matrix. em mới mã hóa font cho vài từ thì chương trình đã báo là không đủ RAM.
thế làm cách nào để nâng cấp thêm RAM cho CCS hả các anh.
còn về phần cứng em cũng chưa biết dùng RAM gì cho đủ để mã hóa toàn bộ font cho đủ. còn cách giao tiếp với RAM ngoài thì thế nào em cũng chưa biết. các anh chỉ giúp em nhé.
vì em đang ở tp qui nhơn nên không có điều kiện họi hỏi mong các anh giúp đỡ

Để mã hóa font cho các ứng dụng led ma trận thì người ta thường dùng flash (bộ nhớ chương trình), vì RAM trên chip không nhiều và việc sử dụng RAM làm bảng mã hóa là sử dụng không đúng mục đích.

Thân,

tungtot_vl 01-10-2007 09:30 AM

Trích:

Nguyên văn bởi namqn (Post 11664)
Để mã hóa font cho các ứng dụng led ma trận thì người ta thường dùng flash (bộ nhớ chương trình), vì RAM trên chip không nhiều và việc sử dụng RAM làm bảng mã hóa là sử dụng không đúng mục đích.

Thân,

lại làm phiền anh nam nữa rồi.
anh nam ơi vì em học lập trình qua mạng nên kinh nghiệm còn non lắm. từ trước đến giờ em chỉ biết xuất dữ liệu trực tiếp ra port thôi. em chưa biết cách lưu data vào flash như thế nào. em nhờ anh chỉ cho vài đường để hiểu biết thêm. em dùng pic 877. và trình dịch ccs
thank you
pic xuất hiện đầu tiên tại thành phố qui nhơn


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