![]() |
|
![]() |
#1 |
Đệ tử 2 túi
|
Đo tốc độ phản hồi về Lcd
Chào các bác.Có chút vướng mắc,các bác giúp em với.
Mục đích:Điều khiển động cơ phản hồi tốc độ về LCD Thực hiện:Điều khiển được động cơ nhưng chưa phản hồi đc. Em không biết sau mỗi lần gọi ngắt có cần phải để 1 vòng while() để đợi ngắt không. Em dùng 16F877A,bây giờ điều khiển 1 kênh đã phải cần:TIMER2-PWM,TIMER 0:Đếm xung,TIMER1:Đếm thời gian,dùng để tính toán vận tốc. Vậy nếu em dùng động cơ thứ 2 phải làm thế nào,có thuật toán nào ko ạ. Có đoạn code và chương trình mô phỏng,các bác xem cho em: Code:
#include <16f877a.h> #include <def_877a.h> #FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT #use delay(clock=8000000) #include <lcd_lib_4bit.c> int16 cnt,cnt2,xung,v; int8 a,b,c; #int_TIMER0 void TIMER0_isr(void) //TIMER0 dem xung ve { set_timer0(255); if(tmr0if==1) { cnt++; tmr0if=0; } } #int_TIMER1 //TIMER1 dem tgian,tinh van toc void TIMER1_isr(void) { set_timer1(5565); if(tmr1if==1) { xung=get_timer0()*4; v=(xung*60)/((100*60*0.001)); tmr1if=0; } } void Lcd() { while(1) { a=(int)v/100; b=(int)(v-a*100)/10; c=(int)v%10; LCD_putcmd(0xC0); LCD_putchar("xung encoder"); LCD_putcmd(0x80); LCD_putchar(a+48); LCD_putcmd(0x81); LCD_putchar(b+48); LCD_putcmd(0x82); LCD_putchar(c+48); } } void Ngat() { set_timer0(255); setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4); enable_interrupts(INT_TIMER0); setup_timer_1(T1_INTERNAL|T1_DIV_BY_2); set_timer1(5565); enable_interrupts(INT_TIMER1); enable_interrupts(GLOBAL); } void PWM() { setup_timer_2(T2_DIV_BY_16,255,1); setup_ccp1(CCP_PWM); setup_ccp2(CCP_PWM); set_pwm1_duty(1000); set_pwm2_duty(1022); } void main() { set_tris_d(0); set_tris_a(0xff); //Cho tin hieu di vao RA4 set_tris_c(0); LCD_Init(); PWM(); Ngat(); Lcd(); delay_ms(100); } thay đổi nội dung bởi: popeye_ts22, 31-08-2008 lúc 12:56 AM. Lý do: Edit |
![]() |
![]() |
![]() |
#2 | |
Đệ tử 1 túi
Tham gia ngày: Sep 2010
Bài gửi: 16
: |
giúp code điều khiển động cơ
Trích:
|
|
![]() |
![]() |
![]() |
#3 |
Đệ tử 2 túi
|
Em đã sửa lại bài chỉn chu rùi,bác nào giúp đỡ em với.Đo vận tốc về nó cứ hiện 215,em thay đổi giá trị biến trở để thay đổi tốc độ mà hiển thị không thay đổi.
**.Em dùng encoder 100 xung/1 vòng
__________________
Best Regard. |
![]() |
![]() |
![]() |
#4 |
Đệ tử 5 túi
Tham gia ngày: Jun 2008
Bài gửi: 112
: |
![]() Mình vẫn theo dõi chuyên mục này đều đặn.Mình đợi mọi người trả lời câu hỏi của bạn Bean984 vì mình cũng đang thắc mắc như bạn, nhưng chưa thấy ai trả lời nên mình xin hỏi lại và nhờ mọi người trên diễn đàn chỉ giúp :
Làm thế nào để sử dụng chân RA4 như 1 chân I/O bình thường trong khi các chân còn lại của portRA vẫn sử dụng chức nằng đầu vào AD ?? trong ccs phải khai báo như nào ? vì nếu sử dụng câu lênh " set_tris_A(??) " để định thực hiện chức năng I/0 cho RA4 thì các chân còn lại của portRA cũng sẽ bị định dạng chức năng I/0 theo ,khi đó ko thể sử dụng làm cổng vào AD được ************ mong mọi người giúp đỡ .. Thanks ********
__________________
** xin hãy cho tôi là tượng đá ** Để muôn đời không nhớ thương ai ..!! |
![]() |
![]() |
![]() |
#5 | |
Đệ tử 6 túi
Tham gia ngày: May 2007
Bài gửi: 127
: |
Trích:
................... ................... ................... #bit TRISA4 = 0x85.4 .................. .................. .................. void main(void) { TRISA4=0 ; ............ ............ ............ }; |
|
![]() |
![]() |
![]() |
#6 | |
Trưởng lão PIC bang
|
Trích:
TRISA cho phép thiết lập trạng thái vào/ra cho từng chân riêng biệt, không có chuyện không thể dùng các chân RA khác độc lập với RA4. Bạn cần phân biệt rõ khái niệm chức năng I/O của chân với chế độ làm việc digital hay analog. Nếu chân làm việc ở chế độ analog, nó là ngõ vào (vì PIC không có chức năng xuất tín hiệu analog, thông qua một module DAC). Nếu chân làm việc ở chế độ digital, nó có thể là ngõ vào hay ngõ ra. Nếu bit tương ứng của TRISA là '1', chân đó là ngõ vào, ngược lại, bit tương ứng của TRISA là '0', chân đó là ngõ ra. Điều này đúng cho cả hai chế độ analog và digital của chân I/O. 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 |
|
![]() |
![]() |
![]() |
#7 |
Đệ tử 4 túi
|
em cũng đang theo dõi câu trả lời cho bài dk động cơ của bạn popeyee mà chưa thấy sư huynh nào trả lời.nên em hỏi vấn đề của em luôn.
em cũng làm 1 bài tập tương tự.nhưng làm mạch thật.em dùng chính tần số PWM để kiểm tra chương trình đếm xung từ động cơ.nhưng khi percent PWM là 100 hay 0% thì LCD luôn hiện số 175 còn khi có xung thì sai lệch rất lớn 40-50%.đây là đoạn code của em.các huynh chỉ giáo!!! Code:
#include <16f877a.h> //#include <def_877a.h> #fuses NOWDT,NOPROTECT,XT,NOLVP #use delay(clock=4000000) #define use_portd_lcd True #define portb=0x06 #define portd=0x08 #include <lcd.c> #define interr_per_second 20//khi set_timer1(15535)timer 1 16 bit=>65535-15535=50.000us #define interr_per_100ms 2//khi set_timer1(15535) int8 timer1over,value,percent; int16 so_vong,count,tram,chuc,donvi,ngan; #int_rtcc void interrupt_timer0()//dem so vong dong co { ++count; } #int_timer1 // ngat timer 1 khi timer 1 tran void interrupt_timer1() { if (--timer1over==0) { timer1over=interr_per_second; so_vong=(count*255+get_timer0());//100; //voi encoder la 100 xung tính trong 1 s count=0; set_timer0(15535); } } #int_ext void ngatngoai() // tang he so duty cho DC { if(percent==0)percent=0; else { percent=percent-5; value = percent*2; } } void tao_ma_so_vong() { ngan=so_vong/1000; tram=(so_vong-ngan*1000)/100; chuc=(so_vong-ngan*1000-tram*100)/10; donvi=so_vong%10; } void hienthi_lcd() { lcd_gotoxy(1,2); lcd_putc(ngan+0x30); lcd_putc(tram+0x30); lcd_putc(chuc+0x30); lcd_putc(donvi+0x30); } //ham main chinh main() { delay_ms(100); //tao thoi gian tre de khoi tao LCD lcd_init(); // khoi tao LCd // cac cong I O set_tris_a(0xff); //cho port a la port thu, su dung chan RA4 set_tris_b(0x01); output_b(0x01); //tao muc cao cho ngat ngoai set_tris_c(0); // enable cac timer setup_timer_0(rtcc_div_1|rtcc_ext_h_to_l); // timer 0 lam couter set_timer0(0); // gia tri dau timer 0 setup_timer_1(t1_internal|t1_div_by_1); // dung inter clock,dinh thoi gian 1 s set_timer1(15535); // gia tri de ngat xay ra 20lan/ 1 s // configue cac ngat enable_interrupts(global); //cho phep ngat enable_interrupts(int_rtcc); // ngat timer 0 enable_interrupts(int_timer1); // ngat timer 1 enable_interrupts(int_ext); // cho ngat ngoai ext_int_edge(h_to_l); // ngat ngoai canh xuong // khoi tao che do PWm setup_timer_2(t2_div_by_1,199,1); // t2div=1=>f=5khz,period=200 // setup_timer_2(t2_div_by_4,199,1); //t2div=4=>f=1250hz,period=200 // setup_timer_2(t2_div_by_16,199,1); //t2div=16=>f=312hz,period=200 setup_ccp1(CCP_PWM); // xung PWm tren chan CCP1 RC2 // khoi tao cac gia tri bien ban dau count=0; so_vong=0; timer1over=interr_per_second; value=200; // do phan cung dieu xung muc thap percent=100; //phan cung dung xung muc thap // tao mau cho lcd lcd_gotoxy(1,1); lcd_putc('s'); lcd_putc('o'); lcd_putc('-'); lcd_putc('v'); lcd_putc('o'); lcd_putc('n'); lcd_putc('g'); lcd_putc('-'); lcd_putc('1'); lcd_putc('s'); lcd_putc(':'); //bat dau vong lap while(1) { set_pwm1_duty(value); tao_ma_so_vong(); hienthi_lcd(); } } thay đổi nội dung bởi: cong1810, 02-09-2008 lúc 12:43 AM. |
![]() |
![]() |
![]() |
#8 |
Đệ tử 5 túi
Tham gia ngày: Jun 2008
Bài gửi: 112
: |
Thanks Lion !! mình làm như bạn hướng dẫn và mô phỏng proteus rất ổn....
__________________
** xin hãy cho tôi là tượng đá ** Để muôn đời không nhớ thương ai ..!! thay đổi nội dung bởi: picpen, 02-09-2008 lúc 09:33 AM. |
![]() |
![]() |
![]() |
#9 |
Đệ tử 5 túi
Tham gia ngày: Jun 2008
Bài gửi: 112
: |
![]() Công à ! mình chưa làm với encoder bao giờ lên ko thể góp ý với bạn về chương trình được .Nhưng mình thấy chương trình của bạn khá dài do viết mã cho LCD .bạn có thể dùng file LCD.C có sẵn trong thư viện CCS để cho chương trình ngắn gọn hơn, mọi người trên diễn đàn rễ đọc và chỉnh sửa giúp bạn. ví dụ nhé :
đoạn ct con này: Code:
void hienthi_lcd() { lcd_gotoxy(1,2); lcd_putc(ngan+0x30); lcd_putc(tram+0x30); lcd_putc(chuc+0x30); lcd_putc(donvi+0x30); } .............. .............. // tao mau cho lcd lcd_gotoxy(1,1); lcd_putc('s'); lcd_putc('o'); lcd_putc('-'); lcd_putc('v'); lcd_putc('o'); lcd_putc('n'); lcd_putc('g'); lcd_putc('-'); lcd_putc('1'); lcd_putc('s'); lcd_putc(':'); Printf( lcd_putc,"so_vong_1s:%d",value )
__________________
** xin hãy cho tôi là tượng đá ** Để muôn đời không nhớ thương ai ..!! |
![]() |
![]() |
![]() |
#10 |
Đệ tử 6 túi
Tham gia ngày: May 2007
Bài gửi: 127
: |
Công này đoạn code này gây ra lỗi sai :
//--------------------------------------------------------------- ngan=so_vong/1000; tram=(so_vong-ngan*1000)/100; chuc=(so_vong-ngan*1000-tram*100)/10; donvi=so_vong%10; //--------------------------------------------------------------- mình cũng đã từng gặp lỗi này , nhưng ko thể nào điều chỉnh được : nguyên nhân là do trình dịch CCS không sử lý được phép chia > 8 bit : vi du : unsigned char so1,so2,so3,so4 ; //--------------------------------------------------------- void tach_so( unsigned int data ) { so1 = data / 1000 ; so2 = (data % 1000)/100 ; so3 = ((data % 1000)%100)/10 ; so4 = ((data % 1000)%100)%10 ; } //---------------------------------------------------------- void main(void) { TRISA=0xff; TRISB=0xff; TRISC=0x00; TRISD=0x00; while(1) { tach_so( 1234 ) // cho kết quả hiển thị sai hien_thi( so1 ); hien_thi( so2 ); hien_thi( so3 ); hien_thi( so4 ); }; } //------------------------------------------------ nếu gán cho hàm : tach_so( 1234 ) ( data > 255 ) thì kết quả hiển thị sẽ sai , còn nếu gán cho hàm : tach_so( 223 ) ( data < 255 ) thì kết quả hiển thị đúng . |
![]() |
![]() |
![]() |
#11 |
Đệ tử 4 túi
|
cám ơn anh picpen.nhưng làm theo cách của anh thì em thấy có 1 hạn chế.có lẽ do em chưa tìm ra giải pháp.vần đề thế này.nếu dùng theo cách của anh.chương trình gọn gàng nhiểu lắm nhưng khi tốc độ thay đổi thì những số lớn sẽ ko bị mất.
vd thế này lcd hiển thị số 1111. sau đó vận tốc giảm còn 222.tức là chỉ 3 chữ số.nhưng trên lcd số thứ 4 ko bị mất.nên kết quả hiển thị là 2221. cách làm của em thế này Code:
lcd_gotoxy(1,1); Printf( lcd_putc,"so_vong_1s:%ld",so_vong); |
![]() |
![]() |
![]() |
#12 |
Đệ tử 6 túi
Tham gia ngày: May 2007
Bài gửi: 127
: |
Ko biết có bậc tiền bối nào gặp nỗi này chưa ???
nếu gặp rồi, sửa được nỗi trên xin chi giúp . |
![]() |
![]() |
![]() |
#13 |
Đệ tử 4 túi
|
anh lion!!
em dùng cách hiển thị theo anh PICPEN hướng dẫn.nó cũng hiện lên giống như vậy! dùng lệnh printf! vậy để em thử với tần số nhỏ hơn 255 thử xem.do em dùng xung PWM để kiểm tra! hì hì!! |
![]() |
![]() |
![]() |
#14 |
Đệ tử 4 túi
|
hix!!vẫn ko đúng.chắc em phải mua cái encoder làm cho đàng hoàng thôi!!thanks các huynh đã để tâm!!
|
![]() |
![]() |
![]() |
#15 |
Đệ tử 2 túi
|
Mình test mãi và cũng đang nghi ngờ chân tín hiệu của encoder.Bác nào biết giúp em sửa bài đo và phản hồi tốc độ về LCD với.(Bài bên page6)..
Thank's các bác..
__________________
Best Regard. |
![]() |
![]() |
![]() |
Ðiều Chỉnh | |
Xếp Bài | |
|
|