本文實現了用潤和 HiHope Pegasus 3861 開發板實現 TCP 電子琴。
樣例運行的 OpenHarmony 源碼環境下載:
https://gitee.com/HiSpark/hi3861_hdu_iot_application通過本文您將了解:
HiHopePegasus 3861 開發環境選擇
HiHopePegasus 3861 連接 wifi
HiHopePegasus 3861 TCP 連接
HiHopePegasus 3861 環境監測板上蜂鳴器的控制
TCP電子琴樣例運行效果
3861 開發板作為 TCP 服務端與 TCP 客戶端(自己的設備)連接。
TCP 客戶端發送 12345678,控制開發板上環境拓展板上的蜂鳴器發出 duō lái mī fā suō lā xī duō 8 種音調。
樣例運行步驟
①下載源文件
https://gitee.com/from-north-to-north/open-armony-north/tree/master/潤和3861輕量系統TCP電子琴
將源文件文件放置在命名為 TCP_keyboard_demo 的文件夾下,將其放置在 OpenHarmony 輕量系統源碼 applicationssamplewifi-iotapp 目錄下。
②修改 net_params.h 文件的相關代碼
如下:
PARAM_HOTSPOT_SSID 設置為要連接的熱點名稱
PARAM_HOTSPOT_PSK 設置為要連接的熱點秘碼
PARAM_SERVER_ADDR 設置為要連接的作為 TCP 客戶端的設備 IP 地址
PARAM_SERVER_PORT 設置 3861開發板(作為 TCP 服務端) TCP socket端口號
③在源碼 applicationssamplewifi-iotappBUILD.gn 文件 features 字段下添加"TCP_keyboard_demo:TCP_keyboard_demo",使樣例 demo 加入編譯。
④根據 3861 開發板的 ip(串口打印出來的)和 net_params.h 中填寫的 TCP socket 端口號創建客戶端,連接 3861 開發板。
主控芯片對應關系
環境監測板上蜂鳴器與主控芯片(Pegasus)引腳的對應關系:GPIO9/PWM0。
源碼分析
文件說明:
tcp_server_test.c 文件解析:
#include#include #include #include //TCP連接的部分 #include"net_demo.h" #include"net_common.h" /********************環境監測板上蜂鳴器的部分*********************************/ #include"iot_gpio.h" #include"iot_pwm.h" #include"hi_pwm.h" #include"hi_io.h" #defineBEEP_PIN_NAME9 #defineBEEP_PIN_FUNCTION5 #defineWIFI_IOT_PWM_PORT_PWM00 #defineBEEP_PWM_DUTY50 /*********************************************************************/ #defineDELAY_1S(1) voidTcpServerTest(unsignedshortport) { /********************環境監測板上蜂鳴器的部分*********************************/ //初始化蜂鳴器 //蜂鳴器:GPIO9/PWM0 //環境監測板上蜂鳴器與主控芯片(Pegasus)引腳的對應關系GPIO9/PWM0 //IoTGpioInit用于初始化GPIO設備 IoTGpioInit(BEEP_PIN_NAME); //hi_io_set_func用于配置某個IO的復用功能 hi_io_set_func(BEEP_PIN_NAME,BEEP_PIN_FUNCTION); //IoTGpioSetDir用于設置GPIO引腳的方向 IoTGpioSetDir(BEEP_PIN_NAME,IOT_GPIO_DIR_OUT); //IoTPwmInit用于初始化PWM設備 IoTPwmInit(WIFI_IOT_PWM_PORT_PWM0); /***************************************************************************************/ ssize_tretval=0; intbacklog=1; intsockfd=socket(AF_INET,SOCK_STREAM,0);//TCPsocket intconnfd=-1; structsockaddr_inclientAddr={0}; socklen_tclientAddrLen=sizeof(clientAddr); structsockaddr_inserverAddr={0}; serverAddr.sin_family=AF_INET; serverAddr.sin_port=htons(port);//端口號,從主機字節序轉為網絡字節序 serverAddr.sin_addr.s_addr=htonl(INADDR_ANY);//允許任意主機接入,0.0.0.0 /*************************************綁定端口****************************************************/ retval=bind(sockfd,(structsockaddr*)&serverAddr,sizeof(serverAddr)); if(retval0)?{ ????????printf("_______________________________________ "); ????????printf("bind?failed,?%ld! ",?retval); ????????//關閉socket ????????printf("do_cleanup... "); ????????close(sockfd); ????}else{ ????printf("_______________________________________ "); ????printf("bind?to?port?%hu?success! ",?port); ????} /***********************************************************************************************/ ????retval?=?listen(sockfd,?backlog);?//?開始監聽 ????if?(retval?0)?{ ????????printf("_______________________________________ "); ????????printf("listen?failed! "); ????????//關閉socket ????????printf("do_cleanup... "); ????????close(sockfd); ????}else{ ????printf("_______________________________________ "); ????printf("listen?with?%d?backlog?success! ",?backlog); ????} /**************************************接受客戶端連接*********************************************************/ ????//?接受客戶端連接,成功會返回一個表示連接的 socket , clientAddr 參數將會攜帶客戶端主機和端口信息?;失敗返回?-1 ????//?此后的?收、發?都在?表示連接的 socket 上進行;之后 sockfd 依然可以繼續接受其他客戶端的連接, ????//??UNIX系統上經典的并發模型是“每個連接一個進程”——創建子進程處理連接,父進程繼續接受其他客戶端的連接 ????//??鴻蒙liteos-a內核之上,可以使用UNIX的“每個連接一個進程”的并發模型 ????//?????liteos-m內核之上,可以使用“每個連接一個線程”的并發模型 ????connfd?=?accept(sockfd,?(struct?sockaddr?*)&clientAddr,?&clientAddrLen); ????if?(connfd?0)?{ ????????printf("accept?failed,?%d,?%d ",?connfd,?errno); ????????//關閉socket ????????printf("do_cleanup... "); ????????close(sockfd); ????}else{ ????printf("_______________________________________ "); ????printf("accept?success,?connfd?=?%d! ",?connfd); ????printf("client?addr?info:?host?=?%s,?port?=?%hu ",?inet_ntoa(clientAddr.sin_addr),?ntohs(clientAddr.sin_port)); ????} /***********************************socket收、發的部分************************************************************/ ??//?后續?收、發?都在?表示連接的 socket 上進行; ????while?(1)?{ ???????char?request[128]?=?""; ???????//接收客戶端發送過來的數據 ???????retval?=?recv(connfd,?request,?sizeof(request),?0); ???????if?(retval?0)?{ ???????????printf("_______________________________________ "); ???????????printf("recv?request?failed,?%ld! ",?retval); ???????????//關閉與客戶端的連接 ???????????printf("do_disconnect... "); ???????????sleep(DELAY_1S); ???????????close(connfd); ???????????sleep(DELAY_1S);?//?for?debug ????????}else{ ???????????printf("_______________________________________ "); ???????????printf("The?data?received?from?the?client?is?%s? ",?request); ????????} ????????//發送數據到客戶端 ????????retval?=?send(connfd,?request,?strlen(request),?0); ????????if?(retval?<=?0)?{ ???????????printf("_______________________________________ "); ???????????printf("send?response?failed,?%ld! ",?retval); ???????????//關閉與客戶端的連接 ???????????printf("do_disconnect... "); ???????????sleep(DELAY_1S); ???????????close(connfd); ???????????sleep(DELAY_1S);?//?for?debug ????????}else{ ???????????printf("The?data?responsed?to?the?client?is?%s ",?request); ????????} /************************tcp?客戶端發送12345678控制不同的音調****************************/ ??????int?i=atoi(request);?//?將字符串request轉換成int類型 ??????hi_pwm_set_clock(PWM_CLK_XTAL);?//?設置時鐘源為晶體時鐘(40MHz,默認時鐘源160MHz) ????????switch?(i) ????????{ ?????????case?1: ??????????printf("Tone?is?1 "?); ????????/** ??????????* IoTPwmStart 根據給定的輸出頻率和占空比啟動指定端口的 PWM 信號輸出。 ??????????*?-?port?指示?PWM?設備的端口號 ??????????*?-?占空比?表示 PWM 信號輸出的占空比。值范圍為 1 到 99。 ??????????*?-?頻率?指示 PWM 信號輸出的頻率。 ????????**/ ??????????IoTPwmStart(WIFI_IOT_PWM_PORT_PWM0,?BEEP_PWM_DUTY,?2500);??//通過調節PWM?信號輸出的頻率控制蜂鳴器聲調(調到2000聽不到蜂鳴器聲音) ??????????usleep(500000);//音長 ??????????IoTPwmStop(WIFI_IOT_PWM_PORT_PWM0); ??????????break;?? ?????????case?2: ??????????printf("Tone?is?2 "); ??????????IoTPwmStart(WIFI_IOT_PWM_PORT_PWM0,?BEEP_PWM_DUTY,?3000); ??????????usleep(500000);//音長 ??????????IoTPwmStop(WIFI_IOT_PWM_PORT_PWM0); ??????????break;???? ?????????case?3: ??????????printf("Tone?is?3 "); ??????????IoTPwmStart(WIFI_IOT_PWM_PORT_PWM0,?BEEP_PWM_DUTY,?3500); ??????????usleep(500000);//音長 ??????????IoTPwmStop(WIFI_IOT_PWM_PORT_PWM0); ??????????break; ?????????case?4: ??????????printf("Tone?is?3 "); ??????????IoTPwmStart(WIFI_IOT_PWM_PORT_PWM0,?BEEP_PWM_DUTY,?4000); ??????????usleep(500000);//音長 ??????????IoTPwmStop(WIFI_IOT_PWM_PORT_PWM0); ??????????break; ?????????case?5: ??????????printf("Tone?is?5 "); ??????????IoTPwmStart(WIFI_IOT_PWM_PORT_PWM0,?BEEP_PWM_DUTY,?4500); ??????????usleep(500000);//音長 ??????????IoTPwmStop(WIFI_IOT_PWM_PORT_PWM0); ??????????break; ?????????case?6: ??????????printf("Tone?is?6 "); ??????????IoTPwmStart(WIFI_IOT_PWM_PORT_PWM0,?BEEP_PWM_DUTY,?5000); ??????????usleep(500000);//音長 ??????????IoTPwmStop(WIFI_IOT_PWM_PORT_PWM0); ??????????break; ?????????case?7: ??????????printf("Tone?is?7 "); ??????????IoTPwmStart(WIFI_IOT_PWM_PORT_PWM0,?BEEP_PWM_DUTY,?5500); ??????????usleep(500000);//音長 ??????????IoTPwmStop(WIFI_IOT_PWM_PORT_PWM0); ??????????break; ???????case?8: ??????????printf("Tone?is?8 "); ??????????IoTPwmStart(WIFI_IOT_PWM_PORT_PWM0,?BEEP_PWM_DUTY,?6000); ??????????usleep(500000);//音長 ??????????IoTPwmStop(WIFI_IOT_PWM_PORT_PWM0); ??????????break; ?????????default:break; ????????} /***********************************************************************************************/ ???????usleep(10); ????} /***********************************************************************************************/ } SERVER_TEST_DEMO(TcpServerTest);
審核編輯:湯梓紅
-
TCP
+關注
關注
8文章
1353瀏覽量
79055 -
開發板
+關注
關注
25文章
5032瀏覽量
97372 -
電子琴
+關注
關注
4文章
152瀏覽量
30496 -
鴻蒙
+關注
關注
57文章
2339瀏覽量
42805 -
HiHope
+關注
關注
0文章
63瀏覽量
3540
原文標題:鴻蒙開發板上實現TCP電子琴
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論