本篇实现WIFI扫描 功能。
一.硬件原理
开发板搭载了一颗Infineon CYW43439WIFI蓝牙双模芯片模块,支持802.11b/g/n Wi-Fi and Bluetooth® 5.2,模块通讯接口为SDIO
二.代码准备
1.创建wifi scan 工程如下
2.工程目录结构如下。主要应用功能实现在main.c和scan_task.c
3.代码解析
这里主要从main函数开始解读。
(1)用户led初始化,主要用在用在扫描出错时的指示。
(2)按键初始化及应用。主要是按键实现扫描模式切换
扫描模式有如下几种
(3)QSPI接口初始化并使能XIP
这里XIP(Execute-In-Place) 是一项允许CPU直接从非易失性存储器(如Flash)中读取并执行代码的技术,无需先将代码复制到RAM中。使用到了QSPI接口读写Flash.
(4)创建scan_task任务,启动FreeRTOS调度器。
(5)在scan_task任务里,是由按键触发改变的scan_filter_mode_select状态机执行各种扫描模式,并在scan_callback回调打印扫描结果。
wifi扫描任务
- void scan_task(void *arg)
- {
- cy_wcm_scan_filter_t scan_filter;
- cy_rslt_t result = CY_RSLT_SUCCESS;
- cy_wcm_config_t wcm_config = { .interface = CY_WCM_INTERFACE_TYPE_STA };
- cy_wcm_mac_t scan_for_mac_value = {SCAN_FOR_MAC_ADDRESS};
- memset(&scan_filter, 0, sizeof(cy_wcm_scan_filter_t));
- result = cy_wcm_init(&wcm_config);
- error_handler(result, "Failed to initialize Wi-Fi Connection Manager.\n");
- while (true)
- {
- /* Select the type of filter to use.*/
- switch (scan_filter_mode_select)
- {
- case SCAN_FILTER_NONE:
- APP_INFO(("Scanning without any filter\n"));
- break;
- case SCAN_FILTER_SSID:
- APP_INFO(("Scanning for %s.\n", SCAN_FOR_SSID_VALUE));
- /* Configure the scan filter for SSID specified by
- * SCAN_FOR_SSID_VALUE.
- */
- scan_filter.mode = CY_WCM_SCAN_FILTER_TYPE_SSID;
- memcpy(scan_filter.param.SSID, SCAN_FOR_SSID_VALUE, sizeof(SCAN_FOR_SSID_VALUE));
- break;
- case SCAN_FILTER_RSSI:
- APP_INFO(("Scanning for RSSI > %d dBm.\n", SCAN_FOR_RSSI_VALUE));
- /* Configure the scan filter for RSSI range specified by
- * SCAN_FOR_RSSI_VALUE.
- */
- scan_filter.mode = CY_WCM_SCAN_FILTER_TYPE_RSSI;
- scan_filter.param.rssi_range = SCAN_FOR_RSSI_VALUE;
- break;
- case SCAN_FILTER_MAC:
- APP_INFO(("Scanning for %02X:%02X:%02X:%02X:%02X:%02X.\n", scan_for_mac_value[0], scan_for_mac_value[1], scan_for_mac_value[2], scan_for_mac_value[3], scan_for_mac_value[4], scan_for_mac_value[5]));
- /* Configure the scan filter for MAC specified by scan_for_mac_value
- */
- scan_filter.mode = CY_WCM_SCAN_FILTER_TYPE_MAC;
- memcpy(scan_filter.param.BSSID, &scan_for_mac_value, sizeof(scan_for_mac_value));
- break;
- case SCAN_FILTER_BAND:
- APP_INFO(("Scanning in %s band.\n", band_string[SCAN_FOR_BAND_VALUE]));
- /* Configure the scan filter for band specified by
- * SCAN_FOR_BAND_VALUE.
- */
- scan_filter.mode = CY_WCM_SCAN_FILTER_TYPE_BAND;
- scan_filter.param.band = SCAN_FOR_BAND_VALUE;
- break;
- default:
- break;
- }
- PRINT_SCAN_TEMPLATE();
- if(SCAN_FILTER_NONE == scan_filter_mode_select)
- {
- result = cy_wcm_start_scan(scan_callback, NULL, NULL);
- }
- else
- {
- result = cy_wcm_start_scan(scan_callback, NULL, &scan_filter);
- }
- /* Wait for scan completion if scan was started successfully. The API
- * cy_wcm_start_scan doesn't wait for scan completion. If it is called
- * again when the scan hasn't completed, the API returns
- * CY_WCM_RESULT_SCAN_IN_PROGRESS.
- */
- if (CY_RSLT_SUCCESS == result)
- {
- xTaskNotifyWait(0, 0, NULL, portMAX_DELAY);
- }
- /* Define PRINT_HEAP_USAGE using DEFINES variable in the Makefile. */
- print_heap_usage("After scan results are printed to UART");
- vTaskDelay(pdMS_TO_TICKS(SCAN_DELAY_MS));
- }
- }
wifi扫描回调
- static void scan_callback(cy_wcm_scan_result_t *result_ptr, void *user_data, cy_wcm_scan_status_t status)
- {
- if ((strlen((const char *)result_ptr->SSID) != 0) && (status == CY_WCM_SCAN_INCOMPLETE))
- {
- num_scan_result++;
- print_scan_result(result_ptr);
- }
- if ( (CY_WCM_SCAN_COMPLETE == status) )
- {
- /* Reset the number of scan results to 0 for the next scan.*/
- num_scan_result = 0;
- /* Notify that scan has completed.*/
- xTaskNotify(scan_task_handle, 0, eNoAction);
- }
- }
(6)指定ssid扫描这里将名称改为自己所用的WIFI,任务轮询间隔由3s改为5s。地方改动如下
至此,代码梳理了一遍,准备完毕。
三.编译烧录调试
编译烧录后,打开串行监视器,扫描出结果在5s间隙内按一次按键,串口日志如下,可以看到各扫描模式下的结果。
至此,实现开发板WIFI扫描功能,并对工程代码实现进行了梳理掌握。
|