我使用了8个通道的ADC,2个通道的DA
DA使用简单的程序控制发送方式,发送值递增,AD采用连续采样DMA传送方式,获得了成功
液晶连续的显示正确的数值
所有程序在BrightPoint开发板上运行成功,这块屏拿来拿去的打烂了不过还能用哈哈!
http://s10/middle/9cc48191xc7b86b41b649&690
测试方法:DA1连AD1,DA2连AD2 12位AD,精度3.3/4095=8×0.0001,我需要小数点后2位,足够精确
网上部分代码计算公式用 4096是错误的,因为3.3V的时候对应的是4095(12位能表示的最大的数)
函数代码:
void BP_ADC_INIT(void)
{
ADC_InitTypeDef
ADC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 ,
ENABLE ); //使能ADC1通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6);
//72M/6=12,ADC最大时间不能超过14M
//PC 0/ 1/
2/ 3/ 4/ 5 pb0 1 作为模拟通道输入引脚
//adc 10 11 12 13 14
15 8
9
GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOC,
&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOB,
&GPIO_InitStructure);
ADC_DeInit(ADC1); //将外设 ADC1
的全部寄存器重设为缺省值
ADC_InitStructure.ADC_Mode =
ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
//ENABLE 模数转换工作在扫描模式
//DISABLE
模数转换工作在单次模式
ADC_InitStructure.ADC_ContinuousConvMode =
ENABLE; //ENABLE 模数转换工作在连续转换模式
//DISABLE 模数转换工作在单次转换模式ENABLE
ADC_InitStructure.ADC_ExternalTrigConv =
ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign =
ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel =
ADC_CHANALS; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1,
&ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
//设置指定ADC的规则组通道,设置它们的转化顺序和采样时间
//ADC1,ADC通道x,规则采样顺序值为y,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1,
ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2,
ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 3,
ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 4,
ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 5,
ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 6,
ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 7,
ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 8,
ADC_SampleTime_239Cycles5 );
// 开启ADC的DMA支持(要实现DMA功能,还需独立配置DMA通道等参数)
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1,
ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //重置指定的ADC1的校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1)); //获取ADC1重置校准寄存器的状态,设置状态则等待
ADC_StartCalibration(ADC1); //开始指定ADC1的校准状态
while(ADC_GetCalibrationStatus(ADC1)); //获取指定ADC1的校准程序,设置状态则等待
//ADC_SoftwareStartConvCmd(ADC1,
ENABLE); //使能指定的ADC1的软件转换启动功能
}
float AD_GetVolt(u16
advalue)
{
return (float)(advalue * 3.30
/ 4095);
}
void AD_filter(void)
{
int sum =
0;
u8
count,i;
for(i=0;i<ADC_CHANALS;i++)
{
for ( count=0;count<ADC_TIMES;count++)
{
sum += AD_Value[count][i];
}
After_filter[i]=sum/ADC_TIMES;
sum=0;
}
}
void BP_DAC_Init(void)
{
DAC_InitTypeDef DAC_InitStructure;
DAC_DeInit();
GPIO_InitStructure.GPIO_Pin
= GPIO_Pin_4 | GPIO_Pin_5|GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed =
GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode =
GPIO_Mode_Out_PP;
GPIO_Init(GPIOA,
&GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC,
ENABLE);
DAC_Cmd(DAC_Channel_1,ENABLE); //
DAC_Cmd(DAC_Channel_2, ENABLE);
DAC_InitStructure.DAC_Trigger =
DAC_Trigger_None;
DAC_InitStructure.DAC_WaveGeneration
= DAC_WaveGeneration_None;
DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude=DAC_TriangleAmplitude_4095;
DAC_InitStructure.DAC_OutputBuffer
= DAC_OutputBuffer_Disable;
DAC_Init(DAC_Channel_1,
&DAC_InitStructure);
DAC_Init(DAC_Channel_2,
&DAC_InitStructure);
}
void BP_DMA_Init(void)
{
DMA_InitTypeDef
DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,
ENABLE);//使能DMA传输
DMA_DeInit(DMA1_Channel1);
//将DMA的通道1寄存器重设为缺省值
DMA_InitStructure.DMA_PeripheralBaseAddr
=
(u32)&ADC1->DR;
//DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr =
(u32)&AD_Value; //DMA内存基地址
DMA_InitStructure.DMA_DIR =
DMA_DIR_PeripheralSRC; //内存作为数据传输的目的地
DMA_InitStructure.DMA_BufferSize =
ADC_TIMES*ADC_CHANALS; //DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_PeripheralInc =
DMA_PeripheralInc_Disable; //外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc =
DMA_MemoryInc_Enable; //内存地址寄存器递增
DMA_InitStructure.DMA_PeripheralDataSize =
DMA_PeripheralDataSize_HalfWord; //数据宽度为16位
DMA_InitStructure.DMA_MemoryDataSize =
DMA_MemoryDataSize_HalfWord; //数据宽度为16位
DMA_InitStructure.DMA_Mode =
DMA_Mode_Circular; //工作在循环缓存模式
DMA_InitStructure.DMA_Priority =
DMA_Priority_High; //DMA通道 x拥有高优先级
DMA_InitStructure.DMA_M2M =
DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(DMA1_Channel1,
&DMA_InitStructure);
//根据DMA_InitStruct中指定的参数初始化DMA的通道
}
主程序部分代码:
if (ADC_SUPPORT)
{
BP_ADC_INIT();
BP_DAC_Init();
BP_DMA_Init();
DMA_Cmd(DMA1_Channel1,
ENABLE); //启动DMA通道
daout1=0;
daout2=0;
DAC_SetDualChannelData(DAC_Align_12b_R,daout1,daout2);
DAC_DualSoftwareTriggerCmd(ENABLE);//
ADC_SoftwareStartConvCmd(ADC1,
ENABLE);
while(1)
//for 连续
{
DAC_SetDualChannelData(DAC_Align_12b_R,daout1+=1,daout2+=12);
DAC_DualSoftwareTriggerCmd(ENABLE);//
//while(DAC_GetFlagStatus(, uint32_t DAC_FLAG)
if (daout1>4095)
daout1=daout2=0;
// while(ADC_GetSoftwareStartConvStatus(ADC1)==RESET);
//while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//等待传输完成否则第一位数据容易丢失
ADC_SoftwareStartConvCmd(ADC1, DISABLE);
AD_filter();
//
value[0]=AD_GetVolt(After_filter[0]) ;
for(i=0;i<ADC_CHANALS;i++)
{
value[i]=
AD_GetVolt(After_filter[i]);
//if (i<2)
//printf("value[%d]:\t%d.%dv\n",i,value[i]/100,value[i]0)
;
delay_ms(10);
}
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
if
(LCD_SUPPORT) LcdClear(WHITE);
if (LCD_SUPPORT) LcdPrintf(35,200,RED,WHITE,"v[0]:%d %4.2fv v[1]:%d
%4.2fv",daout1,value[0],daout2,value[1]);
//Delay100ms(50);
}
效果非常好,程序已经验证!
加载中,请稍候......