已经解决 代码如下
#include "timer4.h"
#define TMR4_UNIT (CM_TMR4_1)
#define TMR4_PERIPH_CLK (FCG2_PERIPH_TMR4_1)
#define TMR4_EVT_CH (TMR4_EVT_CH_UH) //TMR4事件通道
void TMR4_init(void)
{
FCG_Fcg2PeriphClockCmd(TMR4_PERIPH_CLK,ENABLE); //使能TME4_1外围时钟
/************************* Configure TMR4 counter *************************/
stc_tmr4_init_t stcTmr4Init;
TMR4_StructInit(&stcTmr4Init);
stcTmr4Init.u16ClockSrc = TMR4_CLK_SRC_INTERNCLK; //TMR4计数器时钟源 PCLK1=100M
stcTmr4Init.u16ClockDiv = TMR4_CLK_DIV1024; //TMR4计数器时钟分频 1024分频
stcTmr4Init.u16CountMode = TMR4_MD_SAWTOOTH; //TMR4计数模式 锯齿波模式
stcTmr4Init.u16PeriodValue = 24; //PCLK1=100M 100000000/1024/2000/2=24 2000HZ采样频率 0.5ms
TMR4_Init(TMR4_UNIT, &stcTmr4Init);
/************************* Configure TMR4 event ***************************/
stc_tmr4_evt_init_t stcTmr4EventInit;
TMR4_EVT_StructInit(&stcTmr4EventInit);
stcTmr4EventInit.u16CompareValue = 24/2U; //50%占空比
stcTmr4EventInit.u16MatchCond = TMR4_EVT_MATCH_CNT_UP; //向上计数
stcTmr4EventInit.u16Mode = TMR4_EVT_MD_CMP; //MR4_EVT比较模式
stcTmr4EventInit.u16OutputEvent = TMR4_EVT_OUTPUT_EVT0; //TMR4输出事件为TMR4事件输出特殊事件0
TMR4_EVT_Init(TMR4_UNIT, TMR4_EVT_CH, &stcTmr4EventInit);
/* Start TMR4 count. */
TMR4_Start(TMR4_UNIT);
}
#include "adc.h"
#include "gpio.h"
#include "clock.h"
#include "timer4.h"
#define ADC_CLK_SEL (ADC_CLK_MPLL)
#define ADC_CLK (CLK_PERIPHCLK_PLLQ)
/* ADC unit instance for this example. */
#define ADC_UNIT (CM_ADC1) //ADC1基地址(起始地址)
#define ADC_PERIPH_CLK (FCG3_PERIPH_ADC1) //ADC1使能时钟
/* Selects ADC channels that needed. */
#define ADC_CHA (ADC_CH0) //选择ADC_CH0通道
#define ADC_CHA_PORT (GPIO_PORT_A) //对应PA0口
#define ADC_CHA_PIN (GPIO_PIN_00)
#define ADC_CHB (ADC_CH1) //选择ADC_CH1通道
#define ADC_CHB_PORT (GPIO_PORT_A) //对应PA1口
#define ADC_CHB_PIN (GPIO_PIN_01)
#define ADC_CHC (ADC_CH2) //选择ADC_CH2通道
#define ADC_CHC_PORT (GPIO_PORT_A) //对应PA2口
#define ADC_CHC_PIN (GPIO_PIN_02)
#define ADC_CHD (ADC_CH3) //选择ADC_CH3通道
#define ADC_CHD_PORT (GPIO_PORT_A) //对应PA3口
#define ADC_CHD_PIN (GPIO_PIN_03)
#define ADC_CHE (ADC_CH4) //选择ADC_CH4通道
#define ADC_CHE_PORT (GPIO_PORT_A) //对应PA4口
#define ADC_CHE_PIN (GPIO_PIN_04)
#define ADC_CHF (ADC_CH5) //选择ADC_CH5通道
#define ADC_CHF_PORT (GPIO_PORT_A) //对应PA5口
#define ADC_CHF_PIN (GPIO_PIN_05)
#define ADC_CHG (ADC_CH6) //选择ADC_CH6通道
#define ADC_CHG_PORT (GPIO_PORT_A) //对应PA6口
#define ADC_CHG_PIN (GPIO_PIN_06)
#define ADC_CHH (ADC_CH7) //选择ADC_CH7通道
#define ADC_CHH_PORT (GPIO_PORT_A) //对应PA7口
#define ADC_CHH_PIN (GPIO_PIN_07)
#define ADC_CHI (ADC_CH8) //选择ADC_CH8通道
#define ADC_CHI_PORT (GPIO_PORT_B) //对应PB0口
#define ADC_CHI_PIN (GPIO_PIN_00)
#define ADC_CHJ (ADC_CH9) //选择ADC_CH9通道
#define ADC_CHJ_PORT (GPIO_PORT_B) //对应PB1口
#define ADC_CHJ_PIN (GPIO_PIN_01)
#define ADC_CHK (ADC_CH10) //选择ADC_CH10通道
#define ADC_CHK_PORT (GPIO_PORT_C) //对应PC4口
#define ADC_CHK_PIN (GPIO_PIN_04)
//uint16_t m_u16AdcVal[11] = {0};
/* ADC sequence to be used. */
#define ADC_SEQ (ADC_SEQ_A) //使用ADC1的序列A
/* Hard trigger of the specified sequence. */
#define ADC_SEQ_HARDTRIG (ADC_HARDTRIG_EVT0) //硬件触发标志位-------TMR4触发 2k采样率
/* ADC trigger event source */
#define ADC_TRIG_SEL (AOS_ADC1_0)
#define ADC_EVT_SRC (EVT_SRC_TMR4_1_SCMP0)
void adc_init(void)
{
GPIO_init();
TMR4_init();
AdcClockConfig();
AdcInitConfig();
AdcTriggerConfig();
// ADC_IrqCallback();
ADC_Start(ADC_UNIT);
}
static void AdcClockConfig(void)
{
Clock_init();
CLK_SetPeriClockSrc(ADC_CLK);
}
static void AdcInitConfig(void)
{
FCG_Fcg3PeriphClockCmd(ADC_PERIPH_CLK, ENABLE);
stc_adc_init_t stcAdcInit;
(void)ADC_StructInit(&stcAdcInit);
stcAdcInit.u16ScanMode = ADC_MD_SEQA_CONT; //ADC1序列A序列A连续扫描
stcAdcInit.u16Resolution = ADC_RESOLUTION_12BIT; //ADC分辨率为12位
stcAdcInit.u16DataAlign = ADC_DATAALIGN_RIGHT; //转换数据右对齐
(void)ADC_Init(ADC_UNIT, &stcAdcInit);
//ADC通道引脚重映射
ADC_ResetChMapping(ADC_UNIT);
ADC_ChRemap(ADC_UNIT, ADC_CH10, ADC1_PIN_PC4); //将PC4重映射为ADC通道10(原为通道14)
//使能ADC通道
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHA, ENABLE);
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHB, ENABLE);
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHC, ENABLE);
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHD, ENABLE);
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHE, ENABLE);
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHF, ENABLE);
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHG, ENABLE);
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHH, ENABLE);
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHI, ENABLE);
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHJ, ENABLE);
ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_CHK, ENABLE);
//设置采样时间
ADC_SetSampleTime(ADC_UNIT, ADC_CHA, 240U);
ADC_SetSampleTime(ADC_UNIT, ADC_CHB, 240U);
ADC_SetSampleTime(ADC_UNIT, ADC_CHC, 240U);
ADC_SetSampleTime(ADC_UNIT, ADC_CHD, 240U);
ADC_SetSampleTime(ADC_UNIT, ADC_CHE, 240U);
ADC_SetSampleTime(ADC_UNIT, ADC_CHF, 240U);
ADC_SetSampleTime(ADC_UNIT, ADC_CHG, 240U);
ADC_SetSampleTime(ADC_UNIT, ADC_CHH, 240U);
ADC_SetSampleTime(ADC_UNIT, ADC_CHI, 240U);
ADC_SetSampleTime(ADC_UNIT, ADC_CHJ, 240U);
ADC_SetSampleTime(ADC_UNIT, ADC_CHK, 240U);
//设置扫描平均计算
ADC_ConvDataAverageConfig(ADC_UNIT, ADC_AVG_CNT32);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHA, ENABLE);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHB, ENABLE);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHC, ENABLE);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHD, ENABLE);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHE, ENABLE);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHF, ENABLE);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHG, ENABLE);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHH, ENABLE);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHI, ENABLE);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHJ, ENABLE);
ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_CHK, ENABLE);
}
//ADC触发源设置
static void AdcTriggerConfig(void)
{
FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE); //使能AOS外围时钟
ADC_TriggerConfig(ADC_UNIT, ADC_SEQ, ADC_HARDTRIG_EVT0); //ADC触发设置 内部事件0触发
AOS_SetTriggerEventSrc(ADC_TRIG_SEL, ADC_EVT_SRC); //ADC1_0的触发源为Timer4_1_SCMP0
ADC_TriggerCmd(ADC_UNIT, ADC_SEQ, ENABLE);
}
#include "dma.h"
#define ADC_UNIT (CM_ADC1) //ADC1基地址(起始地址)
#define ADC_DR_START ((uint32_t)&ADC_UNIT->DR0) //DMA数据源地址
#define DMA_UNIT (CM_DMA1) //DMA1基地址
#define DMA_PERIPH_CLK (FCG0_PERIPH_DMA1) //DMA1使能时钟
#define DMA_CH (DMA_CH0) //通道0地址
#define DMA_AOS_TRIG_SEL (AOS_DMA1_0) //外设电路之间的联动(AOS自动运行系统)
#define DMA_TRANS_CNT (0U) //设置DMA传输次数,0表示传输无限次(传输次数要大于0)
#define DMA_BLOCK_SIZE (11U) //设置DMA数据块大小
#define DMA_DATA_WIDTH (DMA_DATAWIDTH_16BIT) //设置数据宽度,也决定了源地址和目的地址增加或者减少多少
#define DMA_SRC_ADDR ADC_DR_START //DMA数据源地址
#define DMA_DEST_ADDR ((uint32_t)&ad_value) //DMA数据目的地址
#define DMA_TRIG_EVT (EVT_SRC_ADC1_EOCA) //选择AOS触发源 ADC1序列A转换完成事件
#define DMA_INT_TYPE (DMA_INT_BTC_CH0) //选择DMA中断类型为:数据块传输完成中断
#define DMA_INT_SRC (INT_SRC_DMA1_BTC0) //选择DMA中断类型为:数据块传输完成
#define DMA_INT_IRQn (INT028_IRQn) //DMA中断序号为028
#define DMA_INT_PRIO (DDL_IRQ_PRIO_03) //DMA中断优先级为03(根据自己需要设定)
#define DMA_INT_FLAG (DMA_FLAG_BTC_CH0) //DMA数据块传输完成中断标志位
uint16_t ad_value[11]={0}; //定义一个数组,用来存放11个ADC通道转换结果,也是DMA的目标地址
uint16_t adc_data[11]={0}; //定义一个数组,用来存放11个ADC通道转换电压值结果
//static __IO en_flag_status_t m_enAcquisition; //采集标志位
//DMA配置
void DMA_init(void)
{
FCG_Fcg0PeriphClockCmd(DMA_PERIPH_CLK, ENABLE); //使能DMA外围时钟
DMA_DeInit(DMA_UNIT, DMA_CH); //复位DMA1通道0
DMA_Cmd(DMA_UNIT, ENABLE);
//DMA基本配置
stc_dma_init_t stcDmaInit;
DMA_StructInit(&stcDmaInit);
stcDmaInit.u32IntEn = DMA_INT_ENABLE; //开启DMA中断
stcDmaInit.u32SrcAddr = DMA_SRC_ADDR; //DMA源地址
stcDmaInit.u32DestAddr = DMA_DEST_ADDR; //DMA目的地址
stcDmaInit.u32DataWidth = DMA_DATA_WIDTH; //DMA传输数据宽度16位
stcDmaInit.u32BlockSize = DMA_BLOCK_SIZE; //DMA数据块大小
stcDmaInit.u32TransCount = DMA_TRANS_CNT; //DMA传输计数
stcDmaInit.u32SrcAddrInc = DMA_SRC_ADDR_INC; //DMA源地址增量方式 递增
stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC; //DMA目的地址增量方式 递增
DMA_Init(DMA_UNIT, DMA_CH, &stcDmaInit);
DMA_ChCmd(DMA_UNIT, DMA_CH, ENABLE);
//DMA重复模式配置
stc_dma_repeat_init_t stcDmaRptInit;
DMA_RepeatStructInit(&stcDmaRptInit);
stcDmaRptInit.u32Mode = DMA_RPT_BOTH; //DMA重复模式 DMA源和目标重复启用
stcDmaRptInit.u32SrcCount = DMA_BLOCK_SIZE; //DMA源重复大小=DMA数据块大小
stcDmaRptInit.u32DestCount = DMA_BLOCK_SIZE; //DMA目的重复大小=DMA数据块大小
DMA_RepeatInit(DMA_UNIT, DMA_CH, &stcDmaRptInit);
//设置DMA触发源
FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
AOS_SetTriggerEventSrc(DMA_AOS_TRIG_SEL, DMA_TRIG_EVT); //ADC转换完成->DMA传输数据
//DMA中断处理函数
DmaIrqConfig();
DMA_IrqCallback();
}
//DMA中断函数设置
static void DmaIrqConfig(void)
{
stc_irq_signin_config_t stcIrqSignConfig;
stcIrqSignConfig.enIntSrc = DMA_INT_SRC;
stcIrqSignConfig.enIRQn = DMA_INT_IRQn;
stcIrqSignConfig.pfnCallback = &DMA_IrqCallback;
(void)INTC_IrqSignIn(&stcIrqSignConfig);
DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG);
//中断控制设置
NVIC_ClearPendingIRQ(DMA_INT_IRQn);
NVIC_SetPriority(DMA_INT_IRQn, DMA_INT_PRIO);
NVIC_EnableIRQ(DMA_INT_IRQn);
}
//DMA中断回调函数
static void DMA_IrqCallback(void)
{
if(SET == DMA_GetTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG)){
DMA_Cmd(DMA_UNIT, DISABLE);
adc_data[0] = (ad_value[0]*63/100) + (ad_value[0]*75/1001) + 26; //PA0 ADC0还原后的电压值
adc_data[1] = (ad_value[1]*31/20) + (ad_value[1]*75/394) - 3225; //PA1 ADC1还原后的电压值
adc_data[2] = -(ad_value[2]*31/20) - (ad_value[2]*75/394) + 3246; //PA2 ADC2还原后的电压值
adc_data[3] = (ad_value[3]*31/20) + (ad_value[3]*75/394) - 3214; //PA3 ADC3还原后的电压值
adc_data[4] = (ad_value[4]*3.3)/4096; //PA4 ADC4的电压值
adc_data[5] = -(ad_value[5]*31/20) - (ad_value[5]*75/394) + 3222; //PA5 ADC5还原后的电压值
adc_data[6] = (ad_value[6]*31/20) + (ad_value[6]*75/394) - 3240; //PA6 ADC6还原后的电压值
adc_data[7] = (ad_value[7]*3.3)/4096; //PA7 ADC7的电压值
adc_data[8] = -(ad_value[8]*29/20) - (ad_value[8]*75/391) + 3047; //PB0 ADC8还原后的电压值
adc_data[9] = (ad_value[9]*29/20) + (ad_value[9]*75/391) - 3041; //PB1 ADC9还原后的电压值
adc_data[10] = (ad_value[10]*3.3)/4096; //PC4 ADC14的电压值
DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG);
DMA_Cmd(DMA_UNIT, ENABLE);
}
}
|