Giải thích:
- Phần khởi động các module bao gồm:
o Khởi động Module LCD
o Khởi động Module UART
o Khởi động khối PWM.
o Khởi động Timer dùng để định thời gian lấy mẫu vận tốc và Counter để đếm xung từ Encoder.
o Enable ngắt toàn cục và ngắt do timer
- Mỗi lần có ngắt timer (kết thúc chu kì lấy mẫu), VDK sẽ đọc giá trị bộ đếm (Counter), Reset bộ đếm để bắt đầu lại từ đầu. Sau đó VDK tính
Khởi động các Modul Begin Ngắt timer? Dữ liệu từ PC? Đọc bộ đếm, Reset bộ đếm Nhận dữ liệu từ PC Tính giá trị ĐK theo PID Hiển thị Gửi vận tốc lên PC
toán các giá trị điều khiển PWM theo thuật toán PID nhờ hàm pid_control().
- Chương trình gửi dữ liệu lên PC gửi vận tốc hiện thời lên PC. - Nếu có dữ liệu từ PC (các thông số vận tốc, hệ số Ki, Kp,). Chương trình con điều khiển PID:
Áp dụng thuật toán PID số, thay giá trị uk bởi giá trị điều xung (vì điện áp trung bình ra tỉ lệ với chu kì nhiệm vụ (Duty Cycle)), ta có chương trình điều khiển như sau:
Chương trình con nhận dữ liệu từ máy tính:
Dữ liệu từ PC gửi xuống VDK qua cổng RS232 sẽ được lưu trong bộ đệm 16 byte., khi gọi hàm UART_1_bCmdCheck(), nếu kết thúc 1 chuỗi lệnh từ máy tính (kí tự ASCII CR 0DH) thì hà trả về giá trị 1, còn không hàm trả về giá trị 0. Ta dùng hàm này để kiểm tra dữ liệu từ máy tính đã nhận xong hay chưa. Nếu đã nhận đủ dữ liệu, ta gọi hàm UART_1_szGetParam() để đọc giá trị trước dấu phân cách để lấy mã lệnh (mã lệnh ở đây là S, P, I, D, R), sau đó gọi tiếp hàm này để lấy giá trị tiếp
void pid_control(){
e1=v_set-save_count;
P_Term=(kp*e1)/10; //K'p = 0.1 -> 5 khi kp = 1-50, tranh truong hop tinhs toan vuot khoi nguong cua integer
D_Term=(kd*((e1-e0)))/10; //K'd = 0.1 -> 5 khi kd = 1- 50 (e1-2*e00 +e0)) e00=e0; e0=e1; I_state=(I_state+e1)/10; I_Term=(ki*I_state)/10;//k'i = 0.01,0.02 ...1
PWM_set=PWM_set + P_Term + D_Term + I_Term; if (PWM_set>2000) PWM_set=2000;
if (PWM_set<0) PWM_set=0; PWM16_1_WritePeriod (2000);
PWM16_1_WritePulseWidth(PWM_set); }
VD: lệnh từ máy tính là P 10 (kí tự kết thúc: (Enter)) (Chú ý dấu phân cách (Space) giữa P và 10)
Gọi lần 1: UART_1_szGetParam()-> trả về chuỗi ‘P’ Gọi lần 2: UART_1_szGetParam()-> trả về chuỗi ‘10’
Đọc giá trị đầu tiên str[0] Begin Str[0]= ’S’ Str[0]= ’P’ Vân tốc = Dữ liệu từ PC Str[0]= ’I’ Str[0]= ’D’ Str[0]= ’D’ Kp = Dữ liệu từ PC Ki = Dữ liệu từ PC Kd = Dữ liệu từ PC Đóng Relaay đảo chiều động cơ End
Chương trình con hiển thị:
Chương trình hiển thị sẽ chuyển đổi các giá trị vận tốc, các hệ số Ki, Kp, Kd ra giá trị thích hợp để hiển thị.
Chương trình hiển thị dùng các hàm API:
LCD_1_Position(byte i,byte j); Dịch chuyển con trỏ tới vị trí hàng I cột j LCD_1_PrHexByte(byte); Hiển thị 1 byte ở dạng Hexa lên LCD
LCD_1_PrString(BYTE *s); hiển thị chuỗi s.
Chương trình gửi vận tốc lên máy tính
Trước khi gửi dữ liệu lên PC ta convert sang dạng chuỗi dùng hàm itoa(sp,tem1,10). void send_data_pc(){ int tem1; tem1=save_count*3; itoa(sp,tem1,10); UART_1_PutString(sp); }
5.3 Chương trình giao tiếp trên máy tính: Giao diện chương trình:
Mã nguồn chương trình:
Dim mang(1 To 50000) As Double Dim i As Double
Dim str As String Dim even As Integer Dim direction As Integer
Private Sub Command1_Click() MSComm1.Output = "O" MSComm1.Output = Chr(32) MSComm1.Output = "1" MSComm1.Output = Chr(13) End Sub
Private Sub Command2_Click() MSComm1.Output = "O" MSComm1.Output = Chr(32) MSComm1.Output = "0" MSComm1.Output = Chr(13) End Sub
Private Sub Check1_Click() MSComm1.Output = "R" MSComm1.Output = Chr(32)
If (direction = 1) Then 'Neu dang quay theo chieu thuan direction = 0 MSComm1.Output = "1" MSComm1.Output = Chr(13) Else direction = 1 MSComm1.Output = "0" MSComm1.Output = Chr(13) End If
End Sub
Private Sub Command3_Click() If MSComm1.PortOpen Then MSComm1.PortOpen = False End If
End End Sub
Private Sub Command4_Click() MyChart.Series(0).Clear i = 1
End Sub
Private Sub Command5_Click() frmsetting.Show
End Sub
Private Sub Exit_Click() End
End Sub
Private Sub Form_Load()
MSComm1.Settings = "115200,N,8,1" MSComm1.CommPort = 1 MSComm1.PortOpen = True ' frmsetting.Show str = "00" i = 1 direction = 1 End Sub
Private Sub KP_Click() End Sub
Private Sub MSComm1_OnComm()
If (MSComm1.CommEvent = comEvReceive) Then ' Text2.Text = MSComm1.Input
str = MSComm1.Input mang(i) = Val(str)
MyChart.Series(0).AddXY i, mang(i), "", vbRed Label8.Caption = str
'mang(i) = Asc(MSComm1.Input)
'MyChart.Series(0).AddXY i, mang(i), "", vbRed
'MyChart.Series(0).AddXY i, Val(Text6.Text), "", vbGreen
i = i + 1 End If End Sub
Private Sub Setting_Click() frmsetting.Show
End Sub
Private Sub Slider1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim kp As String kp = Slider1.Value MSComm1.Output = "P" MSComm1.Output = Chr(32) MSComm1.Output = kp MSComm1.Output = Chr(13) End Sub
Private Sub Slider1_Scroll() Text3.Text = Slider1.Value
End Sub
Private Sub Slider2_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim ki As String ki = Slider2.Value MSComm1.Output = "I" MSComm1.Output = Chr(32) MSComm1.Output = ki MSComm1.Output = Chr(13) End Sub
Private Sub Slider2_Scroll() Text4.Text = Slider2.Value End Sub
Private Sub Slider3_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
kd = Slider3.Value MSComm1.Output = "D" MSComm1.Output = Chr(32) MSComm1.Output = kd MSComm1.Output = Chr(13) End Sub
Private Sub Slider3_Scroll() Text5.Text = Slider3.Value End Sub
Private Sub Slider4_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
Dim speed As String speed = Slider4.Value MSComm1.Output = "S" MSComm1.Output = Chr(32) MSComm1.Output = speed MSComm1.Output = Chr(13) 'MSComm1.Output = Chr((Val(speed) \ 6) \ 256) ' MSComm1.Output = Chr((Val(speed) \ 6) Mod 256) '