Tải bản đầy đủ (.pdf) (39 trang)

bài giảng thí nghiệm đo lường và điều khiển bằng máy tính2

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.71 MB, 39 trang )

THÍ NGHIỆM ĐO LƯỜNG VÀ ĐIỀU
KHIỂN BẰNG MÁY TÍNH
BTN #4: LẬP TRÌNH CARD USB GIAO TIẾP VỚI
MÁY TÍNH

THÁNG 4 NĂM 2018
BỘ MÔN TỰ ĐỘNG, KHOA ĐIỆN ĐIỆN TỬ - ĐẠI HỌC BÁCH KHOA TP.HCM


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

BTN #4: BÀI THÍ NGHIỆM LẬP TRÌNH CARD USB
GIAO TIẾP VỚI MÁY TÍNH
A. MỤC ĐÍCH THÍ NGHIỆM
• Biết cách lập trình vi điều khiển sử dụng phần mềm Keil-C.
• Biết cách lập trình chương trình C# bằng phần mềm Visual Studio.
• Lập trình giao tiếp giữa vi điều khiển và C# qua ch̉n USB.

B. CHUẨN BỊ THÍ NGHIỆM
• Sinh viên đọc kỹ các yêu cầu của mỗi bài thí nghiệm, xem sơ đồ mạch trước khi
lên lớp.

C. GIỚI THIỆU MÔ HÌNH THÍ NGHIỆM
Kit thí nghiệm cho được bố trí như Hình 1

Hình 1: Sơ đồ bố trí của kit thí nghiệm
Kít thí nghiệm được chia thành 12 khu vực:
-


Khu vực 1 – CPU: là khu vực bố trí card USB.
Khu vực 2 – HMI/METER: là khu vực bố trí màn hình HMI và các thiết bị hiển
thị
Khu vực 3 – AI: là khu vực bố trí tín hiệu Analog, gồm các ngõ vào Analog
AI1 và AI2; Điện áp thay đổi được VR1, và VR2.
Page |1


Bài TN4: Lập trình card USB

-

Biên soạn: TS. Nguyễn Trọng Tài

Khu vực 4 – ENCODER: là khu vực bố trí tín hiệu ngõ vào xung tốc độ cao.
Khu vực 5 – DI: là khu vực bố trí các nút nhấn và công tắc điều khiển.
Khu vực 6 – DO: là khu vực bố trí các LED hiển thị ngõ ra số
Khu vực 7 – AO: là khu vực bố trí các ngõ ra điều khiển ANALOG
Khu vực 8 – PWM-PTO: là khu vực bố trí các ngõ ra xung tốc độ cao PWM và
PTO cho phép điều khiển động cơ tốc độ, vị trí động cơ DC, SERVO, Bước
Khu vực 9 - SENSOR: là khu vực bố trí lắp đặt cảm biến
Khu vực 10: là khu vực bố trí các thiết bị cho phép kết nối mạng PLC
Khu vực 11: là khu vực nguồn áp cung cấp 24VDC và 5VDC
Khu vực 12: là khu vực ứng dụng điều khiển và hiển thị đèn giao thơng

D. THÍ NGHIỆM
I. Bài thí nghiệm 1: Lập trình vi điều khiển sử dụng Keil-C
❖ Tạo project với Keil-C:
- Chọn Project -> New µVision Project.
- Chọn vị trí lưu project và đặt tên project trong cửa sổ hiện ra.


Hình 2: Cửa sổ tạo project mới trong Keil-C
-

Chọn dòng vi điều khiển STMicroelectronics -> STM32F3 Series ->
STM32F373 -> STM32F373C8Tx
Page |2


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

Hình 3: Cửa sổ chọn dịng vi điều khiển
-

Chọn các pack CMSIS->CORE và Device->Startup, Variant của Device chọn
là Standalone như hình dưới:

Hình 4: Cửa sổ chọn các package trong Keil-C
Page |3


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

❖ Add file thư viện vào project:
- Trong folder DLDKMT_USB ở Desktop, chép folder Src, Inc, Middlewares và
Drivers vào folder chứa project.

- Sau khi hoàn thành các bước trên, folder chứa project bao gồm các folder như
hình dưới đây:

Hình 5: Folder chứa project

Hình 6: Các file trong folder Src

Page |4


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

Hình 7: Các file trong folder Inc
-

Click vào biểu tượng

trên thanh cơng cụ, một cửa sổ hiện ra

Hình 8: Cửa sổ quản lí các file trong project
Tạo group mới bằng cách click vào biểu tượng
:
Tạo group Application/User, nhấn nút Add Files và add các file .c trong folder
Src.
- Tạo group Middlewares/USB_Device_Library và add các file .c trong folder
Middlewares\ST\STM32_USB_Device_Library\Class\CustomHID\Src và
Middlewares\ST\STM32_USB_Device_Library\Core\Src.
- Tạo group Driver/Src và add các file sau từ folder

Drivers\STM32F3xx_HAL_Driver\Src:
stm32f3xx_hal.c
-

stm32f3xx_hal_adc.c
Page |5


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

stm32f3xx_hal_adc_ex.c
stm32f3xx_hal_cortex.c
stm32f3xx_hal_dac.c
stm32f3xx_hal_dac_ex.c
stm32f3xx_hal_dma.c
stm32f3xx_hal_flash.c
stm32f3xx_hal_flash_ex.c
stm32f3xx_hal_gpio.c
stm32f3xx_hal_i2c.c
stm32f3xx_hal_i2c_ex.c
stm32f3xx_hal_pcd.c
stm32f3xx_hal_pcd_ex.c
stm32f3xx_hal_pwr.c
stm32f3xx_hal_pwr_ex.c
stm32f3xx_hal_rcc.c
stm32f3xx_hal_rcc_ex.c
stm32f3xx_hal_tim.c
stm32f3xx_hal_tim_ex.c

stm32f3xx_hal_uart.c
stm32f3xx_hal_uart_ex.c
-

Nhấn OK

Page |6


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

Hình 9: Các file trong group Application/User

Hình 10: Các file trong group Middlewares/USB_Device_Library
Page |7


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

Hình 11: Các file trong group Driver/Src
❖ Add đường dẫn tới file header và các define:
-

Nhấn vào biểu tượng

trên thanh công cụ, một cửa sổ như hình dưới hiện ra


Page |8


Bài TN4: Lập trình card USB

-

Biên soạn: TS. Nguyễn Trọng Tài

Chọn tab C/C++, ta có cửa sổ như sau:

- Copy dòng dưới vào mục Define
USE_HAL_DRIVER,STM32F373xC
- Tiếp tục copy dòng dưới vào mục Include path
./Inc;./Drivers/STM32F3xx_HAL_Driver/Inc;./Drivers/STM32F3xx_HAL_Driver/Inc
/Legacy;./Middlewares/ST/STM32_USB_Device_Library/Core/Inc;./Middlewares/ST/
STM32_USB_Device_Library/Class/CustomHID/Inc;./Drivers/CMSIS/Device/ST/ST
M32F3xx/Include;./Drivers/CMSIS/Include
-

Cuối cùng ta có cửa sổ như sau:

Page |9


Bài TN4: Lập trình card USB

-


Biên soạn: TS. Nguyễn Trọng Tài

Chọn mục Debug, chọn ST-Link Debugger như hình vẽ.

P a g e | 10


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

-

Sau đó chọn Settings, một cửa sổ hiện ra, chọn tab Flash Download và nhấn
Add.

-

Trong cửa sổ hiện ra, chọn mục STM32F3xx Flash như hình vẽ dưới đây và
bấm Add và OK.

P a g e | 11


Bài TN4: Lập trình card USB

-

Biên soạn: TS. Nguyễn Trọng Tài


Trong cửa sổ Options for Target, chọn tab Utilities, click chọn Use Target
Driver for Flash Programming.

- Nhấn OK
❖ Viết chương trình trên vi điều khiển:
- Mở file main.c và sửa lại chương trình như hướng dẫn bên dưới.
- Đầu tiên, include các thư viện như dưới đây:
#include <math.h>
#include <stdio.h>
#include <stdint.h>
#include "stm32f3xx_hal.h"
#include "driver.h"
#include "usb_device.h"
#include "usbd_custom_hid_if.h"

-

Tiếp theo, khai báo các biến toàn cục như sau ở đầu chương trình:

P a g e | 12


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

static uint8_t DI_value;
static float AO_value[2];
static int AI_value[3];
static uint32_t C0_value;

static uint32_t DO_pwm_frequency[3];
static uint16_t Ts_ms =100;//ms
static uint8_t usb_rx_buffer[64];
static uint8_t usb_tx_buffer[17];
static volatile uint8_t usb_tx_flag = 0;
static volatile uint8_t usb_rx_flag = 0;

- Khai báo prototype của các hàm trong chương trình như sau:
void USB_RX_Interrupt(void);
void Sample_Timer_Interrupt(void);

-

Viết hàm main như bên dưới. Trong hàm main này, đầu tiên ta sẽ khởi tạo các
ngoại vi, cấu hình xung clock, sau đó, chương trình sẽ vào hàm while(1). Trong
hàm này, ta sẽ liên tục kiểm tra cờ usb_tx_flag và usb_rx_flag để thực hiện việc
điều khiển các ngoại vi:

int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock */
SystemClock_Config();

/* Initialize all configured peripherals */
GPIO_Init();
AI_Init();


P a g e | 13


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

DO_Init();
AO_Init();
Counter_Init();
MX_USB_DEVICE_Init();
Sample_Timer_Init();

while (1)
{
if(usb_tx_flag)
{
usb_tx_flag =0;
DI_value = DI_Read_All();
C0_value = Counter_Read();
AI_Read_All(AI_value);
/* DIN */
usb_tx_buffer[0]

=

DI_value;

usb_tx_buffer[1]


=

(uint8_t)(C0_value >> 24);

usb_tx_buffer[2]

=

(uint8_t)(C0_value >> 16);

usb_tx_buffer[3]

=

(uint8_t)(C0_value >> 8);

usb_tx_buffer[4]

= (uint8_t)(C0_value);

/* counter */

/* AIN */
usb_tx_buffer[5]

=

(uint8_t)(AI_value[0] >> 24);

usb_tx_buffer[6]


=

(uint8_t)(AI_value[0] >> 16);

usb_tx_buffer[7]

=

(uint8_t)(AI_value[0] >> 8);

usb_tx_buffer[8]

=

(uint8_t)(AI_value[0]);

usb_tx_buffer[9]

=

(uint8_t)(AI_value[1] >> 24);

usb_tx_buffer[10]

=

(uint8_t)(AI_value[1] >> 16);

usb_tx_buffer[11]


=

(uint8_t)(AI_value[1] >> 8);

usb_tx_buffer[12]

=

(uint8_t)(AI_value[1]);

P a g e | 14


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

usb_tx_buffer[13]

=

(uint8_t)(AI_value[2] >> 24);

usb_tx_buffer[14]

=

(uint8_t)(AI_value[2] >> 16);


usb_tx_buffer[15]

=

(uint8_t)(AI_value[2] >> 8);

usb_tx_buffer[16]

=

(uint8_t)(AI_value[2]);

USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS,usb_tx_buffer,17);
}
if (usb_rx_flag)
{
int i;
usb_rx_flag = 0;
switch (usb_rx_buffer[0])/* cmd id */
{
case 'N':/* DO, AO */
{
//DO
DO_Write_All(&usb_rx_buffer[1]);

//AO
AO_value[0] = ((float)usb_rx_buffer[9]*256+(float)usb_rx_buffer[10])/1000;
AO_value[1] = ((float)usb_rx_buffer[11]*256+(float)usb_rx_buffer[12])/1000;

AO_Write_All(AO_value);


//reset Counter
if (usb_rx_buffer[13] == 'R')
{
Counter_Reset();
}
break;

P a g e | 15


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

}
case 'F':/* pwm frequency */
{
for(i=0;i<3;i++)
{
DO_pwm_frequency[i]= (uint32_t)(usb_rx_buffer[i+1]);
}
DO_pwm_set_frequency(DO_pwm_frequency);
break;
}
case 'G':/* ADC 18 bit gain */
{
AI18_Set_Gain(usb_rx_buffer[1]);
break;
}

case 'T':/* sample time */
{
Ts_ms = ((int)usb_rx_buffer[1]<<8) + (int)usb_rx_buffer[2];
Sample_Timer_Set_Period(Ts_ms);
}
}
}
}
}

- Viết hàm USB_RX_Interrupt dưới hàm main:
void USB_RX_Interrupt(void)
{
int i;

P a g e | 16


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

USBD_CUSTOM_HID_HandleTypeDef
*myusb=(USBD_CUSTOM_HID_HandleTypeDef *)hUsbDeviceFS.pClassData;
//myusb->Report_buf[0]= numbers of byte data
for (i=0;i<myusb->Report_buf[0];i++)
{
usb_rx_buffer[i]=myusb->Report_buf[i+1];
}
usb_rx_flag = 1;

}

- Viết hàm Sample_Timer_Interrupt như bên dưới:
void Sample_Timer_Interrupt(void)
{
usb_tx_flag =1;
}

- Viết hàm _Error_Handler và hàm assert_failed như bên dưới:
void _Error_Handler(char *file, int line)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
P a g e | 17


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

{
/* USER CODE BEGIN 6 */

/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif
❖ Biên dịch chương trình và nạp chương trình
-

Nhấn Ctrl + S để save chương trình, click vào biểu tượng
trên thanh công
cụ hoặc nhấn F7 để biên dịch chương trình. Nếu biên dịch thành công, cửa sổ
Build Output sẽ hiện thông báo tương tự hình bên dưới.

-

Nhấn F8 hoặc nhấn vào biểu tượng
khiển.

để nạp chương trình xuống vi điều

II. Bài thí nghiệm 2: Tạo window form app C#
❖ Tạo project mới:

P a g e | 18


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài


❖ Add Reference (Thư viện) cho Windown Form:

P a g e | 19


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

- Chọn Browse sau đó kiếm theo đường link
C:\Program Files\LibUsbDotNet\LibUsbdotnet.dll

Như vậy là thư viện LibUsbDotNet đã được Add
❖ Tạo giao diện GUI
P a g e | 20


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

Tạo groupbox Connection
- Trong cửa sổ Toolbox bên tay trái, chọn tab Common Controls và kéo thả các
Button, Label, Textbox để tạo thành giao diện như hình sau.

-

Đặt thuộc tính Name của các textbox lần lượt là: txtProductName, txtVendorId,
txtProductId, txtManufacturer.
Đặt thuộc tính Name của Button Connect là btnConnect.

Khai báo thư viện

using LibUsbDotNet;
using LibUsbDotNet.Info;
using LibUsbDotNet.Main;

-

Khai báo biến toàn cục cho kết nối USB

P a g e | 21


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

namespace usbHID
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
#region Declaring Global Variable
public static UsbDevice myUsbDevice, myUsbDevice_temp;
UsbEndpointReader reader;
UsbEndpointWriter writer;
IAsyncResult result;

#endregion Declaring Global Variable

}
}

Chương trình con cần thiết để thiết lập kết nối và gửi nhận dữ liệu:
#region USB_DATA_RECEIVER_INIT
void USB_DATA_RECEIVER_INIT()
{
IUsbDevice wholeUsbDevice = myUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
wholeUsbDevice.SetConfiguration(1);
wholeUsbDevice.ClaimInterface(0);
}
//Open usb end point reader and writer
reader = myUsbDevice.OpenEndpointReader(ReadEndpointID.Ep01);
writer = myUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
//Set Interrupt service rountie for reader complete event
reader.DataReceived += (OnRxEndPointData);
reader.DataReceivedEnabled = true;
}
#endregion USB_DATA_RECEIVER_INIT

P a g e | 22


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài


#region USB DATA RECEIVER INTERRUPT SERVICE ROUTINE
Action<byte[]> UsbReceiverAction;
private void OnRxEndPointData(object sender, EndpointDataEventArgs e)
{
UsbReceiverAction = UsbReceiverActionFunction;
if ((myUsbDevice.IsOpen) && (reader != null))
{
result = this.BeginInvoke(UsbReceiverAction, e.Buffer);
}
}
private void UsbReceiverActionFunction(byte[] input)
{
// giữ liệu nhận sẽ lưu trong chuỗi input và sẽ xử lý số liệu tại đây
}
#endregion USB DATA RECEIVER INTERRUPT SERVICE ROUTINE

#region USB EXIT
private void Usb_exit()
{
reader.DataReceivedEnabled = false;
reader.DataReceived -= (OnRxEndPointData);
this.EndInvoke(ketthuc);
reader.Dispose();
writer.Dispose();
if (myUsbDevice != null)
{
if (myUsbDevice.IsOpen)
{
IUsbDevice wholeUsbDevice = myUsbDevice as IUsbDevice;

if (!ReferenceEquals(wholeUsbDevice, null))
{
wholeUsbDevice.ReleaseInterface(0);
}
myUsbDevice.Close();
}
myUsbDevice = null;
UsbDevice.Exit();
}
}
#endregion USB EXIT

Chương trình cho nút nhấn Connect

P a g e | 23


Bài TN4: Lập trình card USB

Biên soạn: TS. Nguyễn Trọng Tài

private void btnConnect_Click(object sender, EventArgs e)
{
if (btnConnect.Text == "Connect")
{
if (myUsbDevice == null)
{
UsbRegDeviceList allDevices = UsbDevice.AllDevices;
foreach (UsbRegistry usbRegistry in allDevices)
{

if (usbRegistry.Open(out myUsbDevice))
{
txtProductName.Text = myUsbDevice.Info.ProductString;
txtVendorId.Text =
myUsbDevice.Info.Descriptor.VendorID.ToString();
txtProductId.Text =
myUsbDevice.Info.Descriptor.ProductID.ToString();
txtManufacturer.Text =
myUsbDevice.Info.ManufacturerString;
USB_DATA_RECEIVER_INIT();
btnConnect.Text = "Disconnect";
timerSend.Enabled = true;
}
}
}
if (myUsbDevice == null)
{
MessageBox.Show("Device Not Found !!!", "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
else
{
Usb_exit();
btnConnect.Text = "Connect";
txtProductName.Text = "";
txtVendorId.Text = "";
txtProductId.Text = "";
txtManufacturer.Text = "";
txtPWM0.Text = "";

txtPWM1.Text = "";
txtPWM3.Text = "";
txtPWM6.Text = "";
txtPWM7.Text = "";
txtAI0.Text = "";
txtAI1.Text = "";
txtCounter0.Text = "";
timerSend.Enabled = false;
}
}

Form Closed
-

Chọn vào sự kiện để viết đoạn chương trình đóng ứng dụng

P a g e | 24


×