RP2040 + W5100S 多核基础版

RP2040 多核基础版,带 W5100s

转发: RP2040 + W5100S Multicore Basic

项目介绍

你好!

今天,我将解释一个项目,其中我们使用安装在 W5100S-EVB-PICO 上的 RP2040 的两个内核来读取 ADC 数据并将该数据发送到连接的 TCP 客户端!

W5100S-EVB-PICO 中使用的 Raspberry Pi RP2040 有两个内核 (M0+)。

如果您使用过 W5100S-EVB-PICO,您就会知道 Wiznet 提供了基本的示例代码。

示例均是单核实现,为了更好地利用RP2040的硬件资源,使用多核实现效率更高。

然而,网上提供的许多 RP2040 多核示例都是用 MicroPython 实现的。

虽然这些示例使多核实现变得更容易,但它们与该项目的最终目标并不相符:有效地使用有限的嵌入式硬件资源。 因此,我们在这个项目中使用了C语言。

以下部分将解释运行该项目所需的硬件连接和软件设置。

硬件连接

您可以使用 RPI-PICO 和 W5100S 模块作为硬件,但我使用的是包含 RP2040 和 W5100S 的 W5100S-EVB-PICO EVB。

对于 ADC 输入,您可以使用可变电阻器,但我在未来的项目中使用了 XY 操纵杆。 我使用的 XY-Joystick 模块可以输出 X 轴和 Y 轴的 ADC 值,但该项目仅需要一个 ADC 输入。

ADC 输入馈送到 GP26 (ADC0)。

W5100S 安装在 W5100S-EVB-PICO 上,并设置为 SPI0(MOSI - GP19、MISO - GP16、SCK - SP18、CS - GP17、INT - GP21、RST - GP20)。

对于多核实现,我参考了 Rpi 提供的 PICO-SDK 文档中的 pico_multicore 部分。

对于多核实现,我参考了Rpi提供的。 以下是该项目的主要代码。

#include "hardware/adc.h"

#include "hardware/timer.h"

#include "hardware/sync.h"

#include <stdio.h>

#include "port_common.h"

#include "wizchip_conf.h"

#include "w5x00_spi.h"

#include "socket.h"

#include "pico/multicore.h"




#define TIMER_PERIOD_MS (1000)

#define PLL_SYS_KHZ (133 * 1000)

#define ETHERNET_BUF_MAX_SIZE (1024 * 2)

#define SOCKET_LOOPBACK 0

#define PORT 5000




#define ADC0_PIN 26




static wiz_NetInfo g_net_info = {

    .mac = {0x00, 0x08, 0xDC, 0x12, 0x34, 0x56},

    .ip = {192, 168, 11, 2},

    .sn = {255, 255, 255, 0},

    .gw = {192, 168, 11, 1},

    .dns = {8, 8, 8, 8},

    .dhcp = NETINFO_STATIC

};




static uint8_t Send_buf[ETHERNET_BUF_MAX_SIZE] = {0,};




// 기존 함수와 중복되지 않도록 함수명을 변경하였습니다.

static void init_clock_khz(void) {

    set_sys_clock_khz(PLL_SYS_KHZ, true);

    clock_configure(

        clk_peri,

        0,

        CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,

        PLL_SYS_KHZ * 1000,

        PLL_SYS_KHZ * 1000

    );

}




static void read_adc_core1() {

    while (true) {

        adc_select_input(0);

        uint16_t result = adc_read();

        multicore_fifo_push_blocking(result);

        sleep_ms(TIMER_PERIOD_MS);

    }

}




static int32_t send_adc_data_to_client(uint8_t sn, uint8_t* buf, uint16_t port) {

    uint16_t adc_value = multicore_fifo_pop_blocking();

    sprintf((char*)buf, "ADC data : %d\n", adc_value);




    int32_t ret;

    switch(getSn_SR(sn)) {

        case SOCK_ESTABLISHED:

            if(getSn_IR(sn) & Sn_IR_CON) {

                setSn_IR(sn, Sn_IR_CON);

                printf("Client connected!\n");

            }

            if ((ret = send(sn, buf, strlen((char*)buf))) <= 0) {

                return ret;

            }

            break;

        case SOCK_CLOSE_WAIT:

            if ((ret = disconnect(sn)) != SOCK_OK) {

                return ret;

            }

            break;

        case SOCK_INIT:

            if ((ret = listen(sn)) != SOCK_OK) {

                return ret;

            }

            printf("Waiting client connection...\n");

            break;

        case SOCK_CLOSED:

            if ((ret = socket(sn, Sn_MR_TCP, port, 0x00)) != sn) {

                return ret;

            }

            break;

        default:

            break;

    }

    return 1;

}




int main() {

    int retval = 0;




    init_clock_khz();

    stdio_init_all();




    wizchip_spi_initialize();

    wizchip_cris_initialize();

    wizchip_reset();

    wizchip_initialize();

    wizchip_check();




    network_initialize(g_net_info);




    adc_init();

    adc_gpio_init(ADC0_PIN);




    multicore_launch_core1(read_adc_core1);




    print_network_information(g_net_info);

    printf("Port : %d\n", PORT); // 포트 번호 출력 부분 추가




    while (1) {

        if ((retval = send_adc_data_to_client(SOCKET_LOOPBACK, Send_buf, PORT)) < 0) {

            printf(" Data sending error : %d\n", retval);

            while (1);

        }

    }

}

主要功能流程:

系统时钟初始化:调用init_clock_khz函数。

初始化标准I/O:调用stdio_init_all函数。

Wiznet W5100S初始化:使用wizchip功能初始化W5100S。

网络设置:使用g_net_info配置网络。

ADC初始化:初始化ADC和ADC引脚。

运行 Core1:使用 read_adc_core1 函数开始读取 Core1 中的 ADC 值。

打印网络信息:显示当前网络配置信息。

无限循环:使用send_adc_data_to_client函数定期将ADC数据发送到TCP客户端。 完整的源代码发布在Github链接上,所以请参考。

这是该项目正在运行的视频。 对于 TCP 客户端,我们使用 herculas.exe

在以后的项目中,我们会以此项目为基础,探索各种多核项目。

感谢您阅读这篇长文。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值