• linux spi读写


    用的xubuntu,发现有/dev/spidev0.0,是不是意味着驱动已经装好。测试代码,如下:
    /*
    * Debug.h
    * 摘要:用于打印调试信息
    *         为了统一控制打印信息是否输出,而用宏定义的打印函数。同时也可以起到开发版本与发布版本是同一个版本
    *  Created on: 2013-5-22
    *      Author: lzy
    */
    
    #ifndef DEBUG_H_
    #define DEBUG_H_
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdarg.h>
    
    #define     DEBUG_SWITCH    1        /* 打开调试信息打印功能 */
    #define     ERR_DEBUG_SWITCH    1    /* 打印错误信息打印功能 */
    
    /**
    * 简单打印调试信息
    */
    #if    DEBUG_SWITCH
    #define pr_debug(fmt,args...) printf(fmt, ##args)
    #else
    #define pr_debug(fmt,args...) /*do nothing */
    #endif
    
    /**
    * 错误信息打印
    * 自动打印发生错误时代码所在的位置
    */
    #if    ERR_DEBUG_SWITCH
    #define pr_err(fmt,args...) printf("
    Error:
    File:<%s> Fun:[%s] Line:%d
     "fmt, __FILE__, __FUNCTION__, __LINE__, ##args)
    #else
    #define pr_err(fmt,args...) /*do nothing */
    #endif
    
    #endif /* DEBUG_H_ */
    
    /*
    * 说明:SPI通讯实现
    *           方式一: 同时发送与接收实现函数: SPI_Transfer()
    *           方式二:发送与接收分开来实现
    *           SPI_Write() 只发送
    *           SPI_Read()  只接收
    *           两种方式不同之处:方式一,在发的过程中也在接收,第二种方式,收与发单独进行
    *  Created on: 2013-5-28
    *      Author: lzy
    */
    
    #include <stdint.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <getopt.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <linux/types.h>
    #include <linux/spi/spidev.h>
    
    #include "Debug.h"
    #define SPI_DEBUG 0
    
    static const char *device = "/dev/spidev0.0";
    static uint8_t mode = 0; /* SPI通信使用全双工,设置CPOL=0,CPHA=0。 */
    static uint8_t bits = 8; /* 8bits读写,MSB first。*/
    static uint32_t speed = 12 * 1000 * 1000;/* 设置12M传输速度 */
    static uint16_t delay = 0;
    static int g_SPI_Fd = 0;
    
    static void pabort(const char *s)
    {
        perror(s);
        abort();
    }
    
    /**
    *  功 能:同步数据传输
    * 入口参数 :
    *             TxBuf -> 发送数据首地址
    *             len -> 交换数据的长度
    * 出口参数:
    *             RxBuf -> 接收数据缓冲区
    * 返回值:0 成功
    * 开发人员:Lzy 2013-5-22
    */
    int SPI_Transfer(const uint8_t *TxBuf, uint8_t *RxBuf, int len)
    {
        int ret;
        int fd = g_SPI_Fd;
    
        struct spi_ioc_transfer tr =    {
                .tx_buf = (unsigned long) TxBuf,
                .rx_buf = (unsigned long) RxBuf,
                .len =    len,
                .delay_usecs = delay,
        };
    
        ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);
        if (ret < 1)
            pr_err("can't send spi message");
        else
        {
    #if SPI_DEBUG
            int i;
            pr_debug("
    send spi message Succeed");
            pr_debug("
    SPI Send [Len:%d]: ", len);
            for (i = 0; i < len; i++)
            {
                if (i % 8 == 0)
                printf("
    	");
                printf("0x%02X ", TxBuf[i]);
            }
            printf("
    ");
    
            pr_debug("SPI Receive [len:%d]:", len);
            for (i = 0; i < len; i++)
            {
                if (i % 8 == 0)
                printf("
    	");
                printf("0x%02X ", RxBuf[i]);
            }
            printf("
    ");
    #endif
        }
        return ret;
    }
    
    /**
    * 功 能:发送数据
    * 入口参数 :
    *             TxBuf -> 发送数据首地址
    *            len ->  发送与长度
    *返回值:0 成功
    * 开发人员:Lzy 2013-5-22
    */
    int SPI_Write(uint8_t *TxBuf, int len)
    {
        int ret;
        int fd = g_SPI_Fd;
    
        ret = write(fd, TxBuf, len);
        if (ret < 0)
            pr_err("SPI Write error
    ");
        else
        {
    #if SPI_DEBUG
            int i;
            pr_debug("
    SPI Write [Len:%d]: ", len);
            for (i = 0; i < len; i++)
            {
                if (i % 8 == 0)
                printf("
    	");
                printf("0x%02X ", TxBuf[i]);
            }
            printf("
    ");
    
    #endif
        }
    
        return ret;
    }
    
    /**
    * 功 能:接收数据
    * 出口参数:
    *         RxBuf -> 接收数据缓冲区
    *         rtn -> 接收到的长度
    * 返回值:>=0 成功
    * 开发人员:Lzy 2013-5-22
    */
    int SPI_Read(uint8_t *RxBuf, int len)
    {
        int ret;
        int fd = g_SPI_Fd;
        ret = read(fd, RxBuf, len);
        if (ret < 0)
            pr_err("SPI Read error
    ");
        else
        {
    #if SPI_DEBUG
            int i;
            pr_debug("SPI Read [len:%d]:", len);
            for (i = 0; i < len; i++)
            {
                if (i % 8 == 0)
                printf("
    	");
                printf("0x%02X ", RxBuf[i]);
            }
            printf("
    ");
    #endif
        }
    
        return ret;
    }
    
    /**
    * 功 能:打开设备  并初始化设备
    * 入口参数 :
    * 出口参数:
    * 返回值:0 表示已打开  0XF1 表示SPI已打开 其它出错
    * 开发人员:Lzy 2013-5-22
    */
    int SPI_Open(void)
    {
        int fd;
        int ret = 0;
    
        if (g_SPI_Fd != 0) /* 设备已打开 */
            return 0xF1;
    
        fd = open(device, O_RDWR);
        if (fd < 0)
            pabort("can't open device");
        else
            pr_debug("SPI - Open Succeed. Start Init SPI...
    ");
    
        g_SPI_Fd = fd;
        /*
         * spi mode
         */
        ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);
        if (ret == -1)
            pabort("can't set spi mode");
    
        ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);
        if (ret == -1)
            pabort("can't get spi mode");
    
        /*
         * bits per word
         */
        ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
        if (ret == -1)
            pabort("can't set bits per word");
    
        ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
        if (ret == -1)
            pabort("can't get bits per word");
    
        /*
         * max speed hz
         */
        ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
        if (ret == -1)
            pabort("can't set max speed hz");
    
        ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
        if (ret == -1)
            pabort("can't get max speed hz");
    
        pr_debug("spi mode: %d
    ", mode);
        pr_debug("bits per word: %d
    ", bits);
        pr_debug("max speed: %d KHz (%d MHz)
    ", speed / 1000, speed / 1000 / 1000);
    
        return ret;
    }
    
    /**
    * 功 能:关闭SPI模块
    */
    int SPI_Close(void)
    {
        int fd = g_SPI_Fd;
    
        if (fd == 0) /* SPI是否已经打开*/
            return 0;
        close(fd);
        g_SPI_Fd = 0;
    
        return 0;
    }
    
    /**
    * 功 能:自发自收测试程序
    *         接收到的数据与发送的数据如果不一样 ,则失败
    * 说明:
    *         在硬件上需要把输入与输出引脚短跑
    * 开发人员:Lzy 2013-5-22
    */
    int SPI_LookBackTest(void)
    {
        int ret, i;
        const int BufSize = 16;
        uint8_t tx[BufSize], rx[BufSize];
    
        bzero(rx, sizeof(rx));
        for (i = 0; i < BufSize; i++)
            tx[i] = i;
    
        pr_debug("
    SPI - LookBack Mode Test...
    ");
        ret = SPI_Transfer(tx, rx, BufSize);
        if (ret > 1)
        {
            ret = memcmp(tx, rx, BufSize);
            if (ret != 0)
            {
                pr_err("LookBack Mode Test error
    ");
    //            pabort("error");
            }
            else
                pr_debug("SPI - LookBack Mode  OK
    ");
        }
    
        return ret;
    }
    
    int main(int argc, char *argv[])
    {
        int ret = 0;
    
        ret = SPI_Open();
        if (ret)
            return ret;
    
        SPI_LookBackTest();
    
    //    unsigned char buf[10];
    //    SPI_Write(buf, 10);
    //    SPI_Read(buf, 10);
    
        SPI_Close();
    
    return 0;
    }
    
    

      

  • 相关阅读:
    ios每日一发--Leanclude数据云存储以及登录 注册账户
    ios每日一发--仿侧边抽屉效果
    ios-自定义alertView提示框
    ios
    UIStepper 缩放:UI的使用
    UIButton 关灯小实验
    将一个字典内的内value转换为集合:返回一个数组,此数组中包含输入字典的键值对中的数组的所有元素(为NSArray添加category)
    为集合排序的三个方法
    NSMutableDictionary
    头文件导入方式
  • 原文地址:https://www.cnblogs.com/yuanqiangfei/p/15215569.html
Copyright © 2020-2023  润新知