PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > Cơ bản về vi điều khiển và PIC

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Cơ bản về vi điều khiển và PIC Những bài hướng dẫn cơ bản nhất để làm quen với vi điều khiển PIC

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 13-01-2009, 12:31 AM   #1
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Mới bắt đầu? Code không chạy? Hãy vào đây!

Checklist dưới đây được tôi lược dịch từ piclist và cập nhật một số thông tin thích hợp cho người dùng Việt Nam. Những thông tin này rất có ích cho người học PIC, chủ yếu là người mới học, nhưng không loại trừ những người đã có kinh nghiệm dùng PIC lâu năm. Nhiều người dùng lâu năm vẫn chưa biết đến sự tồn tại của piclist và thư viện mã nguồn cùng các thông tin hữu ích của nó.

Nếu code của bạn không chạy, hãy kiểm tra các mục 9 - 17.

1. Biết đến sự tồn tại của www.piclist.com (thư viện mã nguồn rất lớn, cùng các thông tin hữu ích).

2. Chọn một PIC để bắt đầu. Tại VN vào thời điểm này, nên chọn PIC16F886 để có thể học mọi thứ của dòng PIC tầm trung, mà không tốn quá nhiều tiền. Sau đó, hãy chọn một PIC18 để có nhiều tính năng nâng cao (chọn PIC18F2331 nếu thiên về điều khiển động cơ, các hướng khác nên chọn PIC18F2550).

3. Không đụng vào chân của PIC trừ khi bạn đã nối đất bản thân, vì lý do tĩnh điện.

4. Tìm một mạch nạp thích hợp, hỗ trợ PIC của bạn. Các mạch nạp đơn giản được giới thiệu ở đây: http://www4.hcmut.edu.vn/~nqnam/uC.php hoàn toàn hỗ trợ các PIC đã nêu trên.

5. Đừng bật bảo vệ code ở giai đoạn (mới học) này.

6. Chịu khó đọc tài liệu: datasheet cho PIC đang được dùng (www.microchip.com), các tutorial cơ bản cho PIC.

7. Chọn một ngôn ngữ lập trình: hợp ngữ, Pascal, Basic, C/C++, Java, ... Nhiều trình dịch ngôn ngữ cấp cao hiện nay có các phiên bản miễn phí (demo, giới hạn chức năng, phiên bản cho sinh viên, ...).

8. Bắt đầu bằng một bài tập rất đơn giản như bật LED khi công tắc đóng, và phát triển từ đây khi code đã chạy tốt.

9. Đừng thả nổi ngõ vào, kéo lên hoặc kéo xuống các ngõ vào bằng một điện trở 10 k chẳng hạn.

10. Đảm bảo thiết lập đúng các thanh ghi TRISx.

11. Chống nẩy cho các phím/công tắc.

12. Chân RA4 của hầu hết các PIC thuộc loại "cực máng hở", để xuất logic '1' thì cần phải kéo chân này lên VDD bằng một điện trở 500 ohm đến vài k.

13. Tắt WDT nếu không dùng.

14. Kiểm tra xem chân MCLR đã được nối vào VDD (qua một điện trở khoảng 10 k) hay chưa.

15. Nối nguồn tương ứng tất cả chân VDD và VSS của PIC, và đảm bảo giữa mỗi cặp chân VDD và VSS gần nhau đều có một tụ ceramic 100 nF đặt gần các chân này đến mức có thể.

16. Đảm bảo các bit thiết lập dao động là phù hợp cho kiểu mạch/bộ dao động của bạn.

17. Nối một điện trở khoảng 4,7 k từ chân PGM (của các PIC có khả năng nạp chương trình ở điện áp thấp-LVP) đến VSS, trong trường hợp PIC chưa qua sử dụng, hoặc chế độ LVP đang được sử dụng.

18. Code mẫu cho hầu hết các ứng dụng phổ biến có tại www.piclist.com/faq

19. Nếu code của bạn không làm việc tốt: Gạt toàn bộ chương trình sang một bên, tìm cách viết một đoạn code nhỏ và làm cho nó chạy tốt. Sau đó thêm vào từng phần còn lại của code ban đầu, kiểm tra và gỡ rối từng phần, cho đến khi toàn bộ chương trình của bạn làm việc tốt. Chú thích mỗi và mọi dòng code về chức năng của nó, và kiểm tra lại với datasheet.

Thân,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263

thay đổi nội dung bởi: namqn, 17-02-2013 lúc 11:09 AM.
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 01-11-2009, 07:43 AM   #2
hangocminh1989
Đệ tử 6 túi
 
Tham gia ngày: Apr 2009
Bài gửi: 132
:
thank bang chủ nhiều
hangocminh1989 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 24-01-2010, 08:40 AM   #3
danh_lecong1502
Nhập môn đệ tử
 
Tham gia ngày: Oct 2009
Bài gửi: 8
:
Các bác cho em hỏi về vấn đề nạp cho chíp.Em mới làm quen nên có thể là chưa rõ lắm nhờ mọi người chỉ bảo.
Em viết chương trình cho p16f877a và đã viết thành công rồi.Đây là đoạn file hex mà chương trình MPLAP cho ra
:020000040000FA
:1000000001280313831686018312FF30860001281E
:02400E00B13FC0
:00000001FF

Sau đấy em đi nạp thì mạch cũng báo là việc nạp Ok.Nhưng em đi kiểm tra lại code đã nạp bằng cách cho xuất ra export hex file thì thấy không giống so với chương trình mình đã viết.Đây là đoạn hẽ file đã xuất ra :
:020000040000FA
:1000000001280313831686018312FF30860001281E
:10001000FF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FF0
:10002000FF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FE0
:10003000FF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FD0
:10004000FF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FC0
:10005000FF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FB0
:10006000FF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3FA0
:10007000FF3FFF3FFF3FFF3FFF3FFF3FFF3FFF3F90
phía dưới còn nhiều hàng tương tự như vậy lắm
Mong nhận được hồi âm sớm của mọi người.Thank
danh_lecong1502 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 24-01-2010, 10:40 AM   #4
batbatdieu
Đệ tử 4 túi
 
Tham gia ngày: May 2005
Bài gửi: 83
:
những vùng có giá trị FF3 là những vùng trắng (chưa ghi ) trong program memory . code bạn đọc lên là đúng rồi
batbatdieu vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 02-02-2010, 09:15 PM   #5
dienbk36
Nhập môn đệ tử
 
Tham gia ngày: Jan 2010
Bài gửi: 6
:
Mình chào mọi người,mình mới bắt đầu học Pic ,mình vừa viết 1 chường trình nhỏ,dịch chương trình cũng đã thành công,nhưng mình không tim thấy file hex để mô phỏng trên proteus,các bạn cho mình ý kiến nhé
dienbk36 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 02-02-2010, 09:35 PM   #6
greenfield
Đệ tử 6 túi
 
Tham gia ngày: Jul 2009
Bài gửi: 152
:
Bạn lập trình bằng phần mềm gì vậy? Mà nếu dịch thành công thì sẽ tạo ra file hex chứ. Bạn tìm trong thư mục bạn lưu file bạn lập trinhg thử chắc có đó.
greenfield vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-03-2010, 11:12 AM   #7
tungbka
Đệ tử 1 túi
 
Tham gia ngày: Jul 2009
Bài gửi: 11
:
Em đang viết 1 chương trình hiển thị số lên lcd, các hàm của lcd lấy của bác linhnc308. Tuy nhiên chỉ hiển thị được từ 0-255. Mong các cao thủ chỉ giáo để em hiển thị được số có 4 chữ số. Chương trình như sau:
Code:
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock=20000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT 
#include <lcd_lib_4bit.c>
#define enter RA2
#define up    RE0
#define down  RE1
void ht(int);
void main()
{
int16 k=0;
while(ENTER)  {
       if(!UP)  {while(!UP);
       if(k<3000)  k++;else k=0;
       }
       if(!DOWN)  {while(!DOWN);
       if(k>0)  k--;else k=3000;
       }
       lcd_init();
      lcd_putchar("k=");
       lcd_putcmd(0x82);
ht(k);
}
       while(!ENTER);
       
    }
void ht(int a) {
     int nghin,tram,chuc,dvi;
     nghin=(int)a/1000;
     tram=(int)(a%1000)/100;
     chuc=(int)(a%100)/10;
     dvi=(int)(a%10);
     lcd_putchar(nghin+48);
     lcd_putchar(tram+48);
     lcd_putchar(chuc+48);
     lcd_putchar(dvi+48);
}

thay đổi nội dung bởi: namqn, 05-03-2010 lúc 11:44 AM. Lý do: định dạng code
tungbka vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-03-2010, 11:48 AM   #8
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Bạn dùng CCS C, nên mặc định int sẽ là int8 (số nhị phân chứa trong 8-bit). Do đó, bạn chỉ có thể biểu diễn các giá trị từ 0-255.

Hàm ht() của bạn phải nhận đối số 16-bit (tức là kiểu long hay int16, trong CCS C).

Thân,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-03-2010, 11:21 PM   #9
tungbka
Đệ tử 1 túi
 
Tham gia ngày: Jul 2009
Bài gửi: 11
:
Trích:
Nguyên văn bởi namqn View Post
Bạn dùng CCS C, nên mặc định int sẽ là int8 (số nhị phân chứa trong 8-bit). Do đó, bạn chỉ có thể biểu diễn các giá trị từ 0-255.

Hàm ht() của bạn phải nhận đối số 16-bit (tức là kiểu long hay int16, trong CCS C).

Thân,
Vâng, em cũng đã thử thay đổi kiểu trong hàm ht() nhưng khi dịch ra thì lại báo lỗi. Nguyên nhân có lẽ là do các hàm trong lcd_lib_4bit đều có biến kiểu int. Có cách nào để sửa chương trình để em hiển thị được số có 4 chữ số không ạ? Cảm ơn anh nhìu. ^^
tungbka vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-03-2010, 09:40 PM   #10
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Trích:
Nguyên văn bởi tungbka View Post
Vâng, em cũng đã thử thay đổi kiểu trong hàm ht() nhưng khi dịch ra thì lại báo lỗi. Nguyên nhân có lẽ là do các hàm trong lcd_lib_4bit đều có biến kiểu int. Có cách nào để sửa chương trình để em hiển thị được số có 4 chữ số không ạ? Cảm ơn anh nhìu. ^^
Bạn chỉ sửa thế này thôi thì thế nào (tôi không dùng CCS C, nên bạn sửa như dưới đây và dịch xem kết quả ra sao):
Code:
void ht(long a) {
     int nghin,tram,chuc,dvi;
     nghin=(int)a/1000;
     tram=(int)(a%1000)/100;
     chuc=(int)(a%100)/10;
     dvi=(int)(a%10);
     lcd_putchar(nghin+48);
     lcd_putchar(tram+48);
     lcd_putchar(chuc+48);
     lcd_putchar(dvi+48);
}
Tất nhiên bạn cũng nhớ sửa lại prototype của ht() ở đầu chương trình.

Thân,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-03-2010, 10:59 PM   #11
tungbka
Đệ tử 1 túi
 
Tham gia ngày: Jul 2009
Bài gửi: 11
:
Ah. Được rồi. Thanks bác Nam nhé. Lần trước em cũng sửa thành long hoặch int16 nhưng chưa sửa prototype của h(t) nên nó báo lỗi. Hihi.
tungbka vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 15-03-2010, 10:27 AM   #12
vanlv
Đệ tử 1 túi
 
Tham gia ngày: Oct 2009
Bài gửi: 25
:
Em đang tập viết code thử với ngắt chân RB0, các anh xem hộ đoạn này có sai ở đâu không. Em không có người hướng dẫn nên phải mày mò. Em đã enable_interrupts(INT_RB) ở main() rồi và chọn sườn âm.
#INT_RB
void rb_isr()
{
if(input(PIN_B0)==0)
{
tseconds++;
printf("Press any key to start\n");
delay_ms(50);
}
else {printf("Press any key to stop\n");delay_ms(50);}
}
vanlv vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 16-03-2010, 10:43 AM   #13
songphuongbmt
Nhập môn đệ tử
 
Tham gia ngày: Mar 2010
Bài gửi: 1
:
em đang viết code nhập số từ nút ấn từ posd B hiển thị 4led 7 đoạn sao mà nó chạy không đúng ai có chương trình viết trên ccs gưi cho em tham khao với "hepl" cảm ơn nhiều nhiều (Địa chỉ mail " SONGPHUONGBMT@GMAIL.COM)
songphuongbmt vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 29-03-2010, 02:07 PM   #14
steve7680768
Nhập môn đệ tử
 
Tham gia ngày: Mar 2010
Bài gửi: 1
:
Vấn đề vẫn tiếp tục với hệ thống của tôi ... Tôi đã sử dụng mã này ... Bây giờ những gì tôi cần phải làm ...?
__________________
STEVE
steve7680768 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 16-05-2010, 06:13 PM   #15
tungbka
Đệ tử 1 túi
 
Tham gia ngày: Jul 2009
Bài gửi: 11
:
Interrupts disabled during call to prevent re-entrancy: (@MUL1616)

Em đang viết chương trình nhận dữ liệu từ máy tính xuống để điều khiển cái động cơ. Nhưng sau khi biên dịch thì xuất hiện cảnh báo sau:
Interrupts disabled during call to prevent re-entrancy: (@MUL1616).
Em có tham khảo các nguồn thì được biết là do trong hàm ngắt và ngoài hàm ngắt em sử dụng lặp lại 1 hàm hay 1 biến gì đó, nhưng em tìm mãi không thấy sai chỗ nào. Mong các pro chỉ giúp. Em cám ơn nhìu.
Chương trình của em như sau:
(Sorry vì em không biết đưa code vào trong ô code ^^!)

Code:
#include <16f877a.h>
#include <def_877a.h>
#include <stdlib.h>
#fuses  NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT 
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8) 
#include <lcd_lib_4bit.c>
/*#define enter RA2
#define s_t   RA3
#define f_r   RA5
#define up    RE0
#define down  RE1
*/
void ht(int16 a);
//void ht1(int16 a);
void init();
void pid();
void nhapheso();
//void up_down();
int16 count, tocdo, C, temp, temp1, k, tocdodat ;
signed int16 e2=0;
signed int16 e1=0;
int16 e_sum;
int16 e_del;
int16 duty;
float Kp=0;
float Ki=0;
float Kd=0;
int flag=0;
float u, T=0.01;

unsigned char text[30], text2[5] ;
unsigned char a1[5], dem=0, i=0, j=0,i1;

#INT_RDA
void Receive_isr() 
{
text[dem]=getc();
if(text[dem]=='@') //kiem tra dieu kien ket thuc
   {
   flag =1;    //ket thuc nhan, bat co bao
   dem=0;
   }
else dem++;
}
#INT_EXT
void ngatR0()  {
        count++;//set_timer0(0);
      }
#int_timer1
void Timer11_isr() {                // Ham duoc goi khi TImer1 tran (65535->0)
                                   // Chu ky trich mau 0.01
    
      set_timer1(53036);
      tocdo= 30*(count + get_timer0());
     // printf("%ld\t",tocdo);
      count = 0;
      set_timer0(0);

   
    }
void main(){
init();
lcd_putcmd(0x01);
while(true){
                //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
      pid();
if(RC1==0) set_PWM1_duty(duty);
if(RC1==1) set_PWM1_duty(1023 - duty);  
lcd_putcmd(0x80);
ht(tocdo);
printf("n%4Lu",tocdo);


//lcd_putchar("hi");


}
}
void init()
{
   lcd_init();
   nhapheso();
   disable_interrupts(int_rda);
   disable_interrupts(global);
   setup_timer_0 (RTCC_DIV_1|RTCC_EXT_L_TO_H);  // Timer0 is Counter
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
   setup_ccp1(CCP_PWM);
   setup_timer_2(T2_DIV_BY_4, 255, 1);//4*4*256*1/20000000=204.8us=4.8khz
   set_timer0(0);
   set_timer1(53036);
   enable_interrupts(INT_RTCC);
   enable_interrupts(int_timer1);
   enable_interrupts(int_ext);
   ext_int_edge(L_TO_H);
   enable_interrupts(GLOBAL);
   lcd_putcmd(0x80);
   count=0;
   trisc=0;
   trisd=0;
   trisa=255;
   trisb=1;
   RC1=0;
   if(C==1) RC1=1;
   If(C==0) RC1=0;
   }
void pid(){
   e2 = tocdodat - tocdo;
   e_sum += e2;
//   e_del = e2 - e1;
//   e1 = e2;
   u = u + Kp*e2 + Ki*e_sum*T;
   if (u>24){
   u=24;
   e_sum -=e2;
   }
   if (u<0){
   u = 0;
   e_sum -=e2;
   }
  duty = u*1023/24;
}
void ht(long a) {
     int nghin,tram,chuc,dvi;
     nghin=a/1000;
     tram=(a%1000)/100;
     chuc=(a%100)/10;
     dvi=(a%10);
     lcd_putchar(nghin+48);
     lcd_putchar(tram+48);
     lcd_putchar(chuc+48);
     lcd_putchar(dvi+48);
}
void nhapheso(){
   lcd_putchar("nhap tu PC");
   enable_interrupts(int_rda);
   enable_interrupts(GLOBAL);
while(!flag) ;
if(flag){

              //if ((strchr(text,'T')) && (strrchr(text, '@')))
         
                text2[0] = text[0];
                text2[1] = text[1];
                text2[2] = text[2];
                text2[3] = text[3];
                text2[4] = text[4];
                tocdodat = atol(text2);
               
                //----------------------------------------
                  while (text[i] != 'P')
                    i++;
                  while (text[j] != 'I')
                    j++;
                  i1 = i;
                  temp = j - i;                  
                  for (i = 0; i < temp; i++)
                    a1[i] = text[i1 + i + 1];
                    
                  Kp = atof(a1);
                 
                  printf("P%f",Kp);
                   delay_ms(100);   
                  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
                  i = j;
                  while (text[j] != 'D')
                    j++;
                  i1 = i;
                  temp = j - i;                  
                  for (i = 0; i < temp; i++)
                    a1[i] = text[i1 + i + 1];
                    
                  Ki = atof(a1);
                  printf("I%f",Ki);
                     delay_ms(100);
                  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
                  i = j;
                  while (text[j] != 'C')
                    j++;
                  i1 = i;
                  temp = j - i;                  
                  for (i = 0; i < temp; i++)
                    a1[i] = text[i1 + i + 1];
                    
                  Kd = atof(a1);
                  printf("D%f",Kd);
                     delay_ms(100);
                  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
                  i = j;
                  while (text[j] != '@')
                    j++;
                  i1 = i;
                  temp = j - i;                  
                  for (i = 0; i < temp; i++)
                    a1[i] = text[i1 + i + 1];
                    
                  C = atol(a1);
                  printf("C%Lu",C);
                  flag=0;
                  i=0; j=0;
                  dem=0;
 
                  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
                                                
          } 

}

thay đổi nội dung bởi: namqn, 16-05-2010 lúc 08:02 PM.
tungbka vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 07:13 PM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam