DSP不需要复用GPIO,是单独的ADC引脚,与GPIO不共用
ADC结构图
大概图
排序器结构图
双排序器,而且ADCA优先于ADCB
ADCA对应SEQ1排序器1 conV00 到07 结果寄存器0到7
。ADCB使用排序器SEQ2;conV08 到15 结果寄存器8到15
而级联的排序器在同步模式下,也是先A后B,排序器的0是 conv0和conv8 而且先运算conv0 放在结果0寄存器,再把conv8放在结果1寄存器;
采样时间
ADC时钟在PCLKCR0寄存器
所以还要配置HSPCLK
HISPCP/HSPCLK寄存器
所以ADC的输入时钟,有固定公式;
控制寄存器1
简单配置3个东西;
ACQ_PS:单位就是ADC时钟个数也就是 ADC保持、采样的时间
EOC是排序器工作结束,大概是运算结束吧;
cont_RUN, 0为运算结束后停止,而1就是连续模式
SEQ_CASC 0是双排序器模式 1是单排序器模式
控制寄存器2
当前使用双排序, SOC_SEQ1排序器1 SOC触发源选择软件触发
控制器3寄存器
5到7全部设置为1,选择参考电路之外全部上电。个人觉得就是参考电压吧;
通道选择寄存器;
选择通道0
一个寄存只有4个通道
最大转换通道寄存器
用的是SEQ1,所以使用这个7位的前3位去选择对应的SEQ1排序器的CONV最多的号数最多从0到7 ,0是1 7为8;
状态寄存器
可以通过下面两个位;读取转换完成标记和清除标记(EOS估计是转换完成)
程序:
ADC.c
/*
* adc.c
*
* Created on: 2023年12月15日
* Author: My PC
*/
#include"adc.h"
void ADC1_init()
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;
SysCtrlRegs.HISPCP.all = 3;//150M/(3*2),时钟固定公式
AdcRegs.ADCTRL1.bit.ACQ_PS = 0xf;//保持ADC时钟数
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1;//双排序器模式
AdcRegs.ADCTRL1.bit.CONT_RUN = 1;//连续模式
AdcRegs.ADCTRL3.all = 0x00E0;///选择除参考电路外 全部模拟电路上电
AdcRegs.ADCTRL3.bit.ADCCLKPS = 1;//ADC核心时钟再分频 现在是/ 2
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0;//通道选择寄存器 0
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0;//最大转换通道数为1
EDIS;
AdcRegs.ADCTRL2.all = 0x2000;//选择软件触发
// DELAY_US(5000);//等待一断时间不然直接有4095,或者把标记清除
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//清楚标志
}
int read_adc1()
{
if (AdcRegs.ADCST.bit.INT_SEQ1 == 1)//事件标志
{
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;//清除事件标志
return AdcRegs.ADCRESULT0 >> 4;//结果寄存器
}
return 0;
}
主函数
#include "led1.h"
#include "key.h"
#include "epwm.h"
#include "exti.h"
#include "time0.h"
#include "adc.h"
int main()
{
float temp = 0;
Uint16 adc_num;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
led_init();
time0_init(2000);
ADC1_init();
while (1)
{
if(( adc_num=read_adc1())>100)
{
temp=adc_num/4096.0*3.0;
}
}
}