• NL6621 实现获取天气情况


    一、主要完成的工作

    1、建立TASK

    1. INT32 main(VOID)
    2. {
    3. /* system Init */
    4. SystemInit();
    5. OSTaskCreate(TestAppMain, NULL, &sAppStartTaskStack[NST_APP_START_TASK_STK_SIZE -1], NST_APP_TASK_START_PRIO);
    6. OSStart();
    7. return 1;
    8. }

    2、application test task

    1. VOID TestAppMain(VOID * pParam)
    2. {
    3. demo_gpio_init(); //初始化LCD GPIO
    4. InitLCD(); //初始化屏幕
    5. clrScr(VGA_BLACK); //清屏
    6. GUI_Write16CnCharMatrix(0,160,"初始化...... ",VGA_BLUE,VGA_BLACK);
    7. pLinkUpSem = OSSemCreate(0);
    8. InfSysEvtCBSet(AppEvtCallBack);
    9. InfLoadDefaultParam();
    10. sys_thread_new("weatherThread", weatherThread, NULL, NST_TEST_APP_TASK_STK_SIZE, TCPIP_THREAD_PRIO + 4);
    11. while (1)
    12. { /* Task body, always written as an infinite loop. */
    13. OSTimeDly(20);
    14. DBGPRINT_LWIP(DEBUG_INFO, "TestApp RxDataCnt=%d, SendDataCnt=%d.\n", RxDataCnt, SendDataCnt);
    15. }
    16. }

    3、void weatherThread(void *arg)

    1. void weatherThread(void *arg)
    2. {
    3. char* buff,*http_data;
    4. DBGPRINT(DEBUG_TRACE, " ********************** weatherThread ********************* \n\r");
    5. connectWifi(); //连接WIFI
    6. buff=TestWeatherApi(); //从网页API获得天气数据
    7. printf("%s\r\n", buff);
    8. http_data=https_get_data(buff); //获得JSON部分
    9. mem_free(buff);
    10. printf("[http_data]:%s\r\n", http_data);
    11. extract_all_from_json(http_data); //解析JSON数据
    12. mem_free(http_data);
    13. //LCD显示
    14. GUI_Write16CnCharMatrix(5,20,"日期:",VGA_WHITE,VGA_BLACK);
    15. GUI_Write16CnCharMatrix(53,20,city_weather.date,VGA_BLUE,VGA_BLACK);
    16. GUI_Write16CnCharMatrix(5,60,"城市:",VGA_WHITE,VGA_BLACK);
    17. GUI_Write16CnCharMatrix(53,60,city_weather.city,VGA_BLUE,VGA_BLACK);
    18. GUI_Write16CnCharMatrix(5,100,"温度:",VGA_WHITE,VGA_BLACK);
    19. GUI_Write16CnCharMatrix(53,100,city_weather.tem,VGA_BLUE,VGA_BLACK);
    20. while(1)
    21. {
    22. OSTimeDly(500);
    23. }
    24. }

     4、void connectWifi(void)

    1. void connectWifi(void)
    2. {
    3. UINT8 Err;
    4. InfWiFiStop();
    5. OSTimeDly(10);
    6. InfNetModeSet(PARAM_NET_MODE_STA_BSS);
    7. InfAuthModeSet(PARAM_AUTH_MODE_WPA2PSK);
    8. //此处根据实际修改SSID/PASSWORD
    9. InfSsidSet("SSID",4); /* set ssid */
    10. InfKeySet(0, "PASSWORD",8); /* set pw */
    11. InfEncModeSet(PARAM_ENC_MODE_AUTO);
    12. InfConTryTimesSet(0); /* set trytime */
    13. InfWiFiStart();
    14. //Waiting for connect success
    15. OSSemPend(pLinkUpSem, 0, &Err);
    16. }

    5、char*  TestWeatherApi(void)

    1. #define HTTP_HOST "v1.yiketianqi.com"
    2. #define HTTP_URL "api?unescape=1&version=v61&appid=此处替换自己的ID&appsecret=此处替换自己的key"
    3. #define HOST_PORT "80"
    4. static const char* REQUEST = "GET " "/%s" " HTTP/1.1\r\n"
    5. "Host: " "%s" ":" HOST_PORT "\r\n"
    6. "User-Agent: AiPi-DSL_Dashboard\r\n"
    7. "\r\n";
    8. char* TestWeatherApi(void)
    9. {
    10. char* https_request_handle = mem_malloc(512);
    11. char *recv_data;
    12. int sock;
    13. UINT32 TargetIp;
    14. struct sockaddr_in server_addr;
    15. ip_addr_t hostip;
    16. netconn_gethostbyname(HTTP_HOST, &hostip);
    17. DBGPRINT_LWIP(DEBUG_TRACE, "HTTP_HOST:%s,IP:%d\n",HTTP_HOST,hostip.addr);
    18. TargetIp =hostip.addr;
    19. DBGPRINT_LWIP(DEBUG_TRACE, "TargetIp:%d\n",TargetIp);
    20. /* 分配用于存放接收数据的缓冲 */
    21. recv_data = mem_malloc(1024*4);
    22. if (recv_data == NULL)
    23. {
    24. DBGPRINT_LWIP(DEBUG_ERROR, "TCP Client memory ERR\n");
    25. return 0;
    26. }
    27. /* 一、创建一个socket,类型是SOCKET_STREAM,TCP类型 */
    28. if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    29. {
    30. /* 创建socket失败 */
    31. DBGPRINT_LWIP(DEBUG_ERROR, "TCP Client Socket error\n");
    32. /* 释放接收缓冲 */
    33. mem_free(recv_data);
    34. return 0;
    35. }
    36. /* 初始化预连接的服务端地址 */
    37. server_addr.sin_family = AF_INET;
    38. server_addr.sin_port = htons(atoi(HOST_PORT));
    39. server_addr.sin_addr.s_addr= TargetIp;
    40. memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
    41. /* 二、连接到服务端 */
    42. if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
    43. {
    44. /* 连接失败 */
    45. DBGPRINT_LWIP(DEBUG_TRACE, "TCP Client connect error !");
    46. lwip_close(sock);
    47. ///*释放接收缓冲 */
    48. mem_free(recv_data);
    49. return 0;
    50. //OSTimeDly(2000);
    51. }
    52. else
    53. {
    54. DBGPRINT_LWIP(DEBUG_TRACE, "TCP Client connect OK!\n");
    55. }
    56. memset(https_request_handle, 0, 256);
    57. sprintf(https_request_handle, REQUEST, HTTP_URL, HTTP_HOST);
    58. /* 三、http请求 */
    59. if(write(sock, https_request_handle, strlen(https_request_handle))<0)
    60. {
    61. DBGPRINT_LWIP(DEBUG_TRACE, "http write error !");
    62. close(sock);
    63. }
    64. /* 四、读http返回结果 */
    65. read(sock, recv_data, 1024*4);
    66. shutdown(sock, SHUT_RDWR);
    67. close(sock);
    68. mem_free(https_request_handle);
    69. return recv_data;
    70. }

    6、static char* https_get_data(const char* https_request_data)

    1. static char* https_get_data(const char* https_request_data)
    2. {
    3. char* request_data = https_request_data;
    4. static char* https_data;
    5. char* request_value;
    6. size_t i;
    7. https_data = mem_malloc(1024*3);
    8. memset(https_data, 0, 1024*3);
    9. request_data += 2;
    10. request_value = strtok(request_data, "\n");
    11. for (i = 0; i < 15; i++)
    12. {
    13. if (i==14) strcpy(https_data, request_value);
    14. memset(request_value, 0, strlen(request_value));
    15. request_value = strtok(NULL, "\n");
    16. }
    17. return https_data;
    18. }

    7、json解析

    1. void extract_item_from_json(const char *json_str,char *itemname,char *target)
    2. {
    3. char *start = strstr(json_str, itemname); // 查找"cityEn":"
    4. char *end;
    5. size_t len=20;
    6. char item[20]; // +1 for null terminator
    7. if (start != NULL) {
    8. start += strlen(itemname); // 跳过itemname
    9. end = strchr(start, '"'); // 查找下一个双引号
    10. if (end != NULL) {
    11. // 提取
    12. len = end - start;
    13. strncpy(item, start, len);
    14. item[len] = '\0'; // 添加字符串结束符
    15. printf("Item: %s\n", item);
    16. strncpy(target, item, len);
    17. target[len] = '\0'; // 添加字符串结束符
    18. }
    19. } else {
    20. printf("Item[%s] not found in the JSON string.\n",itemname);
    21. }
    22. }
    23. void extract_all_from_json(const char *json_str)
    24. {
    25. extract_item_from_json(json_str,"\"cityEn\":\"",city_weather.city);
    26. extract_item_from_json(json_str,"\"tem\":\"",city_weather.tem);
    27. extract_item_from_json(json_str,"\"date\":\"",city_weather.date);
    28. }

    二、说明

    1、NL6621 SDK二次开发,还是用KEIL4吧,KEIL5编译太慢了。

    2、没用CJSON,不是不想用,尝试了好长时间还是用不了CJSON,最后JSON自己解析了。

    3、编译的bin文件,不要超过192k,否则没法烧录,编译也会失败。

    4、scatter_loader.scat没有为适应NuDevTool ver1.11.0.exe修改,需要用bootTool.exe或bootTool_Ack_0822.exe烧录。

    1. ; 0x10100-0x40000 for download SRAM FW(including 32KB for customer), interrupt vector locate in 0x10100
    2. LOAD_REGION 0x00010100 0x0002FF00 { ; load region size_region
    3. ROM 0x00010100 0x0002FF00 { ; load address = execution address
    4. *.o (RESET, +First) ; interrupt vector table, do not change it
    5. *(InRoot$$Sections)
    6. .ANY (+RO)
    7. }

    5、需要用NuDevTool ver1.11.0.exe烧录工具将字库gb2312_80.bin烧录到0xB0000,不烧录字库运行不了。

    #define FLASH_ADDR_BASE 0xB0000

    6、源码链接:

    链接:https://pan.baidu.com/s/1KQwfkdXDj2R9A_3XGqbgWA?pwd=cmpn 
    提取码:cmpn

  • 相关阅读:
    第二届全国高校计算机技能竞赛——C++赛道 题解
    docker服务部署、迁移与备份、dockerfile、私有仓库
    C语言每日一题(19)回文素数
    CMake学习教程(一)
    2.3IP详解及配置
    扁平化iOS风商务工作汇报PPT模板
    字符设备驱动框架(字符设备基础一)
    2023.05.28 学习周报
    java线程调度
    UI组件库Kendo UI for Vue原生组件中文 - 按钮概述
  • 原文地址:https://blog.csdn.net/weixin_44067125/article/details/139174817