Bài viết này sẽ là về kết nối FTP giữa STM32F103C8T6 với máy chủ (server). Trong bài viết các bạn sẽ được hướng dẫn cách để upload file .txt đã tạo lên server hoặc download file .txt trên server về thông qua tập lệnh AT.
Giao thức FTP (File Transfer Protocol)
Nghe cái tên File Transfer Protocol chắc các bạn cũng hiểu giao thức này dùng để làm gì. FTP cung cấp một trong các chức năng cơ bản của Internet và là phương thức được quy định để chuyển các tệp giữa các máy tính. Đây cũng là cách thông dụng nhất để truyền file bởi vì giao thức FTP giúp truyền tải dữ liệu một cách đáng tin cậy và có hiệu quả cao.
Không đi sâu vào các kiến thức liên quan đến giao thức FTP (File Transfer Protocol), dưới đây là cách để thiết lập cũng như chương trình code để truyền file giữa STM32F103 với server (cụ thể ở đây là server TAPIT).
[HỌC ONLINE: LẬP TRÌNH VI ĐIỀU KHIỂN STM32, VI XỬ LÝ ARM CORTEX – M]
Kết nối phần cứng
STM32 | SIM800C |
Kết nối nguồn ngoài cho VCC (4V) | |
PA9 | RX |
PA10 | TX |
GND | GND |
– Ngoài ra nên có thêm 1 USB TTL để quan sát dữ liệu:
STM32 | USB TTL |
PA3 | TX |
PA2 | RX |
Các lệnh AT liên quan và mô tả ngắn gọn về các câu lệnh đó
AT command | Phản hồi của Sim | Mô tả |
AT+SAPBR | OK | Định cấu hình GPRS |
AT+FTPCID=1 | OK | Thiết lập profile FTP |
AT+FTPSERV=“*****” | OK | Thiết lập domain name hoặc địa chỉ IP của server. |
AT+FTPPORT=*** | OK | Thiết lập port của server |
AT+FTPUN=“*****” | OK | Tên người dùng để truy cập máy chủ FTP |
AT+FTPPW=“*****” | OK | Đặt mật khẩu để truy cập máy chủ FTP |
AT+FTPPUTNAME=“*****” | OK | Chọn tên file được upload |
AT+FTPPUTPATH=“*****” | OK | Chọn đường dẫn upload |
AT+FTPPUT | OK | Sử dụng để đưa một tệp vào Server |
AT+FTPGETNAME=“*****” | OK | Chọn tên file để download |
AT+FTPGETPATH=“*****” | OK | Chọn đường dẫn để download file |
AT+FTPGET | OK | Sử dụng để tải tệp về |
Tạo project với CubeMx và Keil uVision5
Bước 1: Chọn các chức năng cho ví dụ này: Serial wire (nạp code và debug), USART1 (hiển thị dữ liệu lên màn hình máy tính), USART2 (truyền nhận dữ liệu giữa MCU và Sim).
Bước 2: Kích chọn ô Configuration và thay đổi các thông số đã được highlight như hình dưới đây:
– Cấu hình cho UART1 và UART2 giống nhau:
Bước 3: Generate code
Chương trình truyền file qua FTP sử dụng Module Sim 800C
Khai báo và thay đổi các thông tin của server như host, port, username, password trong file main.c
0 1 2 3 4 5 6 |
/* FTP variables */ char APNCommand[100] = {0}; char FTPCommand[100] = {0}; char FTPServer[50] = "yourhost"; char FTPPort[6] = "21"; char Username[32] = "user"; char Pass[32] = "pass"; |
0 1 2 |
/* Sim variables */ char Sim_response[500] = {0}; char Sim_Rxdata[2] = {0}; |
0 1 2 |
/* File variables */ char fileName[20] = "yourfile.txt"; char filePath[50] = "/public_html/DATA/"; |
Ở mục /* USER CODE BEGIN PFP */, khai báo các hàm sau:
– int8_t Sim_sendCommand(char* command, char* response, uint32_t timeout):
- command: Lệnh gửi đi từ Sim
- response: Phản hồi mà người dùng muốn đối chiếu. Nếu response trùng với phản hồi của Sim thì hàm Sim_sendCommand sẽ trả về 1, ngược lại sẽ trả về 0
- timeout: Thời gian tối đa để đợi phản hồi từ Sim
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
int8_t Sim_sendCommand(char* command,char* response,uint32_t timeout) { uint8_t answer = 0, count = 0; deleteBuffer(Sim_response); uint32_t time = HAL_GetTick(); uint32_t time1 = HAL_GetTick(); HAL_UART_Transmit(&huart1, (uint8_t *)command, (uint16_t)strlen(command), 1000); HAL_UART_Transmit(&huart1,(uint8_t *)"\r\n",(uint16_t)strlen("\r\n"),1000); do { while(HAL_UART_Receive(&huart1, (uint8_t *)Sim_Rxdata, 1, 1000) != HAL_OK) { if(HAL_GetTick() - time > timeout) { return 0; } } time = HAL_GetTick(); Sim_response[count++] = Sim_Rxdata[0]; while((HAL_GetTick() - time < timeout)) { if(HAL_UART_Receive(&huart1, (uint8_t *)Sim_Rxdata, 1, 1000) == HAL_OK) { Sim_response[count++] = Sim_Rxdata[0]; time1 = HAL_GetTick(); } else { if(HAL_GetTick() - time1 > 100) { if(strstr(Sim_response,response) != NULL) { answer = 1; } else { answer = 0; } break; } } } } while(answer == 0); display(Sim_response); return answer; } |
– void Sim_configGPRSnFTP(void): Thiết lập kết nối GPRS và FTP profile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
void Sim_configGPRSnFTP(void) { if(Sim_sendCommand("AT","OK",5000)) { HAL_Delay(10); if(Sim_sendCommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\"","OK",5000)) //Configure GPRS { HAL_Delay(10); if(Sim_sendCommand("AT+SAPBR=3,1,\"APN\",\"CMNET\"","OK",5000)) { deleteBuffer(APNCommand); HAL_Delay(10); strcpy(APNCommand,"AT+SAPBR=3,1,\"USER\",\""); //Set username for APN strcat(APNCommand,Username); strcat(APNCommand,"\""); if(Sim_sendCommand(APNCommand,"OK",5000)) { deleteBuffer(APNCommand); HAL_Delay(10); strcpy(APNCommand,"AT+SAPBR=3,1,\"PWD\",\""); //Set password for APN strcat(APNCommand,Pass); strcat(APNCommand,"\""); if(Sim_sendCommand(APNCommand,"OK",5000)) { deleteBuffer(APNCommand); HAL_Delay(10); while(Sim_sendCommand("AT+SAPBR=1,1","OK",5000) != 1); //Open bearer + BO SUNG TIME OUT if(Sim_sendCommand("AT+FTPCID=1","OK",5000)) //Set FTP bearer profile identifier { strcpy(FTPCommand,"AT+FTPSERV=\""); //Set FTP server address strcat(FTPCommand,FTPServer); strcat(FTPCommand,"\""); if(Sim_sendCommand(FTPCommand,"OK",5000)) { deleteBuffer(FTPCommand); HAL_Delay(10); strcpy(FTPCommand,"AT+FTPPORT="); //Set FTP server port strcat(FTPCommand,FTPPort); if(Sim_sendCommand(FTPCommand,"OK",5000)) { deleteBuffer(FTPCommand); HAL_Delay(10); strcpy(FTPCommand,"AT+FTPUN=\""); //Set FTP username strcat(FTPCommand,Username); strcat(FTPCommand,"\""); if(Sim_sendCommand(FTPCommand,"OK",5000)) { deleteBuffer(FTPCommand); HAL_Delay(10); strcpy(FTPCommand,"AT+FTPPW=\""); //Set FTP password strcat(FTPCommand,Pass); strcat(FTPCommand,"\""); if(Sim_sendCommand(FTPCommand,"OK",5000)) { deleteBuffer(FTPCommand); HAL_Delay(10); display("Configuration done!\r\n"); } } } } } } } } } } } |
– void Sim_uploadFileFromFTP(char* data): Ghi dữ liệu data vào file có sẵn trên server, nếu file chưa tồn tại thì file sẽ tự động được tạo rồi ghi dữ liệu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
void Sim_uploadFileFromFTP(char* data) { deleteBuffer(FTPCommand); HAL_Delay(10); strcpy(FTPCommand,"AT+FTPPUTNAME=\""); //Set upload file name strcat(FTPCommand,fileName); strcat(FTPCommand,"\""); if(Sim_sendCommand(FTPCommand,"OK",5000)) { deleteBuffer(FTPCommand); HAL_Delay(10); strcpy(FTPCommand,"AT+FTPPUTPATH=\""); //Set upload file path strcat(FTPCommand,filePath); strcat(FTPCommand,"\""); if(Sim_sendCommand(FTPCommand,"OK",5000)) { if(Sim_sendCommand("AT+FTPPUT=1","+FTPPUT: 1,1,",30000)) { Sim_sendCommand("AT+FTPPUT=2,10","+FTPPUT: 2,10",30000); Sim_sendCommand(data,"+FTPPUT: 1,1",30000); Sim_sendCommand("AT+FTPPUT=2,0","+FTPPUT: 1,0",30000); } } } } |
– void Sim_downloadFileFromFTP(void): Đọc dữ liệu ở trong file trên server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
void Sim_downloadFileFromFTP(void) { deleteBuffer(FTPCommand); HAL_Delay(10); strcpy(FTPCommand,"AT+FTPGETNAME=\""); //Get file name strcat(FTPCommand,fileName); strcat(FTPCommand,"\""); if(Sim_sendCommand(FTPCommand,"OK",5000)) { deleteBuffer(FTPCommand); HAL_Delay(10); strcpy(FTPCommand,"AT+FTPGETPATH=\""); //Get file path strcat(FTPCommand,filePath); strcat(FTPCommand,"\""); if(Sim_sendCommand(FTPCommand,"OK",5000)) { deleteBuffer(FTPCommand); HAL_Delay(10); if(Sim_sendCommand("AT+FTPGET=1","+FTPGET: 1,1",30000)) { eof = 0; while(eof == 0) { Sim_sendCommand("AT+FTPGET=2,20","+FTPGET: 2,",30000); if(strstr(Sim_response,"+FTPGET: 2,0") != NULL) { eof = 1; } } } } } } |
– Hàm display(): hiển thị dữ liệu lên màn hình máy tính
0 1 2 3 |
void display(void* data) { HAL_UART_Transmit(&huart2,(uint8_t *)data,(uint16_t)strlen(data),1000); } |
– Hàm deleteBuffer(): xóa dữ liệu trong bộ đệm
0 1 2 3 4 5 6 7 |
void deleteBuffer(char* buf) { int len = strlen(buf); for(int i = 0; i < len; i++) { buf[i] = 0; } } |
Upload file
0 1 2 3 4 5 6 7 |
/* USER CODE BEGIN 2 */ Sim_configGPRSnFTP(); Sim_uploadFileFromFTP("a12b34c56d"); //Sim_downloadFileFromFTP(); HAL_Delay(3000); Sim_sendCommand("AT+SAPBR=0,1","OK",5000); //Close bearer /* USER CODE END 2 */ |
Link video demo:
Vì lí do bảo mật thông tin server nên từ giây 26 đến giây 51 màn hình hiển thị trên Hercules sẽ bị che lại
Download file
0 1 2 3 4 5 6 7 |
/* USER CODE BEGIN 2 */ Sim_configGPRSnFTP(); //Sim_uploadFileFromFTP("a12b34c56d"); Sim_downloadFileFromFTP(); HAL_Delay(3000); Sim_sendCommand("AT+SAPBR=0,1","OK",5000); //Close bearer /* USER CODE END 2 */ |
Kết quả:
Chúc các bạn thành công!
Xem thêm: Tổng hợp các bài hướng dẫn Lập trình vi điều khiển STM32 tại đây.
Ngoc Hang