📄 k60-keil
字号:
/*============================================================================
文件名称:DAC.c
功能概要:K60 DAC
版权所有:卿丞数码
=============================================================================*/
#include <MK60N512MD100.h> // MK60N512MD100 Definitions
#include "ADC.h" //包含DAC驱动程序头文件
#define __ADC0_IRQ 0 /* 0=pooling mode, 1=interrupt mode */
#define __ADC1_IRQ 0 /* 0=pooling mode, 1=interrupt mode */
#define __DAC_DMA 0
uint8_t ADC0_Channel=4, ADC1_Channel=4;
uint16_t ADC0_Val[30]={0};
uint16_t ADC1_Val[30]={0};
uint16_t ADC0_DmaVal[30]={0};
uint16_t ADC1_DmaVal[30]={0};
/*============================================================================
函数名称:ADC_Calib
函数返回:无
参数说明:ADC_Channel:通道号ADC0 ADC1。
功能概要:Perform calibration of thmaximum avg. samples shoube less or equal
to 4MHz.reconfigured as desired.
==============================================================================*/
void ADC_Calib(ADC_Type *ADChannel)
{
uint16_t val;
ADChannel->SC2 &= ~ADC_SC2_ADTRG_MASK;
ADChannel->SC3 &= ~ADC_SC3_ADCO_MASK;
ADChannel->SC3 |= ADC_SC3_AVGE_MASK | ADC_SC3_AVGS_MASK;
ADChannel->SC3 |= ADC_SC3_CAL_MASK; /* Start calibration (set CAL bit) */
ADChannel->SC3 |= ADC_SC3_CAL_MASK; /* Start calibration (set CAL bit) */
while (!(ADChannel->SC1[0] & ADC_SC1_COCO_MASK)); /* Wait until conversion done */
val = ADChannel->CLPD + ADChannel->CLPS;
val += ADChannel->CLP0 + ADChannel->CLP1 + ADChannel->CLP2 + ADChannel->CLP3 + ADChannel->CLP4;
val /= 2; /* Variable must be divided by two */
ADChannel->PG = val | 0x8000; /* MBS must be set */
val = ADChannel->CLMD + ADChannel->CLMS;
val += ADChannel->CLM0 + ADChannel->CLM1 + ADChannel->CLM2 + ADChannel->CLM3 + ADChannel->CLM4;
val /= 2; /* Variable must be divided by two */
ADChannel->MG = val | 0x8000; /* MBS must be set */
ADChannel->SC3 &= ADC_SC3_CAL_MASK; /* Clear CAL bit */
}
/*============================================================================
函数名称:ADC_init
函数返回:无
参数说明:ADC_Channel:通道号ADC0 ADC1。
功能概要:初始化ADC模块设定。
=============================================================================*/
void ADC_Init(ADC_Type *ADChannel,uint8_t Accuracy)
{
switch(Accuracy)
{
case 8:
Accuracy=0x00;
break;
case 12:
Accuracy=0x01;
break;
case 10:
Accuracy=0x02;
break;
case 16:
Accuracy=0x03;
break;
default:
Accuracy=0x03;
break;
}
if(ADChannel==ADC0)
{
SIM->SOPT7 &=~ SIM_SOPT7_ADC0ALTTRGEN_MASK; //PDB trigger selected for ADC0
SIM->SOPT7 &=~ SIM_SOPT7_ADC0PRETRGSEL_MASK; //Pre-trigger A selected for ADC0.
SIM->SOPT7 |= SIM_SOPT7_ADC0TRGSEL(0);
SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK;
}
else if(ADChannel==ADC1)
{
SIM->SOPT7 &=~ SIM_SOPT7_ADC1ALTTRGEN_MASK; //PDB trigger selected for ADC1
SIM->SOPT7 &=~ SIM_SOPT7_ADC1PRETRGSEL_MASK; //Pre-trigger A selected for ADC1.
SIM->SOPT7 |= SIM_SOPT7_ADC1TRGSEL(0);
SIM->SCGC3 |= SIM_SCGC3_ADC1_MASK; // Enable ADC 1 gate clocking
}
ADChannel->CFG1 |= ADC_CFG1_MODE(Accuracy); // Select conversion Accuracy
ADChannel->CFG1 |= ADC_CFG1_ADICLK(0); // Select Bus clock
ADChannel->CFG1 |= ADC_CFG1_ADIV(2); // The divide ratio is 1 and the clock rate is input clock.
ADChannel->CFG1 |= ADC_CFG1_ADLSMP_MASK; // Select Long sample time
ADChannel->CFG1 &=~ ADC_CFG1_ADLPC_MASK; //1-Low power configuration 0 Normal power configuration.
ADChannel->CFG2 &=~ ADC_CFG2_MUXSEL_MASK; // ADxxa channels are selected
ADChannel->CFG2 |= ADC_CFG2_ADLSTS(0); //Default longest sample time (20 extra ADCK cycles; 24 ADCK cycles total).
ADChannel->CFG2 |= ADC_CFG2_ADHSC_MASK; //High speed conversion sequence selected
ADChannel->CFG2 &=~ ADC_CFG2_ADACKEN_MASK; //Asynchronous clock output disabled
ADC_Calib (ADChannel); /* Perform calibration of the ADC */
ADChannel->SC2 |= ADC_SC2_REFSEL(0); //Default voltage reference pin pair (External pins V REFH and V REFL)
#if __DAC_DMA
ADChannel->SC2 |= ADC_SC2_DMAEN_MASK; //DMA is enabled
#endif
/*
00 4 samples averaged.
01 8 samples averaged.
10 16 samples averaged.
11 32 samples averaged.
*/
ADChannel->SC3 |= ADC_SC3_AVGE_MASK ; //Hardware average function enabled
ADChannel->SC3 |= ADC_SC3_AVGS(0); //Hardware average select
ADChannel->SC3 |= ADC_SC3_ADCO_MASK ; //Continuous conversion enable
ADChannel->SC1[0] = 0; //set to zero
ADChannel->SC1[0] |= ADC_SC1_AIEN_MASK; //Conversion complete interrupt enabled
ADChannel->SC1[0] &=~ ADC_SC1_DIFF_MASK; //diff=0,Single-ended conversions and input channels are selected
ADChannel->SC1[0] |= ADC_SC1_ADCH(4);
#if __ADC0_IRQ
NVIC_EnableIRQ(ADC0_IRQn); /* Enable ADC0 Interrupt */
#endif
#if __ADC1_IRQ
NVIC_EnableIRQ(ADC1_IRQn); /* Enable ADC1 Interrupt */
#endif
}
/*============================================================================
函数名称:ADC_GetVal
函数输入:ADChannel模块号 Channel通道号:具体管脚参考管脚图
函数返回:通道电压值
参数说明:ADC_Channel:通道号ADC0 ADC1。
功能概要:采集电压值
==============================================================================*/
uint16_t ADC_GetVal (ADC_Type *ADChannel,uint8_t Channel)
{
uint16_t Val=0;
ADChannel->SC1[0] &=~ ADC_SC1_ADCH_MASK; // 赋值前先清零
ADChannel->SC1[0] |= ADC_SC1_ADCH(Channel); // When DIFF=0, DADP0 is selected as input 具体管脚参考管脚图
while (( ADChannel->SC1[0] & ADC_SC1_COCO_MASK ) != ADC_SC1_COCO_MASK);
Val=ADChannel->R[0];
ADChannel->SC1[0] &=~ ADC_SC1_COCO_MASK; // clear flag
return Val;
}
/*============================================================================
函数名称:ADC_Close
函数输入:ADChannel模块号 Channel通道号
函数返回:通道电压值
参数说明:ADC_Channel:通道号ADC0 ADC1。
功能概要:关闭AD模块
==============================================================================*/
void ADC_Close(ADC_Type *ADChannel)
{
if(ADChannel==ADC0)
{
SIM->SOPT7 &=~ SIM_SOPT7_ADC0TRGSEL(0);
SIM->SCGC6 &=~ SIM_SCGC6_ADC0_MASK; // disable ADC 0 gate clocking
}
else if(ADChannel==ADC1)
{
SIM->SOPT7 &=~ SIM_SOPT7_ADC1TRGSEL(0);
SIM->SCGC3 &=~ SIM_SCGC3_ADC1_MASK; // disable ADC 1 gate clocking
}
ADChannel->SC1[0] = ADC_SC1_ADCH(0x1f); //Module disabled
}
/*============================================================================
函数名称:ADC_DMA_Init
函数输入:ADChannel模块号:0-1 DMAChannelDMA通道号:0-15
函数返回:void
参数说明:ADC_Channel:通道号ADC0 ADC1。
功能概要:ADC转换值通过DMA传输到相应位置
==============================================================================*/
void ADC_DMA_Init(ADC_Type *ADChannel,uint8_t DMAChannel)
{
SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK;
SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;
DMA->TCD[DMAChannel].NBYTES_MLNO=2;
DMA->TCD[DMAChannel].NBYTES_MLOFFNO=2|DMA_NBYTES_MLOFFYES_SMLOE_MASK|DMA_NBYTES_MLOFFYES_DMLOE_MASK;
DMA->CR= DMA_CR_EMLM_MASK|DMA_CR_CLM_MASK;
if(ADChannel==ADC0)
{
DMA->TCD[DMAChannel].SADDR = (uint32_t)(&(ADC0->R[0])); //取ADC0数据存储器地址
DMA->TCD[DMAChannel].SOFF = 0; // address offset
/*
0 : 8 bit
1 : 16 bit
2 : 32 bit
4 : 16 byte
*/
DMA->TCD[DMAChannel].ATTR = 0;
DMA->TCD[DMAChannel].ATTR |= DMA_ATTR_SSIZE(1) | DMA_ATTR_DSIZE(1); // source/dest size
DMA->TCD[DMAChannel].ATTR |= DMA_ATTR_SMOD(0); //Source address modulo feature is disabled
DMA->TCD[DMAChannel].DADDR = (uint32_t)ADC0_DmaVal; //转换值存在ADC0_DmaVal[]
DMA->TCD[DMAChannel].DOFF = 0; //address offset
DMAMUX->CHCFG[DMAChannel] = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(40); //ADC0 DMA channel=40,refer to DMA request sources p118
}
else if(ADChannel==ADC1)
{
DMA->TCD[DMAChannel].SADDR = (uint32_t)(&(ADC1->R[0])); //取ADC1数据存储器地址
DMA->TCD[DMAChannel].SOFF = 0; // address offset
DMA->TCD[DMAChannel].ATTR = 0;
DMA->TCD[DMAChannel].ATTR |= DMA_ATTR_SSIZE(1) | DMA_ATTR_DSIZE(1); // source/dest size
DMA->TCD[DMAChannel].ATTR |= DMA_ATTR_SMOD(0); //Source address modulo feature is disabled
DMA->TCD[DMAChannel].DADDR = (uint32_t)ADC1_DmaVal; //转换值存在ADC1_DmaVal[]
DMA->TCD[DMAChannel].DOFF = 0; //address offset
DMAMUX->CHCFG[DMAChannel] |=DMAMUX_CHCFG_TRIG_MASK| DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(41); //ADC0 DMA channel=41,refer to DMA request sources p118
}
DMA->ERQ |= 1<<DMAChannel; // Enable CH0 of DMA
}
/*============================================================================
函数名称:ADC0_IRQHandler
函数输入:
函数返回:void
参数说明:
功能概要:ADC0中断,采集的AD值存放在ADC0_Val[]中
==============================================================================*/
void ADC0_IRQHandler(void)
{
ADC0_Val[ADC0_Channel]= ADC0->R[0];
ADC0_Channel++;
if(ADC0_Channel==30)ADC0_Channel=4;
ADC0->SC1[0] &=~ ADC_SC1_ADCH_MASK; // 赋值前先清零
ADC0->SC1[0] |= ADC_SC1_ADCH(ADC1_Channel); // When DIFF=0, DADP0 is selected as input
ADC0->SC1[0] &=~ ADC_SC1_COCO_MASK; // clear flag
}
/*============================================================================
函数名称:ADC1_IRQHandler
函数输入:
函数返回:void
参数说明:
功能概要:ADC1中断 采集的AD值存放在ADC1_Val[]中
==============================================================================*/
void ADC1_IRQHandler(void)
{
ADC1_Val[ADC1_Channel] = ADC1->R[0];
ADC1_Channel++;
if(ADC1_Channel==30)ADC1_Channel=4;
ADC1->SC1[0] &=~ ADC_SC1_ADCH_MASK; // 赋值前先清零
ADC1->SC1[0] |= ADC_SC1_ADCH(ADC1_Channel); // When DIFF=0, DADP0 is selected as input
ADC1->SC1[0] &=~ ADC_SC1_COCO_MASK; // clear flag
}
/*-----------------------------------------------------------------------------
* End of file
*----------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -