• 使用SPIDE操作SPI_DAC模块


    一、硬件

    IMX6ULL:
    在这里插入图片描述
    原理图:
    在这里插入图片描述接线图:
    请添加图片描述

    二、DAC操作原理

    2.1 内部框图

    在这里插入图片描述
    操作过程:

    • CS为低:
    • 在SCLK的上升沿,从DIN采集16位数据,存入上图中的16-Bit Shift Register
    • 在CS的上升沿,把16-Bit Shift Register中的10位数据传入10-Bit DAC Register,作为模拟量在OUT引脚输出

    注意:

    • 传输的16位数据中,高4位是无意义的
    • 中间10位才被转换为模拟量
    • 最低2位必须是0

    2.2 时序图

    在这里插入图片描述

    使用SPI传输的细节:

    • SCLK初始电平为低
    • 使用16个SCLK周期来传输16位数据
    • 在SCLK上升沿读取DIN电平
    • 在SCLK上升沿发出DOUT信号
    • DOUT数据来自16-Bit Shift Register
      • 低1个数据是上次数据遗留下的LSB位
      • 其余16个数据来自16-Bit Shift Register的高15位
      • 16-Bit Shift Register的LSB在下一个周期的第1个时钟传输
      • LSB必定是0,所以当前的周期里读出16-Bit Shift Register的15位数据也足够了

    2.3 DAC公式

    在这里插入图片描述

    输出电压 = 2 * VREFIN * n / 1024 = 2 * 2.048 * n / 1024
    其中:n为10位数值
    
    • 1
    • 2

    2.3 编写设备树

    确认SPI时钟最大频率
    在这里插入图片描述
    在这里插入图片描述

    这里一个周期的时间就是 T W ( C L ) + T W ( C H ) = 25 + 25 = 50 n s T_W(CL)+T_W(CH) = 25 + 25 = 50ns TW(CL)+TW(CH)=25+25=50ns
    对应的频率就是 1 / 50 n s = 20 ∗ 1 0 6 = 20 M H z 1/50ns=20*10^6=20MHz 1/50ns=20106=20MHz

    设备树如下:

    dac: dac@00 {
    	compatible = "spidev";
    	reg = <0>;
    	spi-max-frequency = <20000000>;		//从DAC芯片手册获得
    };	
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.4 编写内核支持SPI_DEV模块

    需要开启user spi support

    -> Device Drivers
      -> SPI support (SPI [=y]) 
        < >   User mode SPI device driver support  
    
    • 1
    • 2
    • 3

    2.5 编写APP

    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    #include 
    #include 
    
    #include 
    #include 
    
    /* dac_test /dev/spidevB.D  */
    
    int main(int argc, char **argv)
    {
    	int fd;
    	unsigned int val;
    	struct spi_ioc_transfer	xfer[1];
    	unsigned char tx_buf[2];
    	unsigned char rx_buf[2];
    	int	status;
    
    	if(argc != 3) {
    		printf("Usage: %s /dev/spidevB.D \n", argv[0]);
    		return 0;
    	}
    
    
    	fd = open(argv[1], O_RDWR);
    	if (fd < 0) {
    		printf("can not open %s\n", argv[1]);
    		return 1;
    	}
    
    	val = strtoul(argv[2], NULL, 0);
    	val <<= 2;		/* bit0, bit1 = 0b00 */
    	val &= 0xFFC;	/* only reserve 10 bit */
    
    	tx_buf[0] = (val>>8) & 0xff;
    	tx_buf[1] = val & 0xff;
    
    	memset(xfer, 0, sizeof xfer);
    
    	xfer[0].len = 2;
    	xfer[0].tx_buf = (unsigned long) tx_buf;
    	xfer[0].rx_buf = (unsigned long) rx_buf;
    
    	status = ioctl(fd, SPI_IOC_MESSAGE(1), xfer);
    	if (status < 0) {
    		printf("SPI_IOC_MESSAGE\n");
    		return -1;
    	}
    
    	/* print result */
    	val = (rx_buf[0] <<8)|(rx_buf[1]);
    	val >>= 2;
    	printf("pre val = %d\n", val);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    2.6 实验结果

    [root@firefly-rk3288:/home/picture/spi]# ./dac_test /dev/spidev0.0 0
    pre val = 0
    [root@firefly-rk3288:/home/picture/spi]# ./dac_test /dev/spidev0.0 100
    pre val = 0
    [root@firefly-rk3288:/home/picture/spi]# ./dac_test /dev/spidev0.0 100         0
    pre val = 100
    [root@firefly-rk3288:/home/picture/spi]# ./dac_test /dev/spidev0.0 100
    ^C
    [root@firefly-rk3288:/home/picture/spi]# ./dac_test /dev/spidev0.0 100       100
    0
    pre val = 100
    [root@firefly-rk3288:/home/picture/spi]# ./dac_test /dev/spidev0.0 100      ^C
    [root@firefly-rk3288:/home/picture/spi]# ./dac_test /dev/spidev0.0 200
    0
    pre val = 1000
    [root@firefly-rk3288:/home/picture/spi]# ./dac_test /dev/spidev0.0 200      1500
    Usage: ./dac_test /dev/spidevB.D <val>
    [root@firefly-rk3288:/home/picture/spi]# ./dac_test /dev/spidev0.0 100
    0
    pre val = 976
    [root@firefly-rk3288:/home/picture/spi]# ./dac_test /dev/spidev0.0 100       500
    pre val = 1000
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
  • 相关阅读:
    Java全栈解密:从JVM内存管理到Spring框架,揭秘垃圾回收、类加载机制与Web开发精髓的全方位旅程
    如何从清空的回收站中恢复已删除的Word文档?
    Scrapy 框架之 Item Pipeline 的使用
    Linux 权限系统
    数据仓库之Kappa架构
    C++智能指针[下](shared_ptr/weak_ptr/循环引用/删除器)
    操作系统学习笔记1 | 初识操作系统
    基于java+springboot+vue实现的高校社团管理系统(文末源码+Lw+ppt)23-419
    云服务器ECS价格表出炉_2024年最新价格表——阿里云
    qframework 架构 (作者:凉鞋)使用笔记
  • 原文地址:https://blog.csdn.net/ch122633/article/details/126255440