Chia sẻ – Đo tốc độ động cơ dùng AT89C52 | Page 2

Đo tốc độ động cơ dùng AT89C52

Chia sẻ với các bạn mạch đo tốc độ động cơ dùng AT89C52, hiển thị bằng LCD16x2
– Đặt chính xác tốc độ mong muốn
– Giá thành thấp
– Nhiều tùy biến (có thể phát triển để tích hợp vào các hệ thống khác)

1 – Nguyên lý: Có hai nguyên lý cơ bản đo trực tiếp tốc độ quay như sau
(ngoài ra còn một số phương pháp gián tiếp khác)
xem file Nguyên lý
2 – Lựa chọn: 
Do yêu cầu đặt ra là: 
– Điều khiển cho nhiều cơ cấu điều tốc khác nhau,
– TG đáp ứng nhanh, 
– Tốc độ động cơ vừa phải (200Vg/Ph ~ 1200Vg/Ph) 
=> nên chọn PA đo (đếm) chu kỳ.
(tính toán sơ bộ KQ đo bằng bảng tính)
· Do không phải dân Toán, nên phải tính thủ công, hơn nữa bộ VXL 89xx, không có số thực !
Lệnh ĐK ra sẽ là dạng xung (rơ le / khởi động từ), độ rộng xung, TG trễ có thể đặt trước bằng các SW (điều chỉnh theo thực tế khi lắp đặt để đạt KQ tối ưu)
3 – Sơ đồ nguyên lý mạch điện & PCB (rất tiếc là không tìm thấy file vẽ đâu cả, nên đành mô tả bằng chức năng và Port – Bạn nào giúp vẽ lại cho đầy đủ – giúp các em SV)
– Vi xử lý AT89C52, với thạch anh 12MHz
– Đầu vào đếm xung: dùng cảm biến tiệm cận OMRON, đầu ra xung (có thể dùng photo diode dạng chữ U)
Xung nhận được đưa vào P3.2 (Ngắt ngoài INT0)
3.1 – Phần hiển thị LCD: 
Data 0~7 – Port P0 (0~7)
RS P3.7
RW P3.6
CE P3.5
3.2 – Phần điều khiển (phím bấm)
Nút tăng tốc độ P1.1
Nút giảm tốc độ P3.3
3.3 Phần nhận xung – có zener bảo vệ quá áp
INT0 P3.2
3.4 – Phần Lệnh ra (Tăng/ giảm tốc độ) – Qua tầng đệm, ĐK rơ le
Lệnh Tăng P3.0
Lệnh Giảm P3.1
3.5 – Phần cài đặt (Các SW gạt đặt chế độ)
+ Đặt số răng P2.0 ~P2.6 (Max = 128 răng), chỉ đặt 1 lần cho 1 động cơ cụ thể
+ Đặt TG trễ trước khi ra lệnh (0.6s, 1.2s, 2.5s, 5s)
Bit0DLP1.2
Bit1DLP1.3
+ Sai số cho phép (1%, 2%, 5%, 10%)
Bit0PC P1.4 
Bit1PC P1.5
· dưới ngưỡng sai số này, sẽ ko ra lệnh 
+ TG duy trì lệnh với 10% sai số (0.6s, 1.2s, 2.5s, 5s)
Bit0CTP1.6
Bit1CTP1.7
+ Ngưỡng sai số để duy trì lệnh (>15%, >30%)
Bit30 P2.7
· Khi sai số tốc độ lớn hơn ngưỡng này, lệnh ra sẽ duy trì liên tục
3.6 – Nguồn nuôi: dùng biến áp 220/12, cầu, lọc và 7805
4 – Phần mềm 89C52
Giải thích cấu trúc cơ bản của chương trình:
– Ngắt ngoài INT0, nhận biết xung: với xung thứ nhất sẽ bắt đầu đếm, với xung thứ 2=dừng đếm. (số đếm x T xung = chu kỳ T)
– Timer T0, xử dụng như một bộ đếm 16bit (đếm xung)
– Timer T1, xử dụng như một bộ định kỳ kiểm tra, nhận biết tốc độ quay quá chậm hoặc động cơ đang dừng (do không nhận được xung ngắt ngoài)
– và các thủ tục (function) khác như, so sánh, nhận lệnh, kết xuất LCD v.v.
(code đầy đủ trong file attach, dịch bằng MBUG.EXE)
· Nhược điểm của ngôn ngữ Assembler là hơi rối (vì ko có cấu trúc rõ ràng)
· Ưu điểm là giúp hiểu biết “tường tận” về cấu trúc VXL, và đôi lúc CT nhanh hơn
Kết quả: 
Đã sử dụng ổn định trong nhà máy SX cao su (có rất nhiều động cơ cần đồng bộ tốc độ)
Sai số tốc độ trong phạm vi cho phép.

MenuMsg01:DB Clr_lcd,L1_p1,”SPEED RPM”,L2_p1,”SET RPM”,000h
LowMsg: DB L1_p9,” Low”,000h
HighMsg:DB L1_p9,”High”,000h
LCD_MSG_CMD: 
Clr A ; Clear Index 
Movc A,@A+Dptr ; Get byte pointed by Dptr 
Inc Dptr ; Point to the next byte 
Jz LCD_Msg_end ; Return if found the zero (end of stringz) 

Cjne A,#001h,Lcd_Msg1 ; Check if is a Clear Command 
LCall CmdWrite ; If yes, write it as command to LCD 
SJmp Lcd_Msg_CMD ; Go get next byte from stringz 
Lcd_Msg_end:
Ret 
Data16_to_LCD:
Mov temp1,A ; save position
Lcall Hex2Bcd ; convert to BCD
Lcall Bcd2Str ; convert BCD to Str, result Data_Str
Mov A,temp1 ; restore position
LCall CmdWrite
Mov R0,#Data_Str ; index string of word
LCall Data2LCD
ret
Hex2BCD:
Mov BCD_B1,#000h
Mov BCD_B2,#000h
Mov BCD_B3,#000h
Clr C 
Inc R0

Mov A,@R0 ; @R0=high byte
JNB ACC.7, NextB15 
Mov Dptr,#b15
LCall Add3byte
NextB15:
Mov A,@R0 ; 
JNB ACC.6, NextB14
Mov Dptr,#b14
LCall Add3byte
NextB14:
Mov A,@R0 ; 
JNB ACC.5, NextB13
Mov Dptr,#b13
LCall Add3byte
NextB13:
Mov A,@R0 ; 
JNB ACC.4, NextB12
Mov Dptr,#b12
LCall Add3byte
NextB12:
Mov A,@R0 ; 
JNB ACC.3, NextB11
Mov Dptr,#b11
LCall Add3byte
NextB11:
Mov A,@R0 ; 
JNB ACC.2, NextB10
Mov Dptr,#b10
LCall Add3byte
NextB10:
Mov A,@R0 ; 
JNB ACC.1, NextB09
Mov Dptr,#b09
LCall Add3byte
NextB09:
Mov A,@R0 ; 
JNB ACC.0, NextB08
Mov Dptr,#b08
LCall Add3byte
NextB08:
Dec R0

Mov A,@R0 ; @R0=Low byte
JNB ACC.7, NextB07
Mov Dptr,#b07
LCall Add3byte
NextB07:
Mov A,@R0 ; @R0=Low byte
JNB ACC.6, NextB06
Mov Dptr,#b06
LCall Add3byte
NextB06:
Mov A,@R0 ; @R0=Low byte
JNB ACC.5, NextB05
Mov Dptr,#b05
LCall Add3byte
NextB05:
Mov A,@R0 ; @R0=Low byte
JNB ACC.4, NextB04
Mov Dptr,#b04
LCall Add3byte
NextB04:
Mov A,@R0 ; @R0=Low byte
JNB ACC.3, NextB03
Mov Dptr,#b03
LCall Add3byte
NextB03:
Mov A,@R0 ; @R0=Low byte
JNB ACC.2, NextB02
Mov Dptr,#b02
LCall Add3byte
NextB02:
Mov A,@R0 ; @R0=Low byte
JNB ACC.1, NextB01
Mov Dptr,#b01
LCall Add3byte
NextB01:
Mov A,@R0 ; @R0=Low byte
JNB ACC.0, NextB00
Mov Dptr,#b00
LCall Add3byte
NextB00:
Ret
Bcd2Str:
Setb BlkFirst ;
Mov R0,#BCD_byte ; index BCD word (sourse)
Mov R1,#Data_Str ; index Str (Destination)

;—- danh cho 5 digit 
; Mov A,@R0 ; Get byte highest
; Anl A,#00Fh
; JNZ Num5
; JNB BlkFirst,Num5
; Mov A,#’ ‘ ; insert blank if=0
; Sjmp Cont5
;Num5: Clr BlkFirst
; LCall X2A ; digit 5
;Cont5: Mov @R1,A
;
; Inc R1 ; next digit
;——–

Inc R0 ; Midle byte
Mov A,@R0 ;
Swap A
Anl A,#00Fh
JNZ Num4
JNB BlkFirst,Num4
Mov A,#’ ‘ ; insert blank if=0
Sjmp Cont4
Num4: Clr BlkFirst
LCall X2A ; digit 4
Cont4: Mov @R1,A

Inc R1 ; next digit
Mov A,@R0 ;
Anl A,#00Fh
JNZ Num3
JNB BlkFirst,Num3
Mov A,#’ ‘ ; insert blank if=0
Sjmp Cont3
Num3: Clr BlkFirst
LCall X2A ; digit 3
Cont3: Mov @R1,A

Inc R0 ; lowest byte
Inc R1 ; next digit
Mov A,@R0 ;
Swap A
Anl A,#00Fh
JNZ Num2
JNB BlkFirst,Num2
Mov A,#’ ‘ ; insert blank if=0
Sjmp Cont2
Num2: Clr BlkFirst
LCall X2A ; digit 2
Cont2: Mov @R1,A

Inc R1 ; next digit
Mov A,@R0 ;
LCall X2A ; digit 1
Mov @R1,A

Inc R1
Mov @R1,#000h ; end of string
ret
Data2LCD:
Clr A ; Clear Index 
Mov A,@R0 ; Get byte pointed by R0
Inc R0 ; Point to the next byte 
Jz LCD_data_9 ; Return if found the zero (end of stringz) 
Cjne A,#07Fh,Not_EQ_data ; Data or Address? If A > 7Fh is address.
Sjmp Lcd_data_Data_1 ; if A = 7Fh (Data) 
Not_EQ_data:
Jc Lcd_data_Data_1 ; if A < 7Fh (data)
LCall CmdWrite ; if A > 7Fh, it is address CMD
SJmp Data2LCD ; Go get next byte from stringz 
Lcd_data_Data_1:
LCall DataWrite ; It was data, write it to Lcd 
SJmp Data2LCD ; Go get next byte from stringz 
Lcd_data_9:
Ret ; Retu

///////đây là chương trình chính////////// ở trên là các trương trình con////////////////////////////////

Mov Dptr,#MenuMsg01 ; first time
LCall LCD_Msg_CMD
Mov R0,#Speed ; index word
Mov A,#L1_p9 ; position of Data
Lcall Data16_to_LCD

Mov R0,#SetSpeed ; index word
Mov A,#L2_p9 ; position of Data
Lcall Data16_to_LCD

bạn giải thích giùm mình đoạn này đc ko?

Chương trình trên làm nhiều việc (như đã mô tả), Bạn cần cắt/ghép theo yêu cầu của Bạn. 
(nếu mình nhớ không nhầm thì Bạn cần phím bấm tăng giảm gì đó, không phải tốc độ động cơ ?!)
VD: copy lấy đoạn nhận phím và đoạn hiển thị LCD. muốn biến tăng và giảm thì thêm dòng lệnh asm vào v.v.

mình đang điều khiển động cơ bước, gặp vấn đề khó khăn ở hiển thị LCD. ví dụ: Ban đầu động cơ chạy vận tốc 40v/p,trên màn hình hiển thị 40v/p. ấn phím tăng động cơ tăng lên 10v/p.khi đó trên màn hình LCD 50v/p, tiếp tục nếu ấn thì sẽ là 60v/p. Mình muốn hiển thị như vậy

mình muốn hỏi cách hiển thị: tốc độ tăng lên làm như thế nào thôi.
ví dụ:
DONG_3: DB ‘TOC DO : 0 V/P ‘,0H
DONG_4: DB ‘TOC DO : 10 V/P’,0H
DONG_5: DB ‘TOC DO : 20 V/P’,0H
DONG_6: DB ‘TOC DO : 30 V/P’,0H
DONG_7: DB ‘TOC DO : 40 V/P’,0H
DONG_8: DB ‘TOC DO : 50 V/P’,0H
DONG_9: DB ‘TOC DO : 60 V/P’,0H
ban đầu mình cho hiển thị DONG_5, ấn phím tăng nó sẽ hiển thị DONG_6.Đây là cách mình suy nghĩ, nhưng làm chưa được.Bạn có cách nào hướng dẫn cho mình đơn giản để mình làm.Mình cảm ơn.chương trình bạn mình cũng đã xem và nghiên ngẫm nhưng ko hiểu lắm.Thật sư là vậy

đây là chương trình của e viết để điều khiển tăng tốc độ động cơ,mà ko đúng a xem giúp e vơi?
ORG 0H
JMP main

DELAY_AMS:
MOV R6,A
HET_1S: mov th0,#high(-50000) ;50000 micro second, xtal 12MHz
mov tl0,#low(-50000)
setb tr0
jnb tf0,$ ; Cho mình h?i ch? này
clr tr0
clr tf0
djnz r6,HET_1S
ret
START:
SETB P3.0
MOV P1,#0AH
LCALL DELAY_AMS
CLR P3.0
MOV P1,#09H
LCALL DELAY_AMS
SETB P3.0
MOV P1,#05H
LCALL DELAY_AMS
CLR P3.0
MOV P1,#06H
LCALL DELAY_AMS
RET
MAIN: 
MOV TMOD,#11H
KT: 
JNB P3.4,START_DC
JMP KT
START_DC:
MOV A,#5
START_DC1:
LCALL START
JNB P3.2,TANG_DC

JMP START_DC1
RET
GIAM_DC:
INC A
CJNE A,#30,EXIT
MOV A,#11
EXIT:RET
TANG_DC:

DJNZ A,EXIT1
MOV A,#1
EXIT1:RET

END

Bài viết liên quan

Thông tin tác giả

Thêm bình luận