前文:
petalinux_zynq7 C语言驱动DAC以及ADC模块之一:建立IPhttps://blog.youkuaiyun.com/qq_27158179/article/details/136234296petalinux_zynq7 C语言驱动DAC以及ADC模块之二:petalinux
https://blog.youkuaiyun.com/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.1415926535897932384626433832795
int main (int argc,char *argv[])
{
int fd;
// init
fd = 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 test
usleep(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));
}
// close
if(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*4
int main (int argc,char *argv[])
{
int fd;
// init