使用STM32-C语言生成正弦信号数据表并通过DAC输出
1、在VC编写正弦数据生成正弦信号数据:角度从0到2π,即0到6.28,一个周期生成1024个数据点,数据点放大1600倍(正弦值最大值为1、最小值-1,所以要放大,嵌入式系统的DAC为12位(4096),最大可达3.3V,确保信号不失真,此处放大1600*2倍小于4096倍(dac没有负数值,需要转正数))。
#include <stdio.h>
#include <math.h>
int main(void)
{
int i;
char excle_tab = 0x9;//excle表格table键值
short val;//用于<=16位 dac,24、32位改int
FILE *fd = fopen("E:/sin_table.txt","wb+");
float angle = 0;
int cycle_cnt = 1024;//1个sin周期需要生成多少个数据
float angle_step = (float)6.28 / cycle_cnt;//6.28为2π
if(fd){
for(angle = 0;angle <= 6.28;angle += angle_step){//0到2π
//放大4096/2倍-12it-dac,防止失真可以小一些如1600
//因为正弦从-1到1,间距值为2
val = (float)sin(angle)*1600;
fprintf(fd,"%6f",angle);
fwrite(&excle_tab,1,1,fd);
fprintf(fd,"%d\r\n",val);
}
fclose(fd);
printf("fwrite ok\n");
}
}
得到数据在e盘目录下的sin_table.txt:
把数据复制放到excel表格,生成图表验证
2、把带有负数的正弦值转正数
#include <stdio.h>
#include <math.h>
int main(void)
{
int i;
char excle_tab = 0x9;//excle表格table键值
short val;//用于<=16位 dac,24、32位改int
FILE *fd = fopen("E:/sin_table.txt","wb+");
float angle = 0;
int cycle_cnt = 1024;//1个sin周期需要生成多少个数据
float angle_step = (float)6.28 / cycle_cnt;//6.28为2π
if(fd){
for(angle = 0;angle <= 6.28;angle += angle_step){//0到2π
//放大4096/2倍-12it-dac,防止失真可以小一些如1600
//因为正弦从-1到1,间距值为2
val = ((float)sin(angle) + 1)*1600;//把到负数的转正数
fprintf(fd,"%6f",angle);
fwrite(&excle_tab,1,1,fd);
fprintf(fd,"%d\r\n",val);
}
fclose(fd);
printf("fwrite ok\n");
}
}
生成全正数对比验证数据正确性
3、生成C十六进制数据、PCM-s16le的正数格式PCM数据使用在STM32-DAC:文件在E:/sin_table.txt,E:/sin_pcm.pcm。把sin_table.txt数据复制到STM32进行DAC输出正弦信号。
#include <stdio.h>
#include <math.h>
int main(void)
{
int i = 0;
char excle_tab = 0x9;//excle表格table键值
short val;//用于<=16位 dac,24、32位改int
FILE *fd = fopen("E:/sin_table.txt","wb+");
FILE *fd1 = fopen("E:/sin_pcm.pcm","wb+");
float angle = 0;
int cycle_cnt = 1024;//1个sin周期需要生成多少个数据
float angle_step = (float)6.28 / cycle_cnt;//6.28为2π
if(fd && fd1){
for(angle = 0;angle <= 6.28;angle += angle_step){//0到2π
//放大4096/2倍-12it-dac,防止失真可以小一些如1600
//因为正弦从-1到1,间距值为2
val = ((float)sin(angle) + 1)*1600;//把到负数的转正数
if(++i % 16 == 0){
fprintf(fd,"\r\n");
}
fprintf(fd,"0x%04X ",val);//生成C数组的十六进制值
fwrite(&val,1,2,fd1);//生成PCM文件二进制文件
}
fclose(fd);
fclose(fd1);
printf("fwrite ok\n");
}
}
5、生成C十六进制数据、PCM-s16le的正负数格式PCM数据使用在STM32-DAC:文件在E:/sin_table.txt,E:/sin_pcm.pcm。把sin_pcm.pcm数据复制到STM32进行IIS-PCM5102输出正弦信号。
#include <stdio.h>
#include <math.h>
int main(void)
{
int i = 0;
char excle_tab = 0x9;//excle表格table键值
short val;//用于<=16位 dac,24、32位改int
FILE *fd = fopen("E:/sin_table.txt","wb+");
FILE *fd1 = fopen("E:/sin_pcm.pcm","wb+");
float angle = 0;
int cycle_cnt = 1024;//1个sin周期需要生成多少个数据
short cycle_buf[1024];
short *cycle_val = cycle_buf;
float angle_step = (float)6.28 / cycle_cnt;//6.28为2π
if(fd && fd1){
for(angle = 0;angle <= 6.28;angle += angle_step){//0到2π
//放大4096/2倍-12it-dac,防止失真可以小一些如1600
//因为正弦从-1到1,间距值为2
val = ((float)sin(angle))*10000;//正负数的正弦值
*cycle_val++ = val;
if(++i % 16 == 0){
fprintf(fd,"\r\n");
}
fprintf(fd,"0x%04X ",val);//生成C数组的十六进制值
fwrite(&val,1,2,fd1);//生成PCM文件二进制文件
}
for(i = 0; i < 10*1024*1024; i += 1024*2){//写10M的PCM数据
fwrite(cycle_buf,1,sizeof(cycle_buf),fd1);//生成PCM文件二进制文件
}
fclose(fd);
fclose(fd1);
printf("fwrite ok\n");
}
}
作者:在别处生活