Linux STM32MP157 DMA+DAC 输出正弦波例程
时间: 2024-01-03 10:05:50 浏览: 209
以下是使用Linux STM32MP157板子的DMA+DAC输出正弦波的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <linux/dma-buf.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/dma-fence.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#define DAC_BASE_ADDRESS 0x40007400
#define DAC_DHR12R1 0x08
#define DAC_DHR12L1 0x0C
#define DAC_CR 0x00
#define PI 3.14159265
#define SAMPLE_RATE 48000
#define AMPLITUDE 2047
#define FREQUENCY 1000
int main()
{
int fd_mem = open("/dev/mem", O_RDWR | O_SYNC);
if (fd_mem < 0) {
printf("Failed to open /dev/mem\n");
return -1;
}
void* mem = mmap(0, 0x1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd_mem, DAC_BASE_ADDRESS);
if (mem == MAP_FAILED) {
printf("Failed to mmap memory\n");
return -1;
}
uint32_t* dac = (uint32_t*)mem;
// Enable DAC and DMA
dac[DAC_CR / 4] |= (1 << 0) | (1 << 12);
// Configure DMA
int fd_dma = open("/dev/dma-buf/0", O_RDWR | O_SYNC);
if (fd_dma < 0) {
printf("Failed to open /dev/dma-buf/0\n");
return -1;
}
uint32_t* buf = mmap(0, SAMPLE_RATE * sizeof(uint16_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd_dma, 0);
if (buf == MAP_FAILED) {
printf("Failed to mmap DMA buffer\n");
return -1;
}
uint16_t* samples = (uint16_t*)buf;
for (int i = 0; i < SAMPLE_RATE; i++) {
double t = (double)i / (double)SAMPLE_RATE;
samples[i] = (uint16_t)((double)AMPLITUDE * sin(2 * PI * FREQUENCY * t) + (double)AMPLITUDE);
}
struct dmaengine_cmd cmd = {
.flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK,
.wait_for_completion_timeout = 1000,
.size = SAMPLE_RATE * sizeof(uint16_t),
.direction = DMA_MEM_TO_DEV,
.src_start = buf,
.dst_start = &dac[DAC_DHR12R1 / 4],
};
int ret = ioctl(fd_dma, DMA_BUF_IOCTL_CMD, &cmd);
if (ret < 0) {
printf("Failed to configure DMA\n");
return -1;
}
printf("Press enter to stop the program\n");
getchar();
// Disable DAC and DMA
dac[DAC_CR / 4] &= ~((1 << 0) | (1 << 12));
// Unmap memory
munmap(buf, SAMPLE_RATE * sizeof(uint16_t));
munmap(mem, 0x1000);
close(fd_dma);
close(fd_mem);
return 0;
}
```
这段代码会生成一个1kHz的正弦波,并使用DMA将数据传输到DAC输出。你可以根据需要修改参数,比如采样率、幅值、频率等。同时,请注意实际硬件的数据手册和引脚定义,确保代码正确配置DAC输出。
阅读全文