初级会员

- 积分
- 85
- 金钱
- 85
- 注册时间
- 2019-3-15
- 在线时间
- 18 小时
|
1金钱
#define PHASE_A_ADC_CHANNEL ADC_Channel_11
#define PHASE_A_GPIO_PORT GPIOC
#define PHASE_A_GPIO_PIN GPIO_Pin_1
#define PHASE_B_ADC_CHANNEL ADC_Channel_10
#define PHASE_B_GPIO_PORT GPIOC
#define PHASE_B_GPIO_PIN GPIO_Pin_0
#define TEMP_FDBK_CHANNEL ADC_Channel_13
#define TEMP_FDBK_CHANNEL_GPIO_PORT GPIOC
#define TEMP_FDBK_CHANNEL_GPIO_PIN GPIO_Pin_3
#define BUS_VOLT_FDBK_CHANNEL ADC_Channel_14
#define BUS_VOLT_FDBK_CHANNEL_GPIO_PORT GPIOC
#define BUS_VOLT_FDBK_CHANNEL_GPIO_PIN GPIO_Pin_4
#define ADC1_DR_Address ((uint32_t)0x4001244C) //ADC数据寄存器地址
#define BufferLenght 2
volatile u32 ADC_DualConvertedValueTab[BufferLenght];
volatile u16 ADC1_RegularConvertedValueTab[BufferLenght];
volatile u16 ADC2_RegularConvertedValueTab[BufferLenght];
u16 h_ADCBusvolt;
u16 h_ADCTemp;
u16 h_ADCPhase_A;
u16 h_ADCPhase_B;
/*
* 函数名:ADC_GPIO_Init
* 描述:使能ADC1,ADC2和DMA1的时钟,初始化GPIO口
* 输入:无
* 输出:无
* 调用:内部调用
*/
void ADC_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable DMA clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //DMA1
/* Enable ADC1,ADC2,GPIOA,GPIOB,GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC, ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PHASE_A_GPIO_PIN;//adc_channel11 PC1
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(PHASE_A_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = PHASE_B_GPIO_PIN;//adc_channel10 PC0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(PHASE_B_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = TEMP_FDBK_CHANNEL_GPIO_PIN;//adc_channel13 PC3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(TEMP_FDBK_CHANNEL_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = BUS_VOLT_FDBK_CHANNEL_GPIO_PIN;//adc_channel14 PC4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(BUS_VOLT_FDBK_CHANNEL_GPIO_PORT, &GPIO_InitStructure);
}
/*
* 函数名:ADC_DMA_Init
* 描述:配置ADC1的工作模式为DMA模式
* 输入:无
* 输出:无
* 调用:内部调用
*/
void ADC_DMA_Init(void)
{
// u8 bIndex;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //ADCCLK = PCLK2/6=72M/6=12MHz,ADC最大频率不能超过14MHz
//设置DMA1,用于自动存储ADC1和ADC2规则通道的转换值
DMA_DeInit(DMA1_Channel1);
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //ADC数据寄存器地址(源地址)
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DualConvertedValueTab; //转换值存储地址(目标地址)
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //从外设到内存
DMA_InitStructure.DMA_BufferSize = BufferLenght; //传输大小
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //外设数据单位(每次传输32位)
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //内存数据单位(每次传输32位)
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //本DMA通道优先级(用了多个通道时,本参数才有效果)
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //没有使用内存到内存的传输
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
DMA_ClearITPendingBit(DMA1_IT_TC1); //清除通道1传输完成中断
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); //打开通道1传输完成中断
DMA_Cmd(DMA1_Channel1, ENABLE); //使能DMA1
/****使用双ADC模式,ADC1为主,ADC2为从。当ADC转换配置成由外部事件触发时,用户必须设置成仅触发主ADC,从ADC设置成软件触发,这样可以防止意外的触发从转换。
但是,主和从ADC的外部触发必须同时被激活,要调用 ADC_ExternalTrigConvCmd(ADC2, ENABLE);//ADC2外部触发使能****/
ADC_DeInit(ADC1);
ADC_DeInit(ADC2);
ADC_StructInit(&ADC_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; //ADC1工作在注入模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //轮流采集各个通道的值
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换模式,触发后就会一直转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换触发信号选择,使用一个软件信号触发ADC1
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left; //数据左对齐,ADC是12位,要存到DR寄存器的高16位或低16位,就有左右对齐问题,决定了高4位无效或低4位无效
ADC_InitStructure.ADC_NbrOfChannel = 2; //要进行ADC转换的通道数:PHASE_A_ADC_CHANNEL,BUS_VOLT_FDBK_CHANNEL
ADC_Init(ADC1, &ADC_InitStructure);
ADC_DMACmd(ADC1, ENABLE); //使能ADC1的DMA
ADC_StructInit(&ADC_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; //ADC2工作在注入模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换模式,触发后就会一直转换
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换触发信号选择,由软件给信号触发,双ADC模式的从ADC必须设置为软件触发
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;
ADC_InitStructure.ADC_NbrOfChannel = 2; //要进行ADC转换的通道数:PHASE_B_ADC_CHANNEL,TEMP_FDBK_CHANNEL
ADC_Init(ADC2, &ADC_InitStructure);
ADC_ExternalTrigConvCmd(ADC2, ENABLE); //ADC2外部触发使能,双ADC模式的从ADC必须要用这条语句
ADC_RegularChannelConfig(ADC1, PHASE_A_ADC_CHANNEL, 1, ADC_SampleTime_55Cycles5); //A相电流
ADC_RegularChannelConfig(ADC1, BUS_VOLT_FDBK_CHANNEL, 2, ADC_SampleTime_55Cycles5); //母线电压
ADC_RegularChannelConfig(ADC2, PHASE_B_ADC_CHANNEL, 1, ADC_SampleTime_55Cycles5); //B相电流
ADC_RegularChannelConfig(ADC2, TEMP_FDBK_CHANNEL, 2, ADC_SampleTime_55Cycles5); //温度电压
ADC_Cmd(ADC1, ENABLE); //ADC1使能
ADC_TempSensorVrefintCmd(ENABLE); //开启MCU内存温度传感器及Vref通道
ADC_ResetCalibration(ADC1); //复位校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1)); //等待校准寄存器复位完成
ADC_StartCalibration(ADC1); //ADC1开始校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准完成
ADC_Cmd(ADC2, ENABLE); //ADC2使能
ADC_ResetCalibration(ADC2); //复位校准寄存器
while(ADC_GetResetCalibrationStatus(ADC2)); //等待校准寄存器复位完成
ADC_StartCalibration(ADC2); //ADC2开始校准
while(ADC_GetCalibrationStatus(ADC2)); //等待校准完成
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //给主ADC一个软件触发信号,之后ADC就会一直转换下去
}
/*
* 函数名:ADC_DMA_Init
* 描述:配置ADC1的工作模式为DMA模式
* 输入:无
* 输出:无
* 调用:内部调用
*/
void ADC1_Init(void)
{
ADC_GPIO_Init();
ADC_DMA_Init();
}
void DMA1_Channel1_IRQHandler(void)
{
u8 i,j=0;
if(DMA_GetITStatus(DMA1_IT_TC1))
{
DMA_ClearITPendingBit(DMA1_IT_GL1); //清除DMA通道1传输完成中断
for(i=0;i<BufferLenght;i++)
{
ADC1_RegularConvertedValueTab[j++] = (uint16_t)(ADC_DualConvertedValueTab[i]>>4); //ADC1规则组左对齐,要右移4位
}
j = 0;
for(i=0;i<BufferLenght;i++)
{
ADC2_RegularConvertedValueTab[j++] = (uint16_t)(ADC_DualConvertedValueTab[i] >> 20);//ADC2规则组左对齐,要右移20位
}
}
}
|
|