单片机型号:STC15F2K60S2
目录
文章附上工程下载地址:
在进行ADC与DAC测试时发现了如下冲突:
实验问题发现:
解决方案:
文章附上工程下载地址:
https://download.csdn.net/download/qq_64257614/87854725?spm=1001.2014.3001.5503
在进行ADC与DAC测试时发现了如下冲突:
ADC与DAC都运行,即使安排了不同的开启时间,但DAC输出电压有明显抖动。
实验问题发现:
如下代码写了PCF8591芯片在不同时间段开启 ADC与DAC
ADC采集电位器的模拟值,
DAC是将一个变量value(大小在0~100之间)做转化,
(0输出0V,100输出5V,一次函数关系作输出)
然后转化为电压输出.
按键S4 S5分别可对value进行加减操作
u8 nr1,nr2,nr3,nr4,nr5,nr6,nr7,nr8;float read_ADC; //浮点ADC读取
u16 ADC_value; //ADC读取变量
u8 DAC_value; //DAC输出变量
u8 value;u8 DAC_cnt;
u16 ADC_cnt;
bit DAC_flag;
bit ADC_flag;bit key_flag = 0;
u8 key_value;
u8 key_cnt;void main()
{inint();while(1){if(key_flag==1) //按键S4 S5改变value 大小{key_flag=0;key_value=key_scan_return();switch(key_value) {case 4:value++;break;case 5:value--;break;}}if(ADC_flag==1) //ADC采样{ADC_flag=0;read_ADC=ADC_pcf8591(0x03);ADC_value=(unsigned int)read_ADC*100;}if(DAC_flag==1) //DAC输出{DAC_flag=0;DAC_value=value * 255 /100 ;dac_pcf8591(DAC_value);}}
}void inint()
{cls_buzz_led();inint_smg();Timer0Init();
}void Timer0Init(void) //1毫秒@12.000MHz
{AUXR &= 0x7F; //定时器时钟12T模式TMOD &= 0x01; TL0 = 0x18; TH0 = 0xFC; TF0 = 0; TR0 = 1; EA=1;ET0=1;
}void Timer0_server() interrupt 1
{u8 i;if(++i==8) {i=0;nr1=value/100%10;nr2=value/10%10;nr3=value%10;nr4=17;nr5=17;nr6=17;nr7=17;nr8=17;smg_display(nr1,nr2,nr3,nr4,nr5,nr6,nr7,nr8);}if(++key_cnt==16) {key_cnt=0;key_flag=1;}if(++DAC_cnt==166) {DAC_cnt=0;DAC_flag=1;}if(++ADC_cnt==450) {ADC_cnt=0;ADC_flag=1;}
}
从中我们发现,即使我们将DAC定位166ms一次转化输出
ADC为450ms一次转化输出,但下载后发现,
DAC的电压输出依旧收到了干扰:
为证明确实是ADC与DAC相互作用的冲突,我注释掉了ADC采样的代码
在此编译下载进了开发板,发现DAC输出变得正常了,十分稳定:
在此后的实验中发现,不论是将ADC采样延长,
还是设定标志位,让一个读取完了再开启另一个,都没有成效。
但有一点可以确定的是,ADC与DAC的使用,确实是需要在不同时间段进行的。
解决方案:
在CT107D单片机上,PCF8591三个硬件引脚地址均接地,两路模拟信号均为单端输入,则有:
光敏传感器接在AIN1即通道1,控制寄存器应该写入0x01;
电位器Rb2接到AIN3即通道3,控制寄存器应该写入0x03。
以上为ADC单独使能用的地址,
照常理来说,我们调用ADC函数时,只需将参数 channel 填为0x01 或 0x03即可:
但我在查阅网上资料后,发现在ADC采样同时,也能使能DAC的地址,
就比如我想读取电位器的0x03的ADC采样值,我把这个地址写成0x43
(即将channel改填为0x43)
这样就能既不影响ADC采样,DAC输出也变得稳定许多:
//ADC读取unsigned char ADC_pcf8591(unsigned char channel)
{unsigned char ad_value,i;for(i=0;i<2;i++){I2CStart();I2CSendByte(0X90);I2CWaitAck();I2CSendByte(channel);I2CWaitAck();I2CStart();I2CSendByte(0X91);I2CWaitAck();ad_value=I2CReceiveByte();I2CSendAck(1); //官方驱动少这句I2CStop();}return ad_value;
}
DAC输出函数地址就是固定的0x40:
void dac_pcf8591(unsigned char dat) //DAC输出 dat - 输入进行数模转换的数据
{IIC_Start();IIC_SendByte(0x90);IIC_WaitAck();IIC_SendByte(0x40); //DAC输出模式IIC_WaitAck();IIC_SendByte(dat);IIC_WaitAck();IIC_Stop();
}
如此改动之后,我们发现DAC输出变得稳定,在串口测试ADC等数据也十分正常:
这样我们的问题就解决了,觉得有用就三连!