首页 > 其他分享 >【代码】--库函数学习 spi.c

【代码】--库函数学习 spi.c

时间:2024-05-22 16:41:51浏览次数:24  
标签:return SPI -- TSpiDev char spi int pDev 库函数

1. SPI介绍

      

2. 全局结构体 和 用到的函数

/***封装的SPI结构体**/
typedef struct
{
    int nSpiFd;          //spi文件描述符
    char nDevName[32];   //spi名称,例/dev/spidev2.0
    int nSpeed;          //spi通信速率
    int nBit;            //为8,写死的
    int nOpenFlag;       //true表示已打开
    pthread_mutex_t nBusLock;   //没啥用,未用到,也未进行初始化
}TSpiDev;
外部函数:
/*该函数做的事情:
   (1)打开SPI控制器的设备文件;
   (2)设置SPI工作模式、一个字节位数(8位)、最高波特率。
   (3)malloc一个TSpiDev结构,然后返回指针。
*/
(1)HANDLE SpiOpen(char *pDevice,int nSpeed,int nMode)


/*该函数做的事情:同时实现SPI的发送和接收函数*/
(2)bool SpiTransfer(HANDLE nHandle,char *pTxBuf,int nTxLen,char *pRxBuf,int nRxLen);

/*该函数做的事情:只进行SPI数据的发送*/
(3)bool SpiWrite(HANDLE nHandle,char *pTxBuf,int nTxLen)  

/*该函数做的事情:改变一个字节的位数*/
(4)bool SpiBit(HANDLE nHandle,int nBit)

/*该函数做的事情:
   (1)关闭SPI控制器的设备文件;
   (2)将打开标志置为false;
   (3)并未释放TSpiDev结构空间。
*/
(5)int SpiClose(HANDLE *pHandle);

3. 函数源码注释

3.1 SpiOpen

/**********************************
*function:    SpiOpen
*input    : 
*            pDevice : Spi device 
*           nSpeed : Spi max speed
*output    :
*return :
*            success : return bus handle,else return -1;
*/  
HANDLE SpiOpen(char *pDevice,int nSpeed,int nMode)
{
    int nFd = 0;
    int ret = 0;
    TSpiDev *pDev = NULL;
/*
Default Mode to 0
*/
    unsigned char mode = nMode;
/*
Default Bit Width to 8
*/    
    unsigned char bits = 8;
    if(pDevice == NULL)
    {
        LOG_ERROR("Get null device name.");
        return -1;
    }
/*
Open Device
*/
    nFd = open(pDevice,O_RDWR);   //打开SPI控制器
    if(nFd <= 0)
    {
        LOG_ERROR("Open %s error with %s.",pDevice,strerror(errno));
        return -1;
    }
/*Initialize SPI*/    
/*
*spi mode
*/
    ret = ioctl(nFd, SPI_IOC_WR_MODE, &mode);   //设置SPI的工作模式,一共有4种
    if (ret == -1)
    {
        LOG_ERROR("SPI_IOC_WR_MODE with %s.",strerror(errno));
        close(nFd);
        return -1;
    }
/*
* bits per word
*/ 
    ret = ioctl(nFd, SPI_IOC_WR_BITS_PER_WORD, &bits);   //设置一个字节的位数,默认情况下设置为 8 即可
    if (ret == -1)
    {
        LOG_ERROR("SPI_IOC_WR_BITS_PER_WORD with %s.",strerror(errno));
        close(nFd);
        return -1;
    }
/* 
* max speed hz 
*/
    ret = ioctl(nFd, SPI_IOC_WR_MAX_SPEED_HZ, &nSpeed);   //设置 最高波特率
    if (ret == -1)
    {
        LOG_ERROR("SPI_IOC_WR_MAX_SPEED_HZ with %s.",strerror(errno));
        close(nFd);
        return -1;
    }   

/*Initialize Muter*/
    pDev = (TSpiDev *)malloc(sizeof(TSpiDev));
    if(pDev == NULL)
    {
        close(nFd);
        LOG_ERROR("Get SPI hanlde error wiyh %s.",strerror(errno));
        return -1;
    }
/*Save Status*/
    snprintf(pDev->nDevName,sizeof(pDev->nDevName),"%s",pDevice);
    pDev->nOpenFlag = true;
    pDev->nSpeed = nSpeed;
    pDev->nSpiFd = nFd;
    pDev->nBit = 8;
    return (HANDLE)pDev;    
}

3.2 SpiTransfer

/**********************************
*function:    SpiTransfer
*input    : 
*            nHandle : Spi device Handle 
*           pTxBuf  : TxBuffer
*           nTxLen  : Tx Len 
*           pRxBuf  : Rx Buffer
*           nRxLen  : Rx Len
*output    :
*return :
*            success : return true,else return false;
*/  
bool SpiTransfer(HANDLE nHandle,char *pTxBuf,int nTxLen,char *pRxBuf,int nRxLen)   //同时发送和接收
{
    int ret;
    unsigned char tx[512] = {0};
    unsigned char rx[512] = {0};

    TSpiDev *pDev = (TSpiDev *)nHandle;
/*
Spi Transfer Message   定义并初始化SPI传输结构体
*/
    struct spi_ioc_transfer tr ={
        .tx_buf = (unsigned long)tx,  //
        .rx_buf = (unsigned long)rx,  //接收到的数据会暂存到rx中
        .len = nTxLen,        //一次传输的数据长度
        .delay_usecs = 0,     //如果不为零则用于设置两次传输之间的时间延迟。
        .speed_hz = pDev->nSpeed,   //指定 SPI 通信的比特率
/*
Default to 8 bit
*/        
        .bits_per_word = pDev->nBit,   //一个字节占用8比特
    };

    
    LOG_DEBUG("{%s-%d}-Start Transmessge.",pDev->nDevName,pDev->nSpiFd);
    if(pDev->nOpenFlag)
    {
        memcpy(tx,pTxBuf,nTxLen);   //把发送的数据拷贝到tx中
        if(pRxBuf == NULL)
        {
            tr.rx_buf = 0;
        }

       //MESSAGE(1)表示:半双工;MESSAGE(2)表示全双工;
        ret = ioctl(pDev->nSpiFd, SPI_IOC_MESSAGE(1), &tr);   //参数 SPI_IOC_MESSAGE(1) 用于指定执行传输次数

        if (ret < 1)
        { 
            LOG_ERROR("SPI Transfer error with %s.",strerror(errno));
            return false;
        }
        if(pRxBuf)
        {
            memcpy(pRxBuf,rx,nRxLen);  //把接收到的到的数据拷贝出来到pRxBuf
        }
        return true;
    }
    LOG_ERROR("SPI device not open.");
    return false;
}

3.3 SpiWrite

/**********************************
*function:    SpiTransfer
*input    : 
*            nHandle : Spi device Handle 
*           pTxBuf  : TxBuffer
*           nTxLen  : Tx Len 
*output    :
*return :
*            success : return true,else return false;
*/  
bool SpiWrite(HANDLE nHandle,char *pTxBuf,int nTxLen)     //只发送
{
    TSpiDev *pDev = (TSpiDev *)nHandle;
    if(pDev->nOpenFlag)
    {
        if(write(pDev->nSpiFd,pTxBuf,nTxLen) != nTxLen)  //只需要往设备文件中写入即可。    如果仅仅读的话,也可以从设备文件中read即可
        {
            LOG_ERROR("Spi write error with %s.",strerror(errno));
            return false;
        }
    }
    return true;
}

3.4 SpiBit

/**********************************
*function:    SpiBit
*input    : 
*            pHandle : Spi device Handle 
*           nBit    : Spi Bit for each word
*output    :
*return :
*            success : return bus handle,else return -1;
*/  
bool SpiBit(HANDLE nHandle,int nBit)   //改变一个字节的位数
{
    int ret = 0;
    unsigned char bits = nBit;
    TSpiDev *pDev = (TSpiDev *)nHandle;
    pDev->nBit = nBit;

/*
* bits per word
*/ 
    ret = ioctl(pDev->nSpiFd, SPI_IOC_WR_BITS_PER_WORD, &bits); 
    if (ret == -1)
    {
        LOG_ERROR("SPI_IOC_WR_BITS_PER_WORD %d with %s.",bits,strerror(errno));
        return false;
    }
    return true;
}

3.5 SpiClose

/**********************************
*function:    SpiClose
*input    : 
*            pHandle : Spi device Handle 
*output    :
*return :
*            success : return bus handle,else return -1;
*/  
bool SpiClose(HANDLE *pHandle)
{
    if(pHandle)
    {
        TSpiDev * pDev = (TSpiDev *)(*pHandle);
        if(pDev->nOpenFlag)
        {
            close(pDev->nSpiFd);
            pDev->nOpenFlag = false;
        }
        *pHandle = 0;
        return true;
    }
    LOG_ERROR("Get NUll pointer.");
    return false;
}

标签:return,SPI,--,TSpiDev,char,spi,int,pDev,库函数
From: https://www.cnblogs.com/dkhlaojogo/p/18206599

相关文章

  • RTL8211F以太网千兆RGMII开发板-飞录科技
    1.概述    RGMII 开发板主芯片是RTL8211FD。配套国产GOWIN的2AR-18和NR-9C的开发板,测试RGMII的千兆以太网数据发送和接收功能。  开发板的代码是基于MAC模式,通过循环发送计数器来判断包发送和接收是否正确。          配套资料  ......
  • Java RMI遇到的Connection refused to Host: 127.x.x.x/192.x.x.x/10.x.x.x问题解决方
    问题故障解决记录--JavaRMIConnectionrefusedtohost:x.x.x.x....在学习JavaRMI时,我遇到了以下情况问题原因:可能大家的host是10或者192的私有地址,我估计都是和我一样的一个原因:/etc/hosts文件的配置问题(我是ubuntu系统下的实验环境),也就是主机名称和IP地址的映射关系......
  • 9-3-了解gzip-bzip2- xz管理压缩文件
    9.3了解gzip-bzip2-xz管理压缩文件-file-sort查看文件创建压缩的TAR存档,TAR命令支持三种不同的压缩方式:gzip压缩速度最快bzip2压缩生成的文件比gzip小,但使用不如gzip广;xz压缩工具相对较新,但是会提供最佳的压缩率9.3.1压缩工具......
  • Ribbon负载均衡
    SpringCloudRibbon是一套基于NetflixRibbon实现的客户端负载均衡和服务调用工具。负载均衡是系统处理高并发、缓解网络压力和服务端扩容的重要手段之一。通过Ribbon,以将面向服务的REST模板(RestTemplate)请求转换为客户端负载均衡的服务调用,SpringCloud微服务之间的......
  • PHP历理 计算24点纸牌游戏
    <?php/*demo*/$tf=newTwentyFourCal();$tf->calculate(array(4,8,8,8));$tf->calculate(array(10,10,4,4));$tf->calculate(array(4,4,4,4));$tf->calculate(array(1,2,1,2));$tf->calculate(array(5,6,7,8));classTwentyFourCal......
  • JS历理 Markdown在线编辑器editor
    官网下载下载地址:http://editor.md.ipandao.comJS引入新建文件夹md,将下载好的文件引入过来,新建方法视图文件<!DOCTYPEhtml><html><head> <metacharset="utf-8"> <metahttp-equiv="X-UA-Compatible"content="IE=edge"> <ti......
  • 2024年度 OKR 最佳平台: Tita OKR 软件
    当公司开始使用“目标和关键结果(OKR)”时,它们便像大多数公司一样开始使用手动跟踪方法,例如Excel,Google表格,PowerPoint和其他手动过程。通过使用这些类型的实践,可以手动创建,更新OKR,并通过电子邮件,企业微信,钉钉和其他各种通信渠道进行共享。 不幸的是,当组织开始深入了解OKR方法......
  • tslib移植配置
    1获取tslib源码https://github.com/libts/tslibgitclonehttps://github.com/libts/tslib.git2修改tslib源码所属用户sudochownbook:booktslib-1.21-R这一步一定要做!否则在稍后的编译中会遇到各种问题。3ubuntu工具安装sudoapt-getinstallautoconfsudoap......
  • PHP函数 Math函数
    <?phpheader('Content-Type:text/html;charset=utf-8');define('ROOT',$_SERVER['DOCUMENT_ROOT']);includeROOT.'/assets/php/head.php';//Math函数/***abs—绝对值*acos—反余弦*acosh—反双曲余弦*asin—反正弦*......
  • python 自然语言处理模块
    Python中有几个流行的自然语言处理(NLP)模块,这些模块提供了广泛的工具和库,用于文本分析、处理和理解。以下是一些广泛使用的NLP模块:NLTK(NaturalLanguageToolkit)NLTK是Python中最著名的NLP库之一,它提供了文本处理的丰富工具,包括分词、词性标注、句法分析、语义推理等。网......