|
Tài trợ cho PIC Vietnam |
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 |
|
Ðiều Chỉnh | Xếp Bài |
13-01-2009, 12:31 AM | #1 |
Trưởng lão PIC bang
|
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. |
01-11-2009, 07:43 AM | #2 |
Đệ tử 6 túi
Tham gia ngày: Apr 2009
Bài gửi: 132
: |
thank bang chủ nhiều
|
24-01-2010, 08:40 AM | #3 |
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 |
24-01-2010, 10:40 AM | #4 |
Đệ 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
|
02-02-2010, 09:15 PM | #5 |
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é
|
02-02-2010, 09:35 PM | #6 |
Đệ 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ó đó.
|
05-03-2010, 11:12 AM | #7 |
Đệ 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 |
05-03-2010, 11:48 AM | #8 |
Trưởng lão PIC bang
|
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 |
05-03-2010, 11:21 PM | #9 |
Đệ tử 1 túi
Tham gia ngày: Jul 2009
Bài gửi: 11
: |
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. ^^
|
06-03-2010, 09:40 PM | #10 | |
Trưởng lão PIC bang
|
Trích:
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); } 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 |
|
06-03-2010, 10:59 PM | #11 |
Đệ 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.
|
15-03-2010, 10:27 AM | #12 |
Đệ 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);} } |
16-03-2010, 10:43 AM | #13 |
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)
|
29-03-2010, 02:07 PM | #14 |
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 |
16-05-2010, 06:13 PM | #15 |
Đệ 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. |
|
|