cuốn sách gpt4 ai đã làm

c - Bộ chuyển đổi tương tự sang số FPGA DE1-SOC

In lại Tác giả: Taklimakan Thời gian cập nhật: 2023-11-03 01:15:41 26 4
mua khóa gpt4 Nike

Tôi có DE1-SOC (phiên bản C) chạy Linux. Tôi gặp sự cố khi truy cập ADC trên bo mạch. Đầu vào của tất cả 8 kênh là tín hiệu hình sin 3V Pk-Pk. ADC trên bo mạch là ADC 8 kênh 12 bit AD7928. Bảng dữ liệu nói rằng ADC có thể xử lý tín hiệu lưỡng cực và đưa ra sơ đồ mạch sau:

Sơ đồ mạch lưỡng cực AD7928

Tất cả tám kênh đều yêu cầu lấy mẫu liên tục. Bảng dữ liệu DE1-SOC chỉ định việc đặt thanh ghi kênh một thành 1, kích hoạt tùy chọn tự động cập nhật trên ADC. Đây là lần thử đầu tiên của tôi với mã. Nó biên dịch và chạy, nhưng các giá trị không chính xác vì máy hiện sóng của tôi cũng đang đo tín hiệu tương tự đi vào ADC.

#include 
#include
#include
#include
#include
#include
#include

/* CẦU CẦU HPS FPGA */
#define LW_BRIDGE_BASE (0xFF200000)
#define HW_REGS_BASE (0xFF200000)
#define HW_REGS_SPAN (0x00200000)
#define HW_REGS_MASK ( HW_REGS_SPAN - 1 )

/* Cầu trục HPS-2-FPGA */
#define ALT_AXI_FPGASLVS_OFST (0xC0000000) // axi_master
#define HW_FPGA_AXI_SPAN (0x40000000) // Nhịp cầu 1GB
#define HW_FPGA_AXI_MASK ( HW_FPGA_AXI_SPAN - 1 )

/* THỜI GIAN ĐĂNG KÝ ADC */
#define ADC_BASE (0x00004000)

/* KÊNH ADC & ĐĂNG KÝ CẬP NHẬT */
#define ADC_CH0_UPDATE (LW_BRIDGE_BASE+ADC_BASE)
#define ADC_CH1_AUTO_UPDATE (LW_BRIDGE_BASE+ADC_BASE+4) // Viết 1 cho yêu cầu ADC liên tục
#define ADC_CH2 (LW_BRIDGE_BASE+ADC_BASE+8)
#define ADC_CH3 (LW_BRIDGE_BASE+ADC_BASE+12)
#define ADC_CH4 (LW_BRIDGE_BASE+ADC_BASE+16)
#define ADC_CH5 (LW_BRIDGE_BASE+ADC_BASE+20)
#define ADC_CH6 (LW_BRIDGE_BASE+ADC_BASE+24)
#define ADC_CH7 (LW_BRIDGE_BASE+ADC_BASE+28)

/* KẾT THÚC ĐĂNG KÝ ADC */
#define ADC_END (0x0000001F)

int chính() {

// Định nghĩa các biến
void *virtual_base;
int fd;
int dễ bay hơi *h2p_lw_adc_addr;
int i;

//Định nghĩa con trỏ để đăng ký
if((fd = open( "/dev/mem",(O_RDWR | O_SYNC ))) == -1) {
printf("LỖI: không thể mở \"/dev/mem\"...\n");
trở lại (1);
}

virtual_base = mmap(NULL,HW_REGS_SPAN,(PROT_READ | PROT_WRITE),MAP_SHARED,fd,HW_REGS_BASE);
if(virtual_base == MAP_FAILED) {
printf("LỖI: mmap() không thành công...\n");
đóng(fd);
trở lại (1);
}

h2p_lw_adc_addr = virtual_base + ((int)(LW_BRIDGE_BASE + ADC_BASE)&(int)(HW_REGS_MASK));

phao Vref = 5,0;
float stepSize = Vref/4096.0;

/* Tiêu đề và tính toán kích thước/độ phân giải của bước */
printf("*______________________________*\n");
printf("* Thiết lập ADC AD7928 *\n");
printf("*______________________________*\n");
printf("Độ phân giải cho 5V Vref: %f[mV]\n", stepSize*1000);

// Thiết lập ADC cho tín hiệu lưỡng cực
// ...

// Tự động cập nhật tất cả các kênh liên tục
*(int *)(h2p_lw_adc_addr + 4) = 1;

// Lấy mẫu một kênh
// ...

/* Nỗ lực thu thập dữ liệu số 1 */
int num = 5; // Số lượng mẫu?
mẫu int không dấu[num];

kênh int = 16; // kênh 4
vì (i = 0; i < num; i++){
samples[i] = *(int *)(h2p_lw_adc_addr + kênh);
}

if(munmap(virtual_base, HW_REGS_SPAN) != 0) {
printf("LỖI: munmap() không thành công...\n");
đóng(fd);
trở lại (1);
}
đóng(fd);
return 0;
}

Nó sử dụng Makefile này để biên dịch chéo:

C_SRC := adc.c
CFLAGS := -g -O0 -Tường
LDFLAGS := -lm

CROSS_COMPILE := arm-linux-gnueabihf-
CC := $(CROSS_COMPILE)gcc
NM := $(CROSS_COMPILE)nm

ifeq ($(hoặc $(COMSPEC),$(ComSpec)),)
RM := rm -rf
khác
RM := cs-rm -rf
cuối cùng

ELF ?= adc
OBJ := $(patsubst %.c,%.o,$(C_SRC))

.co:
$(CC) $(CFLAGS) -c $< -o $@

.PHONY: tất cả
tất cả: $(ELF)

.PHONY:
lau dọn:
$(RM) $(ELF) $(OBJ) $(OBJS) *.map *.objdump

$(ELF): $(OBJ) $(OBJS)
$(CC) $(CFLAGS) $(OBJ) $(OBJS) -o $@ $(LDFLAGS)
$(NM) $@ > $@.map

Tôi mới làm quen với ADC và DSP, nhưng lý tưởng nhất là tôi muốn có thể đo liên tục tất cả tám kênh, ghi lại biên độ từ đỉnh đến đỉnh (biên độ) của sóng hình sin đầu vào trong mỗi kênh, sóng này cuối cùng sẽ được sử dụng trong xử lý hậu kỳ.

Tính đến thời điểm hiện tại, đầu ra của năm mẫu luôn là 0, trừ khi tôi lấy mẫu kênh 1 thì tất cả năm mẫu đều là 1, như sau:

Mẫu [0]: 1
Mẫu [1]: 1
Mẫu [2]: 1
Mẫu [3]: 1
Mẫu [4]: ​​​​1

Ngay cả khi tôi tăng số lượng mẫu, kênh 1 luôn là 1 và tất cả các kênh khác luôn là 0.

Tôi nghĩ vấn đề của tôi có thể là sự kết hợp mã của tôi hoặc có thể không phải là mạch đệm? (Nhưng tôi không xử lý các đầu vào lưỡng cực chỉ vì tôi có thể đặt độ lệch DC trên bộ tạo tín hiệu của mình để nó là pk-pk 3v hoàn toàn dương.)

Vref trên ADC được cung cấp điện áp DC 5V thống nhất. Hiện tại tôi khá lạc lõng nên mọi trợ giúp hoặc gợi ý đều sẽ được đánh giá cao.

câu trả lời hay nhất

Tôi cá là vấn đề của bạn là ở những dòng sau:

> int dễ bay hơi *h2p_lw_adc_addr;
>
> *(int *)(h2p_lw_adc_addr + 4) = 1;
>
> mẫu[i] = *(int *)(h2p_lw_adc_addr + kênh);

因为h2p_lw_adc_addrđang chỉ vàointcon trỏ, do đó bạn sẽ nhận được địa chỉ sai trong hai dòng tiếp theo.

Khi cộng số N vào int con trỏ, con trỏ kết quả là N * sizeof(int) lớn hơn int 指针。

Sẽ h2p_lw_adc_addr Loại được thay đổi thành ký tự Con trỏ để khắc phục nhanh:

char dễ bay hơi *h2p_lw_adc_addr;

或者或者, bạn có thể thay đổi phần bù:

 *(int *)(h2p_lw_adc_addr + 1) = 1;
kênh int = 4; // kênh 4

Nhưng trong trường hợp đó tôi sẽ đề nghị int 上使用 int32_t hoặc uint32_t:

Về chuyển đổi tương tự sang kỹ thuật số c-FPGA DE1-SOC, chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/52287529/

26 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress