petalinux_zynq7 驱动DAC以及ADC模块之三:实现C语言API并编译出库被python调用

前文:

petalinux_zynq7 C语言驱动DAC以及ADC模块之一:建立IPicon-default.png?t=N7T8https://blog.csdn.net/qq_27158179/article/details/136234296petalinux_zynq7 C语言驱动DAC以及ADC模块之二:petalinuxicon-default.png?t=N7T8https://blog.csdn.net/qq_27158179/article/details/136236138注意ADC寄存器的起始地址是:0x43c20000。DAC寄存器的起始地址是0x43c30000。 

1. DAC demo

1.1 寄存器定义

130个32位的寄存器定义
序号    定义
0        控制1,PS写,采样频率设置
1        控制2,PS写,高8位是DAC使能,低8位是数据长度
2        回复1,PL写,
3-129    数据,PS写


1.2 用devmem测试

命令行
读:

devmem 0x43c30000 32

写:

devmem 0x43c30000 32 1
devmem 0x43c30000 32 0
#devmem 0x43c30000 32 0x12345678

1.3 dac_demo.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h> 
#include <sys/mman.h>
#include "stdint.h"     // uint8_t
#include <math.h>       // sin#define ADC_REG_BASE   (0x43c20000)
#define DAC_REG_BASE   (0x43c30000)
#define MAP_SIZE        0x208#define PI 3.1415926535897932384626433832795int main (int argc,char *argv[])
{int fd;// initfd = open("/dev/mem", O_RDWR | O_NDELAY);if(fd < 0)    {printf("open /dev/mem failed.\n");return 0;}unsigned char *var_dac_reg_base = (unsigned char *)mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, DAC_REG_BASE);// write test// 设置采样频率(DAC目前采样频率和数据长度需要是64的倍数)*(volatile unsigned int *)(var_dac_reg_base + 0) = 12800000;usleep(1000);// 设置数据长度uint16_t length = 128;*(volatile unsigned int *)(var_dac_reg_base + 4) = length;// 准备数据内容uint8_t raw_buff[200];// 准备数据内容 - 三角波//for(int i =0;i<length;i++){//    raw_buff[i] = i;//}// 准备数据内容 - 正弦波for(int i =0;i<length;i++){double raw = 0.5 * sin(2*PI*i / length) + 0.5;raw_buff[i] = raw * 0xff;}printf("raw_buff[%d]: ", length);for(int i =0;i<length;i++){printf("%02X ", raw_buff[i]);}printf("\r\n");// 设置数据for(int i=0;i<length/4;i++){uint32_t dat_1 = raw_buff[4*i + 0];uint32_t dat_2 = raw_buff[4*i + 1];uint32_t dat_3 = raw_buff[4*i + 2];uint32_t dat_4 = raw_buff[4*i + 3];uint32_t dat_int = (dat_4 << 24) + (dat_3 << 16) + (dat_2 << 8) + dat_1;*(volatile unsigned int *)(var_dac_reg_base + 4*3 + 4*i) = dat_int;}// 开始输出*(volatile unsigned int *)(var_dac_reg_base + 4) |= 0x00010000;// 停止输出//*(volatile unsigned int *)(var_dac_reg_base + 4) &= 0xFFFEFFFF;// read testusleep(1000);for(int i = 0;i<MAP_SIZE;i = i+4){printf("0x%08X = ",(DAC_REG_BASE +i));printf("0x%08X \n",*(volatile unsigned int *)(var_dac_reg_base +i));}// closeif(fd){close(fd);}munmap(var_dac_reg_base, MAP_SIZE);return 0;
}

1.4 编译[PC]

环境变量

source /tools/Xilinx/Vivado/2018.3/settings64.sh

编译带math.h需要链接m库

arm-linux-gnueabihf-gcc dac_demo.c -o dac_demo -lm

1.5 运行[ZYNQ]

板子上执行 ./dac_demo

用red pitaya开发板的adc输入连接板子的dac输出。

2. ADC demo

2.1 寄存器定义

130个32位的寄存器定义
序号    定义
0        控制1,PS写,采样频率设置
1        控制2,PS写,高16位是采样状态控制,低16位是采样数量
2        回复1,PL写,
3-129    数据,PL写

ADC读取大致过程:

PS:设置控制2为0001xxxx,空闲
PL:设置回复1为0001xxxx,空闲
PS:设置控制2为0002xxxx,开始采样
PL:设置回复1为0002xxxx,开始采样
PL:设置回复1为0004xxxx,采样完毕
PS:设置控制2为0004xxxx,采样完毕
 

2.2 adc_demo.c

// 编译:arm-linux-gnueabihf-gcc adc_demo.c -o adc_1k#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include "stdint.h"     // uint8_t#define ADC_REG_BASE   (0x43c20000)
#define DAC_REG_BASE   (0x43c30000)
#define MAP_SIZE        0x208			// 130*4int main (int argc,char *argv[])
{int fd;// initfd = open("/dev/mem", O_RDWR | O_NDELAY);if(fd < 0){printf("open /dev/mem failed.\n");return 0;}unsigned char *var_adc_reg_base = (unsigned char *)mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ADC_REG_BASE);// write test// 设置采样频率*(volatile unsigned int *)(var_adc_reg_base + 0) = 10000000;usleep(1000);// 设置数据长度uint16_t length = 300;*(volatile unsigned int *)(var_adc_reg_base + 4) = length;// 设置采样状态 - 准备printf("[INFO]adc idle\r\n");*(volatile unsigned int *)(var_adc_reg_base + 4) &= 0x0000FFFF;*(volatile unsigned int *)(var_adc_reg_base + 4) |= 0x00010000;usleep(1000);uint32_t slv_reg0;uint32_t slv_reg1;uint32_t slv_reg2;slv_reg0 = *(volatile unsigned int *)(var_adc_reg_base + 0);slv_reg1 = *(volatile unsigned int *)(var_adc_reg_base + 4*1);slv_reg2 = *(volatile unsigned int *)(var_adc_reg_base + 4*2);printf("[DEBUG]slv_reg0 = 0x%08X, slv_reg1 = 0x%08X, slv_reg2 = 0x%08X \r\n", slv_reg0, slv_reg1, slv_reg2);if( (slv_reg2 & 0x00010000) != 0x00010000){printf("error\r\n");}// read test// usleep(1000);// printf("[DEBUG]read test...\r\n");// for(int i = 0;i<MAP_SIZE;i = i+4)// {//     printf("0x%08X = ",(ADC_REG_BASE +i));//     printf("0x%08X \n",*(volatile unsigned int *)(var_adc_reg_base +i));//     if(i >= length) break;// }// 设置采样状态 - 开始printf("[INFO]adc start\r\n");*(volatile unsigned int *)(var_adc_reg_base + 4) &= 0x0000FFFF;*(volatile unsigned int *)(var_adc_reg_base + 4) |= 0x00020000;// 等待for(int i = 0;;i++){usleep(1);slv_reg0 = *(volatile unsigned int *)(var_adc_reg_base + 0);slv_reg1 = *(volatile unsigned int *)(var_adc_reg_base + 4*1);slv_reg2 = *(volatile unsigned int *)(var_adc_reg_base + 4*2);printf("[DEBUG]slv_reg0 = 0x%08X, slv_reg1 = 0x%08X, slv_reg2 = 0x%08X \r\n", slv_reg0, slv_reg1, slv_reg2);if( (slv_reg2 & 0x00040000) ==  0x00040000 ){printf("[INFO]adc ok\r\n");break;}else if(i > 100000){printf("[ERROR]adc fail, timeout\r\n");break;}}// read test// usleep(1000);printf("[DEBUG]read test...\r\n");for(int i = 0;i<MAP_SIZE;i = i+4){printf("0x%08X = ",(ADC_REG_BASE +i));printf("0x%08X \n",*(volatile unsigned int *)(var_adc_reg_base +i));if(i >= length) break;}// 获取采样数据printf("[INFO]adc data parsing...\r\n");uint8_t adc_buff[1024];uint16_t adc_buff_length = 0;for(int i = 0;i<MAP_SIZE;i = i+4){if(i < 3*4) continue;uint32_t dat_u32 = *(volatile unsigned int *)(var_adc_reg_base + i);printf("%08X ", dat_u32);uint32_t dat_u8_1 = dat_u32 & 0x000000FF;uint32_t dat_u8_2 = (dat_u32 & 0x0000FF00) >> 8;uint32_t dat_u8_3 = (dat_u32 & 0x00FF0000) >> 16;uint32_t dat_u8_4 = (dat_u32 & 0xFF000000) >> 24;adc_buff[adc_buff_length] = dat_u8_1;adc_buff_length++;adc_buff[adc_buff_length] = dat_u8_2;adc_buff_length++;adc_buff[adc_buff_length] = dat_u8_3;adc_buff_length++;adc_buff[adc_buff_length] = dat_u8_4;adc_buff_length++;if(adc_buff_length >= length) break;}printf("\r\n");// 打印结果printf("[INFO]adc_buff[%d]: ", adc_buff_length);for(int i =0;i<adc_buff_length;i++){printf("%02X ", adc_buff[i]);}printf("\r\n");// read test// usleep(1000);// printf("[DEBUG]read test...\r\n");// for(int i = 0;i<MAP_SIZE;i = i+4)// {//     printf("0x%08X = ",(ADC_REG_BASE +i));//     printf("0x%08X \n",*(volatile unsigned int *)(var_adc_reg_base +i));//     if(i >= length) break;// }// closeif(fd){close(fd);}munmap(var_adc_reg_base, MAP_SIZE);return 0;
}

 2.3 编译[PC]
 

source /tools/Xilinx/Vivado/2018.3/settings64.sh
arm-linux-gnueabihf-gcc adc_demo.c -o adc_demo

2.4 运行[ZYNQ]

./adc_demo

命令行会打印到ADC的十六进制字符串。 

 2.5 ADC结果pycharm绘图[PC]

2.5.1 创建工程

File -> Create Project -> 
-> Location: G:\sdk_dmaadc_py
-> Base interpreter: Python3.9
-> OK

2.5.2 修改 adc_test.py

输入内容:

import matplotlib.pyplot as plt
import numpy as npif __name__ == '__main__':# triangledata_str = "E0 CC E0 C6 E0 C4 E0 C4 E0 C4 E0 BF E0 BC DF BC E0 BC C0 B6 C0 B4 C0 B4 BF B4 C0 AF C0 AF B0 A8 AF AF B0 A7 B0 A4 B0 A4 B0 A4 B0 A4 B0 9C A0 97 A0 96 A0 98 A0 94 A0 90 A0 8D A0 94 A0 8C 90 87 90 84 90 86 90 84 90 80 80 E0 FF E4 FF E4 FF E0 FF DC E0 DC FF DC DF D7 E0 D4 E0 D4 E0 D4 E0 D4 E0 CC E0 C9"# sin#data_str = "70 66 60 57 60 4C 50 46 4F 3F 40 34 30 27 30 24 30 24 30 1C 30 18 30 19 30 1F 30 1F 30 24 2F 2F 30 34 3F 3F 50 44 50 4D 60 5F 70 68 70 74 80 7D 90 8D A0 9C B0 A6 B0 B4 C0 BC E0 CC E0 D4 E0 D4 E0 DC FF E4 FF E4 FF E4 FF E4 FF E7 FF E0 FF DC DF D4 E0 CF E0 C7 E0 BC C0 AF B0 A4 B0 9C A0 8C 90 7D 80 70"print(data_str)data_list = data_str.split(" ")y = np.array([int(x, base=16) for x in data_list])x = np.arange(len(y))plt.plot(x, y)plt.show()

2.5.3 安装插件

File -> Settings -> Project: sdk_dmaadc_py -> Python Interpreter -> +
-> matplotlib -> Install Package
-> numpy -> Install Package
-> OK

2.5.4 运行测试

右键 adc_test.py -> Run 'adc_test' -> 

3. adda库

编写两个文件,adda.c,adda.h。可编译出库。

3.1 adda.c

// 编译 arm-linux-gnueabihf-gcc adda.c -o adda -lm
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include "stdint.h"     // uint8_t
#include <math.h>       // sin#define ADC_REG_BASE   (0x43c20000)
#define DAC_REG_BASE   (0x43c30000)
#define MAP_SIZE        0x208               // 130*4#define PI 3.1415926535897932384626433832795int fd;
unsigned char *var_dac_reg_base;
unsigned char *var_adc_reg_base;int adda_open()
{// initfd = open("/dev/mem", O_RDWR | O_NDELAY);if(fd < 0){printf("open /dev/mem failed.\n");return -1;}var_dac_reg_base = (unsigned char *)mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, DAC_REG_BASE);var_adc_reg_base = (unsigned char *)mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, ADC_REG_BASE);return 0;
}
int adda_DacSetSampleFrequency(int sample_frequency)
{// 设置采样频率(DAC目前采样频率和数据长度需要是64的倍数)*(volatile unsigned int *)(var_dac_reg_base + 0) = sample_frequency;usleep(10);return 0;
}
int adda_DacGenDataTriangle(uint8_t* data_buf, uint32_t data_length)
{// 准备数据内容 - 三角波for(int i =0;i<data_length;i++){uint32_t raw = i * 255 / data_length;data_buf[i] = raw;}// printf("data_buf[%d]: ", data_length);// for(int i =0;i<data_length;i++){//     printf("%02X ", data_buf[i]);// }// printf("\r\n");return 0;
}
int adda_DacGenDataSin(uint8_t* data_buf, uint32_t data_length)
{// 准备数据内容 - 正弦波for(int i =0;i<data_length;i++){double raw = 0.5 * sin(2*PI*i / data_length) + 0.5;data_buf[i] = raw * 0xff;}// printf("data_buf[%d]: ", data_length);// for(int i =0;i<data_length;i++){//     printf("%02X ", data_buf[i]);// }// printf("\r\n");return 0;
}
int adda_DacSetData(uint8_t* data_buf, uint16_t data_length)
{// 设置数据长度*(volatile unsigned int *)(var_dac_reg_base + 4) = data_length;// 设置数据for(int i=0;i<data_length/4;i++){uint32_t dat_1 = data_buf[4*i + 0];uint32_t dat_2 = data_buf[4*i + 1];uint32_t dat_3 = data_buf[4*i + 2];uint32_t dat_4 = data_buf[4*i + 3];uint32_t dat_int = (dat_4 << 24) + (dat_3 << 16) + (dat_2 << 8) + dat_1;*(volatile unsigned int *)(var_dac_reg_base + 4*3 + 4*i) = dat_int;}return 0;
}
int adda_DacSetOutput(int enable){if(enable == 1){// 开始输出*(volatile unsigned int *)(var_dac_reg_base + 4) |= 0x00010000;}else{// 停止输出*(volatile unsigned int *)(var_dac_reg_base + 4) &= 0xFFFEFFFF;}return 0;
}
int adda_close()
{// closeif(fd){close(fd);}munmap(var_dac_reg_base, MAP_SIZE);munmap(var_adc_reg_base, MAP_SIZE);return 0;
}int demo_dac_sin()
{// initadda_open();// dac 采样频率adda_DacSetSampleFrequency(128000);// dac 数组 - 正弦波uint8_t dac_buf[1024];uint16_t dac_length = 128;adda_DacGenDataSin(dac_buf, dac_length);adda_DacSetData(dac_buf, dac_length);// dac输出开启adda_DacSetOutput(1);// 延迟10秒usleep(10000000);// closeadda_close();return 0;
}int demo_dac_triangle()
{// initadda_open();// dac 采样频率adda_DacSetSampleFrequency(128000);// dac 数组 - 三角波uint8_t dac_buf[1024];uint16_t dac_length = 128;adda_DacGenDataTriangle(dac_buf, dac_length);adda_DacSetData(dac_buf, dac_length);// dac输出开启adda_DacSetOutput(1);// 延迟10秒usleep(10000000);// closeadda_close();return 0;
}int adda_AdcSetSampleFrequency(int sample_frequency)
{// 设置采样频率*(volatile unsigned int *)(var_adc_reg_base + 0) = sample_frequency;usleep(10);return 0;
}
int adda_AdcSampleData(uint8_t* data_buf, uint16_t data_length)
{// 设置数据长度*(volatile unsigned int *)(var_adc_reg_base + 4) = data_length;// 设置采样状态 - 准备// printf("[INFO]adc idle\r\n");*(volatile unsigned int *)(var_adc_reg_base + 4) &= 0x0000FFFF;*(volatile unsigned int *)(var_adc_reg_base + 4) |= 0x00010000;usleep(1000);uint32_t slv_reg0;uint32_t slv_reg1;uint32_t slv_reg2;slv_reg0 = *(volatile unsigned int *)(var_adc_reg_base + 0);slv_reg1 = *(volatile unsigned int *)(var_adc_reg_base + 4*1);slv_reg2 = *(volatile unsigned int *)(var_adc_reg_base + 4*2);// printf("[DEBUG]slv_reg0 = 0x%08X, slv_reg1 = 0x%08X, slv_reg2 = 0x%08X \r\n", slv_reg0, slv_reg1, slv_reg2);if( (slv_reg2 & 0x00010000) != 0x00010000){printf("error\r\n");}// read test// usleep(1000);// printf("[DEBUG]read test...\r\n");// for(int i = 0;i<MAP_SIZE;i = i+4)// {//     printf("0x%08X = ",(ADC_REG_BASE +i));//     printf("0x%08X \n",*(volatile unsigned int *)(var_adc_reg_base +i));//     if(i >= length) break;// }// 设置采样状态 - 开始// printf("[INFO]adc start\r\n");*(volatile unsigned int *)(var_adc_reg_base + 4) &= 0x0000FFFF;*(volatile unsigned int *)(var_adc_reg_base + 4) |= 0x00020000;// 等待for(int i = 0;;i++){usleep(1);slv_reg0 = *(volatile unsigned int *)(var_adc_reg_base + 0);slv_reg1 = *(volatile unsigned int *)(var_adc_reg_base + 4*1);slv_reg2 = *(volatile unsigned int *)(var_adc_reg_base + 4*2);// printf("[DEBUG]slv_reg0 = 0x%08X, slv_reg1 = 0x%08X, slv_reg2 = 0x%08X \r\n", slv_reg0, slv_reg1, slv_reg2);if( (slv_reg2 & 0x00040000) ==  0x00040000 ){// printf("[INFO]adc ok\r\n");break;}else if(i > 100000){printf("[ERROR]adc fail, timeout\r\n");break;}}// read test// usleep(1000);// printf("[DEBUG]read test...\r\n");// for(int i = 0;i<MAP_SIZE;i = i+4)// {//     printf("0x%08X = ",(ADC_REG_BASE +i));//     printf("0x%08X \n",*(volatile unsigned int *)(var_adc_reg_base +i));//     if(i >= data_length) break;// }// 获取采样数据// printf("[INFO]adc data parsing...\r\n");uint16_t adc_buff_length = 0;for(int i = 0;i<MAP_SIZE;i = i+4){if(i < 3*4) continue;uint32_t dat_u32 = *(volatile unsigned int *)(var_adc_reg_base + i);// printf("%08X ", dat_u32);uint32_t dat_u8_1 = dat_u32 & 0x000000FF;uint32_t dat_u8_2 = (dat_u32 & 0x0000FF00) >> 8;uint32_t dat_u8_3 = (dat_u32 & 0x00FF0000) >> 16;uint32_t dat_u8_4 = (dat_u32 & 0xFF000000) >> 24;data_buf[adc_buff_length] = dat_u8_1;adc_buff_length++;data_buf[adc_buff_length] = dat_u8_2;adc_buff_length++;data_buf[adc_buff_length] = dat_u8_3;adc_buff_length++;data_buf[adc_buff_length] = dat_u8_4;adc_buff_length++;if(adc_buff_length >= data_length) break;}// printf("\r\n");}int demo_adc()
{// initadda_open();// 设置采样频率adda_AdcSetSampleFrequency(100000);// 开始采样uint8_t adc_buff[1024];uint16_t adc_buff_length = 100;adda_AdcSampleData(adc_buff, adc_buff_length);// 打印结果printf("adc_buff[%d]: ", adc_buff_length);for(int i =0;i<adc_buff_length;i++){printf("%02X ", adc_buff[i]);}printf("\r\n");// closeadda_close();
}

3.2 adda.h


#ifndef ADDA_H
#define ADDA_H#include "stdint.h"     // uint8_tint adda_open();
int adda_DacSetSampleFrequency(int sample_frequency);
int adda_AdcSetSampleFrequency(int sample_frequency);
int adda_DacGenDataTriangle(uint8_t* data_buf, uint32_t data_length);
int adda_DacGenDataSin(uint8_t* data_buf, uint32_t data_length);
int adda_DacSetData(uint8_t* data_buf, uint16_t data_length);
int adda_DacSetOutput(int enable);
int adda_close();int demo_dac_sin();
int demo_dac_triangle();int adda_AdcSetSampleFrequency(int sample_frequency);
int adda_AdcSampleData(uint8_t* data_buf, uint16_t data_length);
int demo_adc();#endif //ADDA_H

3.3 C语言调用libadda

3.3.1 编译出 libadda
 

source /tools/Xilinx/Vivado/2018.3/settings64.sh
arm-linux-gnueabihf-gcc -c adda.c -I./
arm-linux-gnueabihf-ar -r libadda.a *.o
rm *.o

3.3.2 main.c

创建 main.c

#include <stdio.h>
#include "adda.h"
#include <unistd.h>int main (int argc,char *argv[])
{demo_dac_sin();demo_dac_triangle();demo_adc();return 0;
}

编译[PC]:
arm-linux-gnueabihf-gcc main.c -o main -L./ -ladda -lm

运行[ZYNQ]
./main

 3.4 python调用libadda

3.4.1 编译出 libadda

编译出动态库 libadda.so

source /tools/Xilinx/Vivado/2018.3/settings64.sh
arm-linux-gnueabihf-gcc -o adda.o -shared -fPIC -c adda.c
arm-linux-gnueabihf-gcc -o libadda.so adda.o -shared -fPIC

3.4.2 main.py

import ctypes
import timell = ctypes.cdll.LoadLibrary
libadda = ll("./libadda.so")# 输出十六进制类型数组
def print_hex(bytes):l = [hex(int(i)) for i in bytes]print(" ".join(l))# 字节列表以16进制格式打印数据
def bytes_to_hexstring(data):lin = ['%02X' % i for i in data]	# [ ]内是列表解析语法 ,'%02X'%是格式化语法。hex_str = " ".join(lin)return hex_str# init
def adda_open():libadda.adda_open.restype = ctypes.c_intret = libadda.adda_open()# close
def adda_close():libadda.adda_close.restype = ctypes.c_intret = libadda.adda_close()# dac 采样频率
def adda_DacSetSampleFrequency(value):libadda.adda_DacSetSampleFrequency.argtype = ctypes.c_intlibadda.adda_DacSetSampleFrequency.restype = ctypes.c_intsample_frequency = ctypes.c_uint(value)ret = libadda.adda_DacSetSampleFrequency(sample_frequency)# dac 数组 - 正弦波
def adda_DacGenDataSin(desire_length):# uint8_t dac_buf[1024]libadda.adda_DacGenDataSin.argtype = [ctypes.POINTER(ctypes.c_ubyte*1024), ctypes.c_int]libadda.adda_DacGenDataSin.restype = ctypes.c_intdac_buf = ctypes.create_string_buffer(desire_length)dac_length = ctypes.c_uint(desire_length)ret = libadda.adda_DacGenDataSin(dac_buf, dac_length)ba_raw = bytearray(dac_buf.raw)ba_out = bytearray(dac_length.value)for i in range(dac_length.value):ba_out[i] = ba_raw[i]# print("ba_out", ba_out)b_out = bytes(ba_out)return b_out# dac 数组 - 三角波
def adda_DacGenDataTriangle(desire_length):# uint8_t dac_buf[1024]libadda.adda_DacGenDataTriangle.argtype = [ctypes.POINTER(ctypes.c_ubyte*1024), ctypes.c_int]libadda.adda_DacGenDataTriangle.restype = ctypes.c_intdac_buf = ctypes.create_string_buffer(desire_length)dac_length = ctypes.c_uint(desire_length)ret = libadda.adda_DacGenDataTriangle(dac_buf, dac_length)ba_raw = bytearray(dac_buf.raw)ba_out = bytearray(dac_length.value)for i in range(dac_length.value):ba_out[i] = ba_raw[i]# print("ba_out", ba_out)b_out = bytes(ba_out)return b_out# dac 数组 - 设置
def adda_DacSetData(data_bytes):libadda.adda_DacSetData.argtype = [ctypes.POINTER(ctypes.c_ubyte*1024), ctypes.c_int]libadda.adda_DacSetData.restype = ctypes.c_intdac_buf = ctypes.create_string_buffer(data_bytes)dac_length = ctypes.c_uint(len(data_bytes))ret = libadda.adda_DacSetData(dac_buf, dac_length)# dac 设置输出
def adda_DacSetOutput(enable):libadda.adda_DacSetOutput.argtype = ctypes.c_intlibadda.adda_DacSetOutput.restype = ctypes.c_intvalue = ctypes.c_uint(enable)ret = libadda.adda_DacSetOutput(value)# dac demo 1
def demo_dac_sin():#libadda.demo_dac_sin()# initadda_open()adda_DacSetSampleFrequency(128000)# dac 数组 - 正弦波dac_length = 128dac_buf = adda_DacGenDataSin(dac_length)print("dac_buf: ", bytes_to_hexstring(dac_buf))adda_DacSetData(dac_buf)# dac输出开启adda_DacSetOutput(1)# closeadda_close()# dac demo 2
def demo_dac_triangle():# libadda.demo_dac_triangle()# initadda_open()adda_DacSetSampleFrequency(128000)# dac 数组 - 三角波dac_length = 128dac_buf = adda_DacGenDataTriangle(dac_length)print("dac_buf: ", bytes_to_hexstring(dac_buf))adda_DacSetData(dac_buf)# dac输出开启adda_DacSetOutput(1)# closeadda_close()# adc 采样频率
def adda_AdcSetSampleFrequency(value):libadda.adda_AdcSetSampleFrequency.argtype = ctypes.c_intlibadda.adda_AdcSetSampleFrequency.restype = ctypes.c_intsample_frequency = ctypes.c_uint(value)ret = libadda.adda_AdcSetSampleFrequency(sample_frequency)# adc 获取采样数据
def adda_AdcSampleData(desire_length):libadda.adda_AdcSampleData.argtype = [ctypes.POINTER(ctypes.c_ubyte*1024), ctypes.c_int]libadda.adda_AdcSampleData.restype = ctypes.c_intadc_buf = ctypes.create_string_buffer(desire_length)adc_length = ctypes.c_uint(desire_length)ret = libadda.adda_AdcSampleData(adc_buf, adc_length)ba_raw = bytearray(adc_buf.raw)ba_out = bytearray(adc_length.value)for i in range(adc_length.value):ba_out[i] = ba_raw[i]# print("ba_out", ba_out)b_out = bytes(ba_out)return b_out# adc demo
def demo_adc():# initadda_open()# 设置采样频率adda_AdcSetSampleFrequency(100000)# 开始采样adc_length = 300adc_buff = adda_AdcSampleData(adc_length)# closeadda_close()# 打印结果print("adc_buff: ", bytes_to_hexstring(adc_buff))if __name__ == '__main__':# 输出正弦波# demo_dac_sin()# 延迟5秒# time.sleep(5)# 输出三角波demo_dac_triangle()# 延迟5秒# time.sleep(5)demo_adc()

3.4.3 运行测试

把 libadda.so和main.py拷贝到板子上

运行

python3 main.py

参考

[1]Linux在应用层读写寄存器的方法,https://blog.csdn.net/liukang325/article/details/26601811
[2]Linux在应用层读写寄存器,https://blog.csdn.net/qq_40629752/article/details/108772952
[3]Linux下c/c++的动态库、静态库制作和使用,并供python调用,https://blog.csdn.net/Snow_cat123456/article/details/113177204
[4]python3调用c++动态库(linux),https://zhuanlan.zhihu.com/p/466169852
[5]Python调用C的基础学习(传递数字、字符串、数组(一维、二维)、结构体),https://blog.csdn.net/qq_31342997/article/details/88374804

下篇:

petalinux_zynq7 C语言驱动DAC以及ADC模块之四:python实现http_apiicon-default.png?t=N7T8https://blog.csdn.net/qq_27158179/article/details/136239572

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/695960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跨界计算与控制,强化显控和UI, 君正MPU再添新旗舰--Ingenic MPU X2600隆重发布

近日&#xff0c;北京君正隆重发布MPU芯片新产品X2600。该产品以商业和工业应用的数个细分领域为重点目标市场&#xff0c;兼顾通用处理器应用需求。无论从CPU结构的设计&#xff0c;还是专门控制器和接口的配备&#xff0c;都体现了北京君正MPU团队“技术路线上追求自主跨界&a…

力扣101 对称二叉树 Java版本

文章目录 题目描述递归解法非递归解法 题目描述 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出…

性能全面提升!探索ONLYOFFICE最新8.0版:更快速、更强大,PDF表单编辑轻松搞定!

文章目录 PDF表单功能表单模板 屏幕朗读器功能EXCEL新增功能单变量求解图表向导数字排序 PPT 新增功能新增语言区域设置和优化插件界面 ONLYOFFICE 是由 Ascensio System SIA 推出的一款功能强大的办公套件&#xff0c;其中提供了适用于文本文档、表格以及演示文稿的在线编辑软…

前端|Day2:列表、表格、表单(黑马笔记)

Day2&#xff1a;列表、表格、表单 目录 Day2&#xff1a;列表、表格、表单一、列表1.无序列表2.有序列表3. 定义列表 二、表格1.基本使用2. 表格结构标签(了解)3.合并单元格 三、表单1.input 标签2.input 标签占位文本3.单选框4.上传文件5.多选框6.下拉菜单7.文本域8.label 标…

基于深度学习的红肉新鲜过期判决系统matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 系统构成与流程 4.2 模型训练与优化 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 ...............................................…

C#使用一个泛型方法操作不同数据类型的数组

目录 一、泛型方法及其存在的意义 二 、实例 1.源码 2.生成效果 再发一个泛型方法的示例。 一、泛型方法及其存在的意义 实际应用中&#xff0c;查找或遍历数组中的值时&#xff0c;有时因为数组类型的不同&#xff0c;需要对不同的数组进行操作&#xff0c;那么,可以使用…

蓝桥杯冲C++组还是选Python组从零开始?

蓝桥杯冲C&#xff0b;&#xff0b;组还是选Python组从零开始&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「c的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家…

Stable Diffusion 模型分享:Dark Sushi Mix 大颗寿司Mix

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十

苍穹外卖Day02——总结2

前期文章 文章标题地址苍穹外卖Day01——总结1https://blog.csdn.net/qq_43751200/article/details/135466359?spm1001.2014.3001.5501苍穹外卖Day01——解决总结1中存在的问题https://lushimeng.blog.csdn.net/article/details/135473412 总结2 前期文章1. 新增员工模块1.1 …

分布式学习Day5

文章目录 初始ES介绍倒排索引ES和MYSQL对比安装ES及其组件1.1.创建网络1.2.加载镜像1.3.运行2.1.部署 分词器 操作索引库文档操作RestAPI介绍 初始ES 介绍 倒排索引 ES和MYSQL对比 安装ES及其组件 1.1.创建网络 因为我们还需要部署kibana容器&#xff0c;因此需要让es和kiban…

【鸿蒙 HarmonyOS 4.0】网络请求

一、介绍 资料来自官网&#xff1a;文档中心 网络管理模块主要提供以下功能&#xff1a; HTTP数据请求&#xff1a;通过HTTP发起一个数据请求。WebSocket连接&#xff1a;使用WebSocket建立服务器与客户端的双向连接。Socket连接&#xff1a;通过Socket进行数据传输。 日常…

如何在Linux搭建Inis网站,并发布至公网实现远程访问【内网穿透】

如何在Linux搭建Inis网站&#xff0c;并发布至公网实现远程访问【内网穿透】 前言1. Inis博客网站搭建1.1. Inis博客网站下载和安装1.2 Inis博客网站测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.…

【Week-P8】YOLOv5-C3模块实现天气识别

YOLOv5-C3模块实现天气识别 一、环境配置二、准备数据三、搭建网络结构-YOLO-C3模块四、开始训练五、查看训练结果六、总结&#xff08;forward函数内部没有调用新增加的层&#xff0c;训练所使用的网络结构还是原来的结构&#xff0c;注意通道参数的一致&#xff0c;训练结果待…

MATLAB 导出可编辑的eps格式图像

任务描述&#xff1a;部分期刊要求提交可编辑的eps格式图像&#xff0c;方便美工编辑对图像进行美化 我试了直接print或者在figure窗口导出&#xff0c;发现导出的文件放到Adobe AI中并不能编辑&#xff0c;经Google找到解决办法&#xff1a; %EPS exportgraphics(gcf,myVect…

Linux中的各类时间 与 find命令的常用参数

之前研究wal日志清理的副产物&#xff0c;wal日志名被修改后文件的哪个时间会变&#xff1f;应该如何删除&#xff1f;由此整理一下Linux中atime、mtime、ctime的区别&#xff0c;以及find的常见用法。 一、 Linux中的各类时间 1. 各类时间的定义 Linux中有三种用于文件时间戳…

解决Uncaught SyntaxError: Cannot use import statement outside a module(at XXX)报错

报错原因&#xff1a;这个错误通常是因为你正在尝试在一个不支持 ES6 模块语法的环境中使用 import 语句。这可能是因为你的代码是在一个只支持 CommonJS 或 AMD 模块系统的环境中运行的&#xff0c;或者你的代码运行的环境没有正确配置以支持 ES6 模块。如果是在浏览器环境&am…

2024最佳住宅代理IP服务商推荐

跨境出海已成为了近几年的最热趋势&#xff0c;大批量的企业开始开拓海外市场&#xff0c;而海外电商领域则是最受欢迎的切入口。新兴的tiktok、Temu&#xff0c;老牌的Amazon、Ebay&#xff0c;热门的Etsy、Mecari等等都是蓝海一片。跨境入门并不难&#xff0c;前期的准备中不…

UE4 C++联网RPC教程笔记(三)(第8~9集)完结

UE4 C联网RPC教程笔记&#xff08;三&#xff09;&#xff08;第8~9集&#xff09;完结 8. exe 后缀实现监听服务器9. C 实现监听服务器 8. exe 后缀实现监听服务器 前面我们通过蓝图节点实现了局域网连接的功能&#xff0c;实际上我们还可以给项目打包后生成的 .exe 文件创建…

LeetCode 0106.从中序与后序遍历序列构造二叉树:分治(递归)——五彩斑斓的题解(若不是彩色的可以点击原文链接查看)

【LetMeFly】106.从中序与后序遍历序列构造二叉树&#xff1a;分治&#xff08;递归&#xff09;——五彩斑斓的题解&#xff08;若不是彩色的可以点击原文链接查看&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/construct-binary-tree-from-inorder-an…

FSQ: FINITE SCALAR QUANTIZATION: VQ-VAE MADE SIMPLE

Paper name FINITE SCALAR QUANTIZATION: VQ-VAE MADE SIMPLE Paper Reading Note Paper URL: https://arxiv.org/abs/2309.15505 Code URL: (官方 jax 实现) https://github.com/google-research/google-research/tree/master/fsq(pytorch 实现) https://github.com/luci…