本帖最后由 qjp1988113 于 2021-6-18 13:45 编辑
PIC18F16Q40带了8BIT的ADC,今天我们就来测试它。DAC的用途之一就是做成可调的直流电压。具体为DAC引脚输出,后面跟一级运放,就可以变成可调直流电压了,可以很好的节省成本。
今天我们不做直流电压,我们做一个正弦波发生器:
先配置,几乎没啥好配置的,配置好DAC,再使能一个引脚输出。
生成配置代码:
void DAC1_Initialize(void)
{
// OE DACOUT2 Enabled and DACOUT1 Disabled; DAC1EN enabled; NSS VSS; PSS VDD;
DAC1CON = 0xA0;
// DAC1R 154;
DAC1DATL = 0x9A;
}
void DAC1_SetOutput(uint8_t inputData)
{
DAC1DATL = inputData;
}
uint8_t DAC1_GetOutput(void)
{
return DAC1DATL;
}
不能再简单了。我们写一个电压转成DAC值的函数:
//电压转ADC值
#define Vref 3,3 //ADC 参考电压
#define resolution_dac 256 //DAC分辨率 BIT
float VOLTG2DACValue(float Voltg)
{
float tmp=0;
if (Voltg>5) return tmp;
//转换数据
tmp=resolution_dac*Voltg*1.0/Vref;
return tmp;
}
我们写一个正弦波数据发生函数:
uint8_t sin_tab[128];
//直接输入DAC数据
void getSinTab(uint8_t point,uint16_t maxnum)
{
uint8_t i=0;
float radian; //弧度
float angle; //角度 分度角
angle=360.000/point;//步进角
for(i=0;i<point;i++)
{
radian=angle*i;//得到角度值
radian=radian*0.01744;//角度转弧度 弧度=角度*(π/180)
sin_tab[i]=(maxnum/2)*sin(radian)+(maxnum/2);
}
}
//输入电压
void getSinTabFromVoltg(uint8_t point,float Voltg)
{
uint8_t i=0;
uint16_t maxnum; //DAC 值
float radian; //弧度
float angle; //角度 分度角
maxnum=VOLTG2DACValue(Voltg); //电压转成DAC值
angle=360.000/point; //步进角
for(i=0;i<point;i++)
{
radian=angle*i;//得到角度值
radian=radian*0.01744;//角度转弧度 弧度=角度*(π/180)
sin_tab[i]=(maxnum/2)*sin(radian)+(maxnum/2);
}
}
我们在main里面调用:
#define POINT 100
#define AM 1.0f
///////////////////////////////////
getSinTabFromVoltg(POINT, AM);
while(1)
{
for(i=0;i<POINT ;i++)
{
DAC1_SetOutput(sin_tab);
__nop();
// __delay_us(1);
}
}
编译下载,查看示波器:
但是就是不加延时,100个点一个周期 最大页就是1.6K以上。做波形发生器还是不行的。
目前只能用PWM脉冲,然后RC滤波产生正弦波,理论上可以做到500K~
好了,DAC就到这了~
|