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)

dvnccbmacbt 30-06-2007 08:12 PM

Các bác ơi! Em gặp nhiều trường hợp vẽ orcad bị nhầm. Theo em biết thì proteus có thể mô phỏng và thiết kế mạch in nữa. Vậy tại sao không dùng Proteus? Có ai so sánh hai món này giúp em ko? Cho em hỏi thêm: Làm sao để tạo bus trong proteus. Cảm ơn các bác rất nhiều!

anh_gioi 01-07-2007 01:27 AM

cái đoạn code này:
#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#device 16F877*=16 ADC=8
#use delay(clock=10000000)
#use fast_io(b)
int8 adc;
main()
{set_tris_b(0);
setup_adc(adc_clock_internal);
setup_adc_ports(AN0);
set_adc_channel(0);
delay_ms(10);
while(true)
{
adc=read_adc();
output_B(adc);
}
}

/////////////////////////////
setup_adc_ports(AN0);
//tại sao lại lại chọn chân AN0, mình có thể chọn chân khác được không.nếu chọn chân khác thì mình có phải thay thông số nào khác nữa không?
thank!

thaithienanh 01-07-2007 04:22 AM

To anh giỏi @ : bạn phải nắm đuợc các tập lệnh sẵn của ccs :)

Như lệnh Setup_ADC_port (value) dùng để xác định chân nhận tín hiệu Analog và điện thế chuẩn sử dụng (Vref), thường thì mình hay dùng (all_analogs) tức là dùng hết các chân analog mà VDK cung cấp và điện thế chuẩn bằng VDD,
nhưng tuỳ vào nguời sử dụng muốn biến một chân Analog thành pin I/O và Vref từ một nguồn khác thì sẽ chọn value này khác đi :o .

Lệnh Set_ADC_channel (channel) dùng để chọn chân đọc giá trị ADC
channel là các số từ 0->n (n phụ thuộc vào từng loại vi điều khiển đuợc trang bị bao nhiêu cổng ADC) ví dụ như bạn nhìn thấy chân AN3, và bạn muốn đọc giá trị từ chân này thì bạn sẽ đánh vào là (3) rất đơn giản phải không :D

Ví dụ cho bạn chút nhá :
setup_adc(adc_clock_internal); // chọn xung lấy mẫu ADC = xung nội
setup_adc_ports(all_analogs); //sử dụng tất cả các chân ADC và vef=VDD
While(true){ // vòng lặp chính
while(true){
set_adc_channel(0); // chọn chân lấy mẫu là ANO
delay_ms(10); // tạo trễ để lấy mẫu ADC chuẩn xác
adc0=read_ADC(); // nạp giá trị đọc đuợc vào biến adc0
set_adc_channel(1); // chọn chân lấy mẫu là AN1
delay_ms(10);
adc1=read_ADC();
}
sau đó bạn muốn làm gì đó với các giá trị thu đuợc thì làm OK ;)
}

To dvnccbmacbt @ : Proteus hỗ trợ luôn cho nguời dùng tiện ích là Ares (thần nam tính theo ngữ hi lạp cổ :D), mình có thể dùng để vẽ mạch khá tốt, đồ hoạ khá bắt mắt (có hỗ trợ cả chức năng mô phỏng mạch 3D), giải thuật giải đẩy khi đi mạch của nó cũng khá thông minh (hơn cả Orcad tất nhiên là theo mình thui), nhưng nó có một điểm cực yếu là khi đi vào cấy hình chi tiết các thông số cho mạch in thì nó không có đủ :( , nên nếu là các mạch dơn giản thì Proteus là một trong những lựa chọn hàng đầu của mình, Orcad điểm mạnh là các thông số OK (quá chi tiết), trình nhiều nguời dùng nên có thể giao lưu học hỏi qua lại, phần help dễ nắm bắt..v.v... tuy nhiên điểm yếu của nó là cực kỳ dễ nhầm lẫn trong thiết kế (chỉ cần phần nguyên lý bạn không cẩn thận chồng dây hay gì đó là sinh chuyện rồi :mad:), đồ hoạ thì xấu hoắc, thuật đi mạch thì ngốc hết biết (thường thấy mấy anh dùng toàn vẽ tay :D),... Nên lựa chọn hàng đầu của mình hiện giờ là Protel hoàn hảo hết tất cả những gì mình muốn ,khuyên bạn nên dùng Protel nếu như cảm thấy mình có khả năng tự tiếp thu tốt (do tài liệu hiện rất ít và chẳng đầy đủ) và chọn Orcad khi muốn học hỏi lớp nguời đi trước ;),

Còn về vẽ Bus trong Proteus thì quá đơn giản rùi bạn chọn cái tool nào có hình giống như "sợi bus" vậy là xong, sau đó nối các đường dây từ linh kiện vào dùng tiếp tool net_label đặt nhãn cho từng đường để bus còn biết đâu là các đầu dây của cùng một dây :o , nếu vẫn chưa hiểu rõ về bus thì bạn phải tìm về một ví dụ nào đó rồi xem tại sao lại nối như vậy

Chú ý nếu bạn vẫn chưa rõ thì hãy rê chuột lên trên các tool chờ 1 lát trình sẽ hiện lên tên của từng tool (cái này giúp ích bạn rất nhiều khi mò mẫm một phần mềm nào đấy ;) )

dvnccbmacbt 01-07-2007 08:49 PM

Tui có cuốn sách này về CCS. hi vọng có thể giúp cho cho 1 số bạn :
http://d3.myfreefilehosting.com/d1/C...update%20I.pdf

namqn 01-07-2007 08:57 PM

Trích:

Nguyên văn bởi thaithienanh (Post 9723)
To dvnccbmacbt @ : Proteus hỗ trợ luôn cho nguời dùng tiện ích là Ares (thần nam tính theo ngữ hi lạp cổ :D), mình có thể dùng để vẽ mạch khá tốt, đồ hoạ khá bắt mắt (có hỗ trợ cả chức năng mô phỏng mạch 3D), giải thuật giải đẩy khi đi mạch của nó cũng khá thông minh (hơn cả Orcad tất nhiên là theo mình thui), nhưng nó có một điểm cực yếu là khi đi vào cấy hình chi tiết các thông số cho mạch in thì nó không có đủ :( , nên nếu là các mạch dơn giản thì Proteus là một trong những lựa chọn hàng đầu của mình, ...

Cho ví dụ về những thông số cho mạch in mà Proteus không có đủ?

Thân,

cuopbienquin 09-07-2007 08:12 PM

Chương trình ngắt đây
 
1 Attachment(s)
Các bạn coi gium` mình có sai chỗ nào không mà mình delay không được
Mình muốn khi đóng RB4 thì LED sẽ nháp nháy với delay 50ms chẳng hạn.
Phần ngắt chuyển chế độ thì mình làm được nhưng delay trong mỗi chế độ thì potay.
Code:

#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=1000000)
#use fast_io(b)
#byte portb=0x06
#byte intcon=0x000B
#bit RB4=portb.4
#bit RB5=portb.5
#bit RBIF=intcon.0 //dinh nghia co ngat RB
#bit RBIE=intcon.3 //dinh nghia bit cho phep ngat RB

// Chuong trinh ngat
#int_RB
void ngat_RB()
{
if((RBIF)&&(RBIE))
  {
      //Kiem tra sw1
      {
      if(RB4==0)
        {
       
        portb=0b00000001;
       
        delay_ms(200);
        portb=0b00001111;
        delay_ms(200);
                 
        }
      }
      //Kiem tra sw2
      {
      if(RB5==0)
        {
        portb=0b00001000;
                                    }
      }
     
  RBIF=0; //Xoa co ngat RB
  }
}
// Chuong trinh chinh
main()
{
set_tris_b(0b11110000);
portb=0b11110000;
enable_interrupts(global);
enable_interrupts(int_RB);
ext_int_edge(H_to_L);
while(true)
  {
 
  }
}


nhh 09-07-2007 08:53 PM

Trích:

Nguyên văn bởi cuopbienquin (Post 9943)
Các bạn coi gium` mình có sai chỗ nào không mà mình delay không được
Mình muốn khi đóng RB4 thì LED sẽ nháp nháy với delay 50ms chẳng hạn.
Phần ngắt chuyển chế độ thì mình làm được nhưng delay trong mỗi chế độ thì potay.
Code:

#include <16F877A.h>
...
}


Code:

#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(b)
#byte portb=0x06
#byte intcon=0x000B
#bit RB4=portb.4
#bit RB5=portb.5
#bit RBIF=intcon.0 //dinh nghia co ngat RB
#bit RBIE=intcon.3 //dinh nghia bit cho phep ngat RB

// Chuong trinh ngat
#int_RB
void ngat_RB()
{
if((RBIF)&&(RBIE))
  {
      //Kiem tra sw1
      {
      if(RB4==0)
        {
       
        portb=0b00000001;
       
        delay_ms(50);
        portb=0b00001111;
        delay_ms(50);
                 
        }
      }
      //Kiem tra sw2
      {
      if(RB5==0)
        {
        portb=0b00001000;
                                    }
      }
     
  RBIF=0; //Xoa co ngat RB
  }
}
// Chuong trinh chinh
main()
{
set_tris_b(0b11110000);
portb=0b11110000;
enable_interrupts(global);
enable_interrupts(int_RB);
ext_int_edge(H_to_L);
while(true)
  {
  }
}

Đã sửa lại cho phù hợp file mô phỏng của bạn. Với code trên, kết thúc ngắt tất nhiên ko còn delay nữa. 50ms hơi ít, tăng lên 1000ms, thấy kết quả.

cuopbienquin 09-07-2007 10:55 PM

Mình đã sữa lại thành 1000ms và đã chạy mô phỏng được,có điều khi chuyển chế độ (nhấn button tới 2 lần và mối làn nhấn phải giữ một thời gian) thì mới chuyển được .
Mình muốn nhấn button (1 lần) thì chế đọ 1 chạy,nhấn button 2 thi chế độ 2 chạy,vạy thôi.Mình hi vọng các bạn có thể sửa giùm mình thêm đoạn code đó nha.
#include <16F877A.h>
#fuses NOWDT,PUT,XT,NOPROTECT
#use delay(clock=4000000)
#use fast_io(b)
#byte portb=0x06
#byte intcon=0x000B
#bit RB4=portb.4
#bit RB5=portb.5
#bit RBIF=intcon.0 //dinh nghia co ngat RB
#bit RBIE=intcon.3 //dinh nghia bit cho phep ngat RB

// Chuong trinh ngat
#int_RB
void ngat_RB()
{
if((RBIF)&&(RBIE))
{
//Kiem tra sw1
{
if(RB4==0)
while(RB5==1)
{

portb=0b00000001;
delay_ms(1000);
portb=0b00001111;
delay_ms(1000);

}
}
//Kiem tra sw2
{
if(RB5==0)
while(RB4==1)
{
portb=0b00001000;

delay_ms(1000);
portb=0b00001111;
delay_ms(1000);
}
}

RBIF=0; //Xoa co ngat RB
}
}
// Chuong trinh chinh
main()
{
set_tris_b(0b11110000);
portb=0b11110000;
enable_interrupts(global);
enable_interrupts(int_RB);
ext_int_edge(H_to_L);
while(true)
{
}
}

tranvanthuong 11-07-2007 09:47 AM

BẠN SỪA LẠI #fuses NOWDT,PUT,XT,NOPROTECT THÀNH
#fuses NOWDT,PUT,HS,NOPROTECT LÀ CHƯƠNG TRÌNH ỔN RỒI

tranvanthuong 11-07-2007 09:50 AM

Lúc Bạn Viết Chương Trình Ngắt Thì Trong Chương Trình Này Phải Cấm Ngắt Toàn Cục Xử Lí Xong Mới Cho Phép Ngắt Lại
Vài điều Trao đổi Cùng Bạn!

cuopbienquin 11-07-2007 02:34 PM

thx bạn nhiều.Mình chạy được rồi,ah,mà bạn giải thích mình thay "Xt" trong dòng đó bằng "HS" la sao hả bạn.

anh_gioi 12-07-2007 09:52 AM

bài này:
Code:

/*-----------------------------------------------------------------------------
* Author    : nhh
* Date      : 05/04/06
* Hardware  : PIC16F877A
* Compiler    : CCS C 3.249
* Description  : Hien thi LCD
*=============================================================================*/
#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 PORTB

/*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);
}
/*Ham main*/
void main(void)
{
 set_tris_B(0);
 set_tris_D(0);
 delay_ms(100);  //  Tao tre 100ms cho LCD khoi dong

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

 LCD = 0x85;      //  Vi tri hang 1,cot 6
 comnwrt();

 LCD = 'B';      //  Xuat dong chu "BE YEU" ra LCD
 datawrt();
 LCD = 'E';
 datawrt();
 LCD = ' ';
 datawrt();
 LCD = 'Y';
 datawrt();
 LCD = 'E';
 datawrt();
 LCD = 'U';
 datawrt();
 LCD = '!';
 datawrt();
}

bài này không bít gọi file DEFS_16F877A.h ra như thế nào nhỉ?
mong mọi người chỉ dùm.thank!

namqn 12-07-2007 06:56 PM

Trích:

Nguyên văn bởi cuopbienquin (Post 9985)
thx bạn nhiều. Mình chạy được rồi,ah,mà bạn giải thích mình thay "Xt" trong dòng đó bằng "HS" la sao hả bạn.

XT là đặt bộ dao động ở chế độ dùng với thạch anh tần số thấp (4 MHz trở lại), HS là đặt bộ dao động ở chế độ dùng với thạch anh tần số cao hơn (4 MHz đến maximum của chip).

Thân,

anh_gioi 12-07-2007 07:30 PM

mọi ngừoi ơi! xem hộ mã này với
không bít có sai gì ko ,nó không báo lỗi nhưng nó không hiển thị chữ

Code:

#include "16F877A.h"
#include "C:\Documents and Settings\Administrator\Desktop\DEFS_16F877A\DEFS_16F877a.h"
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 4M)
#define RS RD0
#define RW RD1
#define E  RD2
#define LCD portB

//tao ham goi lenh dieu khien
void comnwrite(){
                    RS = 0; //chon thanh ghi lenh 
                    RW = 0; //chon che do ghi
                    E = 1; //tao suon xung
                    E = 0;
                    delay_ms(1); //tao do tre cho LCD
                          }
// tao ham ghi du lieu
void datawrite(){
                  RS = 1;
                  RW = 0;
                  E = 1;
                  E = 0;
                  delay_ms(1);
                          }
//ham chinh
void main(){
            set_tris_b(0);
            set_tris_d(0);
            delay_ms(100); //tao tre cho lcd khoi dong
           
            LCD = 0x38; //tao ma tran 5x7
            comnwrite();
            LCD = 0x0C ; //bat hien thi,tat con tro
            comnwrite();
            LCD = 0x80; //dau dong thu nhat
            comnwrite();
           
            //xuat chu ANH_GIOI
            LCD = 'A';
            datawrite();
            LCD = 'N';
            datawrite();
            LCD = 'H';
            datawrite();
            LCD = '_';
            datawrite();
            LCD = 'G';
            datawrite();
            LCD = 'I';
            datawrite();
            LCD = 'O';
            datawrite();
            LCD = 'I';
            datawrite();
                    }

thank!

namqn: bạn xem lại tôi sửa như thế nào để hiển thị code, sau đó bạn làm như vậy khi post code. Tôi không thể sửa cho mọi post có code được.

anh_gioi 12-07-2007 08:43 PM

kiểm tra lại hóa ra chẳng có lỗi gì cả.

tranvanthuong 13-07-2007 11:33 AM

trời đất làm tui hoa cả mắt!!!

tranvanthuong 13-07-2007 11:35 AM

Trích:

Nguyên văn bởi anh_gioi (Post 10020)
kiểm tra lại hóa ra chẳng có lỗi gì cả.

tui bảo đảm với bạn với chương trình này khi lắp mạch thật thì sẽ chắc chắn mạch không chạy được bạn xem lại nhé!

anh_gioi 13-07-2007 03:07 PM

cậu nói đúng rồi!
mình lắp mạch thật mà chẳng thấy gì cả?
cậu có thể nói cho mình sai ở chỗ nào ko?
cám ơn trước nha!

anh_gioi 13-07-2007 03:12 PM

đây là đoạn mã mình cho chạy thật nhưng chẳng thấy báo gì cả:

Code:

#include "16F877A.h"
#include "C:\Documents and Settings\Administrator\Desktop\DEFS_16F877A\defs_16f877a.h"
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 8M)
#define RS RD0
#define RW RD1
#define E RD2
#define LCD portb
const unsigned char digital[]="TA LA VO DICH HA HA...!";
INT I=0;
//TAO HAM LENH
void commwrite(){
  RS = 0;
  RW = 0;
  E = 1;
  E = 0;
  delay_ms(100);}
 //tao ham gui du lieu
 void datawrite(){
                  RS = 1;
                  RW = 0;
                  E  = 1;
                  E  = 0;
                //  delay_ms(10);
                    }
 //ham chinh
 void main(){
        set_tris_b(0);
        set_tris_d(0);
        delay_ms(100);
       
        LCD = 0x38; //tao ma tran 5x7
        commwrite();
        LCD = 0x0c; //tat con tro,bat hien thi
        commwrite();
        LCD = 0x80; //con tro ve dong dau tien
       
        while(1){
                    LCD = digital[i];
                    datawrite();
                    delay_ms(100);
                    i++;
                    if(i ==13){ LCD = 0xc2;
                                commwrite();
                                delay_ms(100);}
                    if(i == 24){ LCD = 0x01;
                                    commwrite();
                                    delay_ms(500);
                                    LCD = 0x80;
                                    commwrite();
                                    i = 0;}
                        }
       
 }

mong mọi người xem dùm cái !

namqn: nhắc bạn một lần nữa về việc dùng các thẻ code để định dạng. Hãy xem tôi sửa post của bạn ra sao để biết cách làm.

anh_gioi 13-07-2007 10:44 PM

anh da sủa cho em đâu ạ?

namqn 13-07-2007 11:22 PM

Trích:

Nguyên văn bởi anh_gioi (Post 10045)
anh da sủa cho em đâu ạ?

Tôi sửa trong post của bạn. Khi bạn đã đăng nhập thì có thể nhấn nút edit của post đó để sửa, khi đó sẽ thấy tôi sửa nó như thế nào.

Thân,

anh_gioi 14-07-2007 10:15 AM

edit là chỉnh sửa bài của mình mà?
anh là ơn có thể xem code củ em ở cuối ạ.
hic...em mơi mua lcd mà chảng hiêrn thị được.tức quá....muốn cho cái búa..

namqn 14-07-2007 07:19 PM

Trích:

Nguyên văn bởi anh_gioi (Post 10054)
edit là chỉnh sửa bài của mình mà?
anh là ơn có thể xem code củ em ở cuối ạ.
hic...em mơi mua lcd mà chảng hiêrn thị được.tức quá....muốn cho cái búa..

Có khả năng bạn cần khởi tạo module LCD trước khi đặt chế độ hiển thị (tôi đã viết 1 lần rồi, nhưng bây giờ tìm bằng chức năng search của diễn đàn thì không ra). Tôi nói lại vậy (quy trình cho các module dùng chip điều khiển tương thích HD44780):

- Làm trễ một khoảng thời gian khi mới bật nguồn cho LCD (40 ms từ thời điểm Vdd = 2.7V, hay 15 ms từ thời điểm Vdd = 4.5V)
- Xuất lệnh 0x33 (0x30 đến 0x3F đều ok)
- Chờ khoảng 4.1 ms trở lên
- Xuất lệnh 0x33 (0x30 đến 0x3F đều ok)
- Chờ khoảng 100 us trở lên
- Xuất lệnh 0x33 (0x30 đến 0x3F đều ok)
- Xuất lệnh đặt chế độ (của bạn là 0x38)
- Xuất lệnh tắt màn hình 0x08
- Xuất lệnh xóa màn hình 0x01
- Xuất lệnh đặt chế độ nhập dữ liệu (tăng hay giảm địa chỉ, có dịch màn hình hay không)

Đó là quy trình khởi tạo cho module LCD chưa từng làm việc lần nào với vi điều khiển của bạn. Thông thường, khi module đã được khởi tạo rồi thì những lần sau bạn có thể dùng thẳng các lệnh đặt chế độ mà không cần thực hiện quy trình khởi tạo như trên.

Thân,

anh_gioi 16-07-2007 07:45 PM

cám ơn anh ạ.em đã cho hiển thị được lên LCD rùi ạ.nhưng chỉ hiển thị chữ không dấu thui,bây giờ em muốn hiển thị chữ có dấu thì làm thế nào ạ?
em cám ơn!!!!

bien_van_khat 16-07-2007 08:11 PM

Để làm chữ có dấu tối thiểu bạn phải có bộ font chữ có dấu, nhưng với LCD kiểu ký tự dạng như 16x2, 16x4 thì hiển thị chữ có dấu rất xấu.
Làm cái này trên LCD graphic tốt hơn nhiều.

anh_gioi 16-07-2007 09:15 PM

vậy bộ font này là loại bộ font nào? hiển thị xấu cũng được,chủ yếu mình muốn xem các làm như thế nào thui
(mình sử dụng 16F877A,LCD 16x2)

bien_van_khat 16-07-2007 10:56 PM

Mình ko theo dõi luồng này, nên ko chắc vấn đề này đã được đề cập hay chưa, bạn nên tìm lại trong diễn đàn, ở đây mình chỉ nói sơ qua.

Mỗi ký tự hiển thị trên lcd thường có kích thước 7 hàng x 5 cột do đó được xác định bởi 7byte, 3 bit cao nhất mỗi byte ko sử dụng. VD:
0x0E
0x0E
0x04
0x04
0x04
0x04
0x0C
Tạo thành chữ J hoa
Để có bộ font của riêng mình công việc của bạn là tìm ra các byte này ứng với mỗi ký tự. Công đoạn này tốn rất nhiều công sức nếu làm bằng tay, thường người ta dùng phần mềm, nhưng các phần mềm này lại thường ko free.

namqn 16-07-2007 11:08 PM

Trích:

Nguyên văn bởi anh_gioi (Post 10104)
vậy bộ font này là loại bộ font nào? hiển thị xấu cũng được,chủ yếu mình muốn xem các làm như thế nào thui
(mình sử dụng 16F877A,LCD 16x2)

LCD chủ yếu hiển thị bằng CGROM (Character Generator Read Only Memory), tức là bạn chỉ cần cho biết mã ASCII của ký tự, các pattern thể hiện ký tự (5x7, 5x8 hay 5x10) sẽ được lấy từ ROM. Các bộ điều khiển tương thích HD44780 cũng cho phép người dùng tự định nghĩa tối đa 8 ký tự (5x7 hay 5x8) trong vùng CGRAM (Character Generator Random Access Memory). Vùng nhớ này gồm 64 byte, chứa trực tiếp các pattern để tạo ký tự, và người dùng được phép ghi vào. Tuy nhiên, chỉ có thể vẽ thêm 8 ký tự, nên việc bạn muốn hiển thị tiếng Việt trên LCD ký tự là việc rất khó khăn và hạn chế. Nếu bạn vẫn muốn làm thì hãy tìm đọc datasheet của HD44780 và các tutorial trên mạng. Cách làm khá dài dòng nên không tiện nêu trên diễn đàn.

Một link để tham khảo:
http://deanandara.com/robots/ApuLcd.html

Thân,

anh_gioi 17-07-2007 12:02 AM

vậy nếu hiển thị trên LCD muốn dễ dàng thì em phải sử dụng lợi LCD khác a(ko phải loại 16x2)như loại mà bien_van_khat đã nói ạ.ngoài ra anh có thể nêu cho em những loại LCD lào nữa ko ạ(tất nhiên kinh phi mua LCD cũng phải rẻ ạ)

namqn 17-07-2007 01:49 AM

LCD thông thường có 2 loại khác nhau về cách thức hiện thực: LCD ký tự và LCD đồ họa. LCD ký tự có các ô định nghĩa sẵn sẽ hiển thị các ký tự nằm trong bộ ROM ký tự hay vài ký tự do người dùng định nghĩa. LCD đồ họa cho phép bạn vẽ (hiển thị) bất kỳ điểm ảnh nào, nó cũng có chế độ hiển thị ký tự. Tất nhiên LCD đồ họa thì giao tiếp phức tạp hơn và cũng đắt tiền hơn. Bạn nên dùng LCD ký tự khi mới làm quen với LCD, sau đó có nhu cầu thì chuyển sang LCD đồ họa. LCD đồ họa gần gũi nhất là các màn hình tại các quầy counter tính tiền của siêu thị, các màn hình trong các máy trò chơi bỏ túi, ...

Thân,

sandro_bk 18-07-2007 02:34 PM

chào các bạn mình mới học pic nên chưa biết nhiều mong được sự giúp đỡ,
tui có vài câu hỏi mong được chỉ giáo
tui sử dụng ngắt timer nhưng thấy lệnh
set_timer0(); ko có tác dụng nghĩa là đặt số mấy cũng ko thấy thay đổi
thậm chí ko có lệnh đó vẫn chạy như thường
bạn nào làm ngắt timer rùi chỉ mình với
Code:

#include <18F4331.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)

int i=0;
void main()
{
        setup_timer_0(rtcc_div_32);
        set_timer0(10);  ????nếu đặt 1 thì bao lâu mới ngắt
        enable_interrupts(int_rtcc);
        enable_interrupts(global);
        while(true)
        {
        }
}

#int_rtcc
void ngat_timer()
{
        i++;
        output_D(i);
       
}

cấu hỏi thứ 2 là khi giao tiếp máy tính mình truyền từ PC đến pic
dùng lệnh getc(); thì chỉ thu được 1 kí tự
ví dụ truyền số 12 thì thu được 2 số 1 và 2
có bạn nào biết lệnh nào để lấy 1 chuỗi ko?

namqn 18-07-2007 06:56 PM

Về timer 0 và hàm set_timer0(), bạn đọc thêm tài liệu hướng dẫn của CCS C (trang 206, ver. 4, 01/2007) và datasheet của chip.

Về getc(), nếu bạn dùng nó thì tất nhiên chỉ lấy được 1 ký tự là nó đã trở về. Bạn đọc thêm về hàm gets() trong tài liệu hướng dẫn của CCS C (đã nêu trên, trang 148) để đọc 1 chuỗi ký tự.

Nếu bạn chưa biết tài liệu đó lấy ở đâu:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf

Thân,

anh_gioi 18-07-2007 08:24 PM

cho em hỏi cái bài LCD ở trên mà em đã hỏi ý ạ.em đã cho hiển thị được rùi, nhưng :
khi chạy lượt đầu tiên thì nó bị mất 1 kí tự đầu tiên,ở cả 2 hàng luôn.và chạy lượt sau nó ko bị mất,đúng như lập trình.
em đã khai báo 0x80 và 0xc0 cho 2 hàng ạ

namqn 18-07-2007 11:06 PM

Trích:

Nguyên văn bởi anh_gioi (Post 10163)
cho em hỏi cái bài LCD ở trên mà em đã hỏi ý ạ.em đã cho hiển thị được rùi, nhưng :
khi chạy lượt đầu tiên thì nó bị mất 1 kí tự đầu tiên,ở cả 2 hàng luôn.và chạy lượt sau nó ko bị mất,đúng như lập trình.
em đã khai báo 0x80 và 0xc0 cho 2 hàng ạ

Mất theo kiểu nào vậy bạn? Không hiển thị ra ở vị trí đó hay là những ký tự nằm cùng hàng bị dịch qua bên trái một vị trí hay là hiển thị sai ở vị trí đó?

Thân,

anh_gioi 19-07-2007 11:44 AM

dạ .LCD quét lần đầu tiên nó bị dịch sang trai 1 ki tu.(như : ANH_GIOI thì nó còn NH_GIOI).quét lần thứ hai thì nó ko bị mất như trên nữa.
e bị mất cả 2 hàng luôn mới đau chứ

namqn 19-07-2007 06:19 PM

Trích:

Nguyên văn bởi anh_gioi (Post 10176)
dạ .LCD quét lần đầu tiên nó bị dịch sang trai 1 ki tu.(như : ANH_GIOI thì nó còn NH_GIOI).quét lần thứ hai thì nó ko bị mất như trên nữa.
e bị mất cả 2 hàng luôn mới đau chứ

Hiện tượng này có nhiều khả năng là do thuật toán của bạn, lượt chạy đầu tiên con trỏ của chuỗi ký tự bị sai chẳng hạn. Bạn kiểm tra lại thuật toán của chương trình. Ở đầu vòng lặp chính nên có lệnh đặt giá trị cho con trỏ dùng để truy xuất chuỗi ký tự.

Thân,

nguyen.geo 19-07-2007 10:10 PM

Trích:

Nguyên văn bởi anh_gioi (Post 10176)
dạ .LCD quét lần đầu tiên nó bị dịch sang trai 1 ki tu.(như : ANH_GIOI thì nó còn NH_GIOI).quét lần thứ hai thì nó ko bị mất như trên nữa.
e bị mất cả 2 hàng luôn mới đau chứ

Ban ơi theo mình thì bạn hãy đặt giá trị trễ thêm 1 tí nữa là được thôi mình cũng đã gặp trường hợp nảy rồi lỗi này thường xuất hiện với các câu lệnh như là xóa màn hình, về đầu dòng, dịch con trỏ. Thưởng thì mình đặt trễ sau xóa màn hình 2ms, sau lệnh chức năng khác cho LCD ( Trường hợp RS = 0) là 10 us thì nó làm việc bình thường.các lệnh hiển thị dữ liệu thì không cần. Bạn thử theo cách của mình nhé. chúc bạn thành công !

tuanta 01-08-2007 02:34 PM

Lỗi với chân RB3
 
Xin chào,

Mình đang sử dụng con PIC16F873A, chương trình viết trên CCS C. Mình gặp một lỗi rất khó hiểu là khi làm việc với portB, có duy nhất chân RB3 là mình không sao điều khiển được. Chẳng hạn mình dùng lệnh output_high(PIN_B3) thì không bao giờ nó High cả. Mạch test mình làm cũng rất đơn giản, giống như mạch của NHH post thôi. Mình đã nghĩ là do con PIC của mình nó hỏng riêng chân đấy, nên mình đã thử mua mấy con PIC16F873A khác về dùng, tình trạng vẫn hệt như vậy. Sau đó mình lại tiếp tục thử bằng cách chuyển sang con PIC16F876A xem sao, thì lỗi gặp cũng y hệt! Xin mọi người lời khuyên.

(Mạch nạp mình dùng là Galep-4).
Trích:

Nguyên văn bởi nhh (Post 2107)
Chào cả nhà!

Để lập trình cho PIC, mọi người có thể chọn cho mình những ngôn ngữ lập trình khác nhau như ASM, CCS C, HT-PIC, pascal, basic,...
Với nhh, đầu tiên tìm hiểu và viết chương trình cơ bản bằng ASM để hiểu rõ cấu trúc sau đó thì viết bằng CCS C cũng viết lại những cái cơ bản và đi dần lên, tốc độ lúc này nhanh hơn khi viết bằng ASM rất nhiều.

Khi viết bằng CCS C thông thường thì dịch ra file.hex có dài hơn so với khi viết bằng ASM. Hai ngôn ngữ CCS C và HT-PIC được ưa chuộng hơn cả, CCS C dễ học,gần gũi với ASM còn HT-PIC là dạng ANSI C.

Để lập trình và biên dịch CCS C, dùng chương trình PIC C Complier,sau khi soạn thảo các bạn ấn F9
để dịch,nếu thành công sẽ có thông báo như sau:

http://i82.photobucket.com/albums/j257/nhhao/ccsc.gif

Ngoài ra, để xem code ASM như thế nào,sau khi dịch bạn chọn mục C/ASM List như hình dưới đây:

http://i82.photobucket.com/albums/j257/nhhao/ccsc1.gif

Link download trình biên dịch CCS C ở đây: http://www.tailieuvietnam.net/downlo...CCSC_3.249.rar
Phiên bản mới hơn tải tại: www.kho.tailieuvietnam.net, vào Download Home > Điện tử tàn thư > Vi điều khiển - Vi xử lý - PLC

Chúng ta cùng nhau tìm hiểu lần lượt các phần sau:

1.I/O + Delay
2.Timer và ngắt Timer
3.Ngắt ngoài
4.ADC, PWM,... (tập trung mổ xẻ nhiều)
5......

Tạm thời cứ như vậy đã, sau này sẽ tính tiếp!
Nào,chúng ta bắt đầu thôi!

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


picpicpic 02-08-2007 10:08 AM

Bạn chú ý chân RB3 là chân cực thu hở, muốn sử dụng, bạn mắc thêm 1 điện trở kéo lên.

c828 05-08-2007 02:12 PM

chào các Bác mình mới học ccs c được vài ngày nhưng khi viết ct hiển thị trên 2 led 7 doan và mô phỏng trên proteus thì không được, mong các bác cho em đoạn code. cám ơn


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