有用Linux下c 读写spi从机,该如何操作,我下面是spi 主机模式,我想知道从机模式怎么写,谢谢了

2004v2004 2023-02-17 20:50:42

#include <stdio.h>
#include <stdint.h>

#include <sys/types.h>
#include <time.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <string.h>

#include <time.h>
#include <stdio.h>

#include <unistd.h>
#include <linux/spi/spidev.h>

static const char *device = "/dev/spidev0.0";
static uint32_t mode = 0;                 //用于保存 SPI 工作模式
static uint8_t bits = 8;                  // 接收、发送数据位数
static uint32_t speed = 10 * 1000 * 1000; /* 设置12M传输速度 */
static int g_SPI_Fd = 0;
int pabort(const char *s)
{
    perror(s);
    abort();
    return -1;
}

/*
* 初始化SPI ,初始化OLED 使用到的命令、数据控制引脚
*/
int spi_init1(void)
{
    int ret = 0;

    /*打开 SPI 设备*/
    g_SPI_Fd = open(device, O_RDWR);
    if (g_SPI_Fd < 0)
    {
        // return pabort("can't open /dev/spidev0.0 ");
        printf("can't open %s error: g_SPI_Fd=%d\n", device, g_SPI_Fd);
        return -1;
        // exit(-1);
    }

    /*
        * spi mode 设置SPI 工作模式
    */
    ret = ioctl(g_SPI_Fd, SPI_IOC_WR_MODE32, &mode);
    if (ret == -1)
        pabort("can't set spi mode");

    ret = ioctl(g_SPI_Fd, SPI_IOC_RD_MODE32, &mode);
    if (ret == -1)
        pabort("can't get spi mode");

    /*
        * bits per word  设置一个字节的位数
    */
    ret = ioctl(g_SPI_Fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
    if (ret == -1)
        pabort("can't set bits per word");

    ret = ioctl(g_SPI_Fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
    if (ret == -1)
        pabort("can't get bits per word");

    /*
        *max speed hz  设置SPI 最高工作频率
    */
     ret = ioctl(g_SPI_Fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
     if (ret == -1)
         pabort("can't set max speed hz");

     ret = ioctl(g_SPI_Fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
     if (ret == -1)
         pabort("can't get max speed hz");

    printf("spi mode: 0x%x\n", mode);
    printf("bits per word: %d\n", bits);
    printf("max speed: %d Hz (%d KHz)\n", speed, speed / 1000);

    return g_SPI_Fd;
}

void transfer1(int fd, uint8_t const *tx, uint8_t const *rx, size_t len)
{
    int ret;
    int out_fd;
    struct spi_ioc_transfer tr = {
        .tx_buf = (unsigned long)tx,
        .rx_buf = (unsigned long)rx,
        .len = len,
    };

    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
    if (ret < 1)
    {
        pabort("can't send spi message");
    }
    // else
    // {
    //     printf("can send spi messagen ok\n");
    // }
}

/**
* 功 能:关闭SPI模块
*/
int SPI_Close1(void)
{
    if (g_SPI_Fd == 0) /* SPI是否已经打开*/
        return 0;
    close(g_SPI_Fd);
    g_SPI_Fd = 0;
    return 0;
}



u_int16_t CRCSPI(u_int8_t *p_Buf, int i_Buf)
{
    int i = 0;
    int j = 0;
    u_int16_t w_Temp;
    u_int16_t w_CRC = 0x55aa;
    for (i = 0; i < i_Buf; i++)
    {
        w_CRC ^= (*p_Buf++ << 8);
        for (j = 0; j < 8; j++)
        {
            w_Temp = w_CRC & 0x8000;
            w_CRC <<= 1;
            if (w_Temp)
                w_CRC ^= 0x8005;
        }
    }
    return w_CRC;
}

// 获取毫秒级时间格式
void get_format_time_ms(char *str_time)
{
    struct tm *tm_t;
    struct timeval time;
    gettimeofday(&time, NULL);
    tm_t = localtime(&time.tv_sec);
    if (NULL != tm_t)
    {
        sprintf(str_time, "%04d-%02d-%02d %02d:%02d:%02d.%03ld",
                tm_t->tm_year + 1900,
                tm_t->tm_mon + 1,
                tm_t->tm_mday,
                tm_t->tm_hour,
                tm_t->tm_min,
                tm_t->tm_sec,
                time.tv_usec / 1000);
    }

    return;
}
// typedef unsigned char u8;
int main(int argc, char **argv)
{

    int i = 0;
    char _Time_S_M[25];
    int ret = 0;
  
    // u8 tx[6] = {0x00, 0x84, 0x00, 0x10, 0x00, 0x00};
    // u8 rx[512] = {0};

    unsigned char tx_buffer[1024];
    unsigned char rx_buffer[1024];
    memset(_Time_S_M, 0, sizeof(_Time_S_M));
    memset(tx_buffer, 0, sizeof(tx_buffer));
    memset(rx_buffer, 0, sizeof(rx_buffer));

    tx_buffer[0] = 0x01;
    tx_buffer[1] = 0x02;
    tx_buffer[2] = 0x03;
    tx_buffer[3] = 0x04;
    tx_buffer[4] = 0x05;
    tx_buffer[5] = 0x06;
    tx_buffer[6] = 0x07;
    tx_buffer[7] = 0x08;
    tx_buffer[8] = 0x09;

    u_int16_t w_Crc12 = CRCSPI((tx_buffer + 4), 5);
    memcpy((tx_buffer + 9), &w_Crc12, 2);

    int i_File = spi_init1();

    while (1)
    {
        // usleep(9 * 1000);
        usleep(4 * 1000);
        get_format_time_ms(_Time_S_M);
        printf("tx_buffer:发送给spi 操作信息帧 数据");
        for (i = 0; i < 15; i++)
            printf("%.2X ", tx_buffer[i]);
        printf("\n");

        /*执行发送*/
        transfer1(i_File, tx_buffer, rx_buffer, sizeof(tx_buffer));
        printf("rx_buffer:接收到spi数据_Time_S_M[%s],[%d]\n", _Time_S_M, sizeof(rx_buffer));
        for (i = 0; i < sizeof(rx_buffer); i++)
            printf("%.2X ", rx_buffer[i]);
        printf("\n");

        fflush(stdout);
    }

    SPI_Close1();
    return -1;
}

 

 

上述是 spi 主机模式, 我想知道的是 从机模式怎么写,该怎么调,谢谢了

...全文
336 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
WangLanguager 2023-02-18
  • 打赏
  • 举报
回复

/*
* spi mode 设置SPI 工作模式
*/
ret = ioctl(g_SPI_Fd, SPI_IOC_WR_MODE32, &mode);
if (ret == -1)
pabort("can't set spi mode");
直接在这个修改模式的接口,把[mode]参数修改一下?

2004v2004 2023-02-18
  • 举报
回复
@WangLanguager 对方主机这里是 0 ,我设置成那个值, 0, ,1,2,3 我都测试过,没什么作用
内容概要:本文提出了一种针对自主多无人机系统的通信模式选择概率模型,该模型能够基于动态环境中实时采集的数据进行智能决策,有效提升多无人机在协同作业中的协作效率与任务执行成功率。研究结合了不确定性因素的影响,采用Matlab实现算法仿真,构建了适应复杂环境变化的通信机制,重点解决了多无人机系统在动态环境下通信稳定性与可靠性的问题,具有较强的实用性和工程应用价值。; 适合人群:具备一定控制理论、通信系统或无人机相关背景,熟悉Matlab/Simulink仿真的科研人员及研究生;适用于从事多智能体系统、无线通信优化或协同控制方向的研究者。; 使用场景及目标:①应用于多无人机协同任务中的通信【自主多无人机系统通信模式选择的概率模型】基于动态环境中的实时数据做出决策,从而提高多无人机协同作业中的协作效果与任务成功率(Matlab代码实现)资源动态分配与模式切换;②为应对动态环境干扰下的通信中断问题提供决策支持;③提升复杂场景下无人机集群的任务完成率与系统鲁棒性; 阅读建议:建议结合Matlab代码深入理解模型实现细节,重点关注概率决策机制与实时数据处理流程,可进一步扩展至其他多智能体系统通信优化场景进行二次开发与验证。
内容概要:本文主要围绕UWB-IMU与UWB定位技术的对比研究展开,基于Matlab代码实现,结合状态估计算法(如UKF、AUKF等)对两种定位方式的性能进行分析与比较。研究重点在于通过数据融合提升定位精度与稳定性,尤其适用于复杂环境下的高精度定位需求。文中提供了完整的仿真代码和实现方法,便于读者复现与扩展应用。此外,文档还列举了大量相关科研方向和技术服务内容,涵盖机器学习、信号处理、路径规划、电力系统等多个领域,展示了广泛的技术支持能力。; 适合人群:具备一定Matlab编程基础,从事定位技术、状态估计、传感器融合或相关科研UWB-IMU、UWB定位对比研究(Matlab代码实现)方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于高精度室内定位系统的设计与优化;②开展UWB与IMU融合定位算法的研究与验证;③学习和掌握卡尔曼滤波(如UKF、EKF)在实际定位问题中的应用;④为科研项目提供算法仿真支持和技术参考。; 阅读建议:建议读者结合提供的Matlab代码逐模块分析,重点关注数据融合策略与状态估计实现过程,同时可参考文中提及的相关技术方向拓展研究思路。注意区分纯UWB与UWB-IMU融合方案的性能差异,深入理解IMU在补偿UWB信号缺失方面的关键作用。
内容概要:本文档围绕六自由度机械臂的ANN人工神经网络设计展开,涵盖正向与逆向运动学求解、正向动力学控制,并采用拉格朗日-欧拉法推导逆向动力学方程,所有内容均通过Matlab代码实现。同时结合RRT路径规划与B样条优化技术,提升机械臂运动轨迹的合理性与平滑性。文中还涉及多种先进算法与仿真技术的应用,如状态估计中的UKF、AUKF、EKF等滤波方法,以及PINN、INN、CNN-LSTM等神经网络模型在工程问题中的建模与求解,展示了Matlab在机器人控制、智能算法与系统仿真中的强大能力。; 适合人群:具备一定Ma六自由度机械臂ANN人工神经网络设计:正向逆向运动学求解、正向动力学控制、拉格朗日-欧拉法推导逆向动力学方程(Matlab代码实现)tlab编程基础,从事机器人控制、自动化、智能制造、人工智能等相关领域的科研人员及研究生;熟悉运动学、动力学建模或对神经网络在控制系统中应用感兴趣的工程技术人员。; 使用场景及目标:①实现六自由度机械臂的精确运动学与动力学建模;②利用人工神经网络解决传统解析方法难以处理的非线性控制问题;③结合路径规划与轨迹优化提升机械臂作业效率;④掌握基于Matlab的状态估计、数据融合与智能算法仿真方法; 阅读建议:建议结合提供的Matlab代码进行实践操作,重点理解运动学建模与神经网络控制的设计流程,关注算法实现细节与仿真结果分析,同时参考文中提及的多种优化与估计方法拓展研究思路。

41

社区成员

发帖
与我相关
我的任务
社区描述
喜欢IT,喜欢编程,希望遇到更多志同道合的朋友!
嵌入式硬件 个人社区 广东省·深圳市
社区管理员
  • WangLanguager
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧