一、智芯Z20K11xM TDG、ADC架构
1.TDG
特性
- 一个软件触发源;一个硬件触发源(6个通道共用)
- 共6个通道,每个通道支持设置8个延时触发点
- 每个通道均支持一路出发信号输出以及中断信号输出
架构
计数模式:TDG_CTRL1.CNTMOD
- 0:单次循环计数
- 1:无线循环计数
清零方式:TDG_CTRL1.CLRMOD
- 0:当计数达到重载值清零
- 1:当计数达到通道延时点总和清零
通道配置更新方式:TDG_CTRL1.UPMOD
- 00:单通道配置完成立即更新
- 01:当计数达到重装载值是更新通道配置
- 11:当所有通道完成延时输出更新通道配置
寄存器
2.ADC
特性
- 最高12bit SAR逐次逼近式adc,可配置8bit、10bit、12bit精度
- 3对差分模拟输入and18路单端外部模拟输入
- 单次or连续转换模式
- 可配置自动比较中断(大于小于等于在范围不在范围编程值)
- 深度16FIFO
- 支持软件触发
- 支持6路输入触发(loop or Map)
- 输入电压不可超过VDDA
- 可配置硬件转换均值滤波
架构
TDG触发:
- LOOP模式:使用一个触发源循环采集CMDbuffer里配置的adc通道
- Map模式:一个触发源对应一个CMDbuffer里的adc通道(两个触发源应至少间隔adc转换时间以上进行触发否则err)
寄存器
二、配置示例
void Init_ADC(void)
{
/**********************************************配置ADC引脚***********************************************************/
PORT_PinmuxConfig(PORT_C, GPIO_14, PTC14_ADC0_CH12);
PORT_PinmuxConfig(PORT_B, GPIO_3, PTB3_ADC0_CH7);
PORT_PinmuxConfig(PORT_B, GPIO_1, PTB1_ADC0_CH5);
PORT_PinmuxConfig(PORT_C, GPIO_2, PTC2_ADC0_CH10);
PORT_PinmuxConfig(PORT_C, GPIO_1, PTC1_ADC0_CH9);
PORT_PinmuxConfig(PORT_C, GPIO_0, PTC0_ADC0_CH8);
PORT_PinmuxConfig(PORT_C, GPIO_17, PTC17_ADC0_CH15);
PORT_PinmuxConfig(PORT_C, GPIO_16, PTC16_ADC0_CH14);
PORT_PinmuxConfig(PORT_C, GPIO_15, PTC15_ADC0_CH13);
PORT_PinmuxConfig(PORT_C, GPIO_3, PTC3_ADC0_CH11);
PORT_PinmuxConfig(PORT_A, GPIO_0, PTA0_ADC0_CH0);
PORT_PinmuxConfig(PORT_A, GPIO_1, PTA1_ADC0_CH1);
PORT_PinmuxConfig(PORT_A, GPIO_7, PTA7_ADC0_CH3);
PORT_PinmuxConfig(PORT_B, GPIO_0, PTB0_ADC0_CH4);
PORT_PinmuxConfig(PORT_A, GPIO_6, PTA6_ADC0_CH2);
/**********************************************Adc相关配置***********************************************************/
/*配置tdg——adc触发映射关系*/
ADC_TDGTriggerConfig_t adcTriggerConfig0 =
{
ADC_LOOP_MODE, /* Loop mode Selected */
ADC_P_CH13, /* CMD0: channel 0; */
ADC_P_CH8, /* CMD1: channel 1; */
ADC_P_CH11, /* CMD2: channel 2; */
ADC_P_CH10, /* CMD3: channel 3; */
ADC_P_CH1, /* CMD4: channel 4; */
ADC_P_CH5, /* CMD5: channel 5; */
};
ADC_Config_t subcaseAdcCfg=
{
ADC_RESOLUTION_12BIT, /* ADC 12-bit resolution */
ADC_VREF_EXTERNAL, /* EXTERNAL Vref_H to 5V, Vref_L to 0V reference */
ADC_TDG_TRIGGER, /* TDG trigger select TDG触发模式*/
ADC_CONVERSION_SINGLE, /* ADC single conversion 单次转换模式*/
ADC_AVGS_8, /* 8 times average for each conversion 8次硬件均值滤波*/
100, /* Set the time interval between two samples when average is enabled or
in continues mode. Please refer to STS definition in RM to see the constraint 采样间隔时间*/
};
/* 对应Checklist中第15条,上电复位或Standby唤醒复位后,丢弃第一次采集的ADC值 */
Bsp_AdcWorkaround();
/* Select clock source for ADC */
while(ERR == CLK_ModuleSrc(CLK_ADC0, CLK_SRC_FIRC64M))
{
/* User or application must add logic code to tackle this situation. */
}
/* Set clock for ADC , make sure it is not greater than bus clock */
CLK_SetClkDivider(CLK_ADC0, CLK_DIV_1);
/* Reset ADC */
SYSCTRL_ResetModule(SYSCTRL_ADC0);
/* Enable ADC clock */
SYSCTRL_EnableModule(SYSCTRL_ADC0);
/* 对应Checklist中第20条,解决调用ADC_SoftwareReset之后有概率出现ADC FIFO中数据不为空的问题 */
ADC_SoftwareReset_Workaround();
/* Register the callback function */
//ADC_InstallCallBackFunc(ADC0_ID, ADC_FWM_INT, ADC_FifoWaterMakerIntCallback);
/* Initialize ADC */
ADC_Init(ADC0_ID,&subcaseAdcCfg);
ADC_FifoDepthRedefine(ADC0_ID, 6);
/* Set ADC watermark*/
ADC_FifoWatermarkConfig(ADC0_ID,5);
/* unmask FIFO watermark interrupt */
ADC_IntMask(ADC0_ID, ADC_INT_ALL, MASK);
ADC_IntClear(ADC0_ID, ADC_INT_ALL);
ADC_IntMask(ADC0_ID, ADC_FWM_INT, UNMASK);
/* Set trigger mode */
ADC_TDGTriggerConfig(ADC0_ID,&adcTriggerConfig0);
/* Enable ADC interrupt */
// NVIC_SetPriority(ADC0_IRQn, (uint32_t)ISR_PRIORITY_ADC);
// NVIC_EnableIRQ(ADC0_IRQn);
/* Enable ADC module */
ADC_Enable(ADC0_ID);
/**********************************************TDG相关配置***********************************************************/
/* mod value, single, divide4, SW trig, clear to mod */
/*配置TDG计数器*/
TDG_InitConfig_t config=
{
0xFA0, /*!< modulate value 重载值 */
TDG_COUNT_SINGLE, /*!< count mode 计数模式 */
TDG_CLK_DIVIDE_4, /*!< presacle clock source */
TDG_TRIG_SW, /*!< counter trig source TDG触发模式*/
TDG_UPDATE_IMMEDIATELY,/*!< update mode 配置更新模式*/
TDG_CLEAR_MODULATOR/*!< counter clear mode 计数清零模式*/
};
/*配置输出延时点*/
TDG_DelayOutputConfig_t doConfig[1] =
{
{
TDG_DO_0, /*!< delay output id 延时点ID*/
0xFA0,/*!< delay output offset 延时值*/
ENABLE},/*!< delay output enable 使能*/
};
/*配置TDG通道*/
const TDG_ChannelConfig_t chConfig =
{
TDG_CHANNEL_0, /*!< channel id 通道id*/
0x016, /*!< delay output complete interrupt delay 中断延时点*/
1, /* number of delya output point 输出延时点个数*/
doConfig/*输出延时点配置句柄*/
};
/* Select clock source for TDG */
CLK_ModuleSrc(CLK_TDG0, CLK_SRC_FIRC64M);
CLK_SetClkDivider(CLK_TDG0, CLK_DIV_4);
/*Enable TDG module */
SYSCTRL_EnableModule(SYSCTRL_TDG0);
/* Select clock source for TDG */
CLK_ModuleSrc(CLK_TDG0, CLK_SRC_FIRC64M);
CLK_SetClkDivider(CLK_TDG0, CLK_DIV_4);
/*Enable TDG module */
SYSCTRL_EnableModule(SYSCTRL_TDG0);
/* Initialize TDG */
TDG_InitConfig(TDG0_ID, &config);
/* Set TDG delay output*/
TDG_ChannelDelayOutputConfig(TDG0_ID, &chConfig, ENABLE);
/* enable TDG */
TDG_Enable(TDG0_ID, ENABLE);
/* Load channel configuration */
TDG_LoadCmd(TDG0_ID);
}
void GetAdcValue(){
uint8_t WaitTimeOutTick = 0u;
uint8_t AdcChannelNum[AD_GROUP0_CHANNEL_ALL] = {0u};
uint16_t AdcConvertData[AD_GROUP0_CHANNEL_ALL] = {0u};
uint32_t TempData = 0u;
if(ADC_GetStatus(ADC0_ID, ADC_STATUS_ACTIVE) == RESET)
{
TDG_SoftwareTrig(TDG0_ID);
}
while((ADC_GetStatus(ADC0_ID, ADC_STATUS_FIFO_RDY) != SET) ||
(ADC_GetStatus(ADC0_ID, ADC_STATUS_FWM_INT) != SET)){
WaitTimeOutTick ++;
if(WaitTimeOutTick >= 100u){
Break;
}
};
if (ADC_GetStatus(ADC0_ID, ADC_STATUS_FIFO_RDY) == SET) &&
(ADC_GetStatus(ADC0_ID, ADC_STATUS_FWM_INT) == SET))
{
TempData=ADC_GetConversionResult(ADC0_ID);
AdcChannelNum[i] = (uint8_t)((TempData >> 12u) & 0x1Fu);
AdcConvertData[i]=((uint32_t)(TempData) & 0xFFFu);
}
}
三、测试结果
四、总结
本文为博主开发过程中总结而得,如有不正之处欢迎指正。