📄 main.c
字号:
/* main.c */
#include "F2407regs.h"
#include "GPIO_DEF.h"
#include "INT_REG_DEF.h"
unsigned int ADCResult[24]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
unsigned int ADCNum = 0,i = 0,T1Num = 0,P=0;
unsigned int T1CONVAL=0,GPTCONAVAL=0;
main()
{
SysInit();
PioInit();
ADCInit();
T1Init();
IntRegsInit();
while(1);
}
SysInit()
{
asm(" setc INTM");//关闭总中断使能
*WDCR = 0x0E8; // 关闭看门狗定时器,调试阶段不使用
asm(" setc SXM");//
*SCSR1 = 0x828F; //xclkin=15M, clkin = 30M;启动ADC时钟;CLKOUT=clkin。
}
IntRegsInit() //中断寄存器初始化
{
*IFR = 0xFFFF;//CPU中断标志位清零
*IMR = 0xFFFF;//CPU中断使能
*EVAIFRA |=T1PINTCLEAR; //清除外设中断标志位
*EVAIMRA |=T1PINTENABLE;//使能外设中断
asm(" clrc INTM");//开总中断
}
PioInit()
{
*MCRA |=0x0FF; //io引脚
*PADATDIR |=0xFF11; //bit 9-8=01 SCITX:input SCIRX:output
}
ADCInit()
{
*ADCCTRL1 |= 0x4000; //复位ADC模块寄存器
asm(" NOP"); //在重新赋值之前,需要延时
asm(" NOP");
asm(" NOP");
*ADCCTRL1 &= 0xBFFF; //取消系统复位,可以对ADC寄存器重新赋值
asm(" nop");
asm(" nop");
asm(" nop");
//--------------------------------------------------------
//ADC模块时钟预定标,ADC时钟频率也可能影响AD转换精度
*ADCCTRL1 |= 0x0080;
// CPS = 1;Aclk = CLKIN/2;A/D转换时间为11*Aclk
*ADCCTRL1 = *ADCCTRL1 & 0xF3FF|0x0300; //采样保持时间=4*2*Aclk
//采样保持预定标根据信号源阻抗选择,
//例如信号源阻抗为500欧,CLKIN为30M,CPS为1,ACQPS应为0001
//--------------------------------------------------------
//自测试模式组态
*ADCCTRL1 &= 0xFFFE; //禁止自测试模式,自测试时,ADC输入由VREFHI和VREFLO组合定
//VREFHI和VREFLO为ADC转换参考电压,并非为自测试模式才有
//--------------------------------------------------------
//校准模式组态
*ADCCTRL1 &= 0xFFF7; //禁止校准模式,ADC转换结果不需要自动校准
//--------------------------------------------------------
//排序器模式组态
*ADCCTRL1 |= 0x0010; //级连排序器SEQ,16通道
//--------------------------------------------------------
//转换模式组态
*ADCCTRL1 &= 0xFFBF; //启动/停止模式
//启动-停止-复位和启动-停止-再起动-停止。。-复位
//--------------------------------------------------------
//ADC中断请求组态
*ADCCTRL1 &= 0xFFDF; //ADC中断为高优先级
*ADCCTRL2 = *ADCCTRL2 &0xF7FF |0x0400; //中断使能,INT_FLAG_SEQ1置1后立即响应中断
//--------------------------------------------------------
//启动ADC触发源组态
//SEQ 置位ADCCTRL2的第13位,软件触发AD中断
*ADCCTRL2 |= 0x0100; //使能EVA触发A/D转换
*ADCCTRL2 &=0x7FFF; //禁止EVB模块触发SEQ AD转换
*ADCCTRL2 &= 0xFF7F; //禁止外部ADCSOC引脚触发A/D转换
/*
//SEQ1 置位ADCCTRL2的第13位,软件触发AD中断
*ADCCTRL2 |= 0x0100; //使能EVA触发A/D转换
*ADCCTRL2 &= 0xFF7F; //禁止外部ADCSOC引脚触发A/D转换
//SEQ2 置位ADCCTRL2的第5位,软件触发AD中断
*ADCCTRL2 &= 0xFFFE; //禁止EVB模块触发AD转换
*/
//--------------------------------------------------------
//转换通道总数设置与转换顺序设置
*MAXCONV = 0x0003; //AD转换通道数为4 为什么改成0x0004后主程序中前两个移位语句
//没有被执行
//最大转换通道个数,启动AD转换后,MAXCONV值加载到AUTOSEQSR
//寄存器中
*CHSELSEQ1 = 0xFE40;//转换顺序ADCIN15->ADCIN14->ADCIN4->ADCIN0
//结果寄存器与CHSELSEQ相对应
//--------------------------------------------------------
//*ADCCTRL2 |=0x2000;//启动A/D转换
}
T1Init()
{
//GPTCONA T1CON T2CON T1PR T1CNT T1CMPR T2PR T2CNT T2CMPR
//GPTCONB T3CON T3CON T3PR T3CNT T3CMPR T4PR T4CNT T4CMPR
//定时器用途:产生波形TxCMP/TxPWM
// 产生四个中断
// 为全比较器提供时基
// 为CAP,QEP提供时基
// 启动ADC
// 定时器寄存器赋值顺序没有要求,最后一条是启动指令就可以
//--------------------------------------------------------
//定时器时钟
*T1CON =*T1CON&0xFFCF;//定时器时钟源为内部CPU时钟(可组态为外部TCLKINA或正交编码)
*T1CON =*T1CON&0xFDFF|0x0500;//输入时中预定标系数32,CPU时钟为输入时钟时才有意义
//--------------------------------------------------------
*T1CON =*T1CON&0xF7FF|0x1000;//连续增计数模式
//--------------------------------------------------------
// 定时器比较
*T1CON &=0xFFFD; //禁止定时器T1比较操作
*GPTCONA &=0xFFBF;//禁止通用定时器T1,T2比较输出(高阻态)
*GPTCONA = *GPTCONA&0xFFF6|0x0006;//T1比较输出低有效,T2比较输出高有效。
//相当于一组PWM。单路T1CMP。双路T1PWM。
*T1CON =*T1CON&0xFFF7|0x0004;//当计数值是0或等于周期寄存器值时重装载T1CMPR
//写TxCMPR和TxPR和MAXCONV,是对影子寄存器操作
//具体类比MAXCONV。
//--------------------------------------------------------
// T1,T2配合使用寄存器设置
*T1CON &=0xFF7F;//T2使用自身的使能位启动定时器
*T1CON &=0xFFFE;//T2使用自身的周期寄存器,不使用T1PR
//比较寄存器T2CMPR使用自身
//--------------------------------------------------------
//定时器启动ADC设置
*GPTCONA =*GPTCONA|0x0100&0xFF7F;//T1的T1PR中断启动ADC
*GPTCONA =*GPTCONA&0xF9FF;//T2无事件启动ADC
//--------------------------------------------------------
//--------------------------------------------------------
*T1CNT = 0x0000;
*T1PR = 0x0070;//定时器时钟为1uS*XXXX
asm(" nop");
asm(" nop");
*T1CON |= 0x0040;//启动定时器,采样时间可调
T1CONVAL = *T1CON;
GPTCONAVAL=*GPTCONA;
// *GPTCONA = 0xF930;
/* BIT 10:9 = 00 T2无事件启动模数转换
BIT 8:7 = 10 T1周期中断标志来启动模数转换
BIT 6 = 0 禁止EVA通用定时器比较输出
*/
// *T1CNT = 0x0000;
// *T1PR = 0xF000;
// *T1CON = 0x324C;
/* BIT 12:11 = 10 连续增计数模式
BIT 10:8 = 010 时钟预定标X/4
BIT 6 = 1 启动定时器
BIT 5:4 = 00 内部CPU时钟
*/
}
interrupt void T1INTIsr(void)
{
if((*EVAIFRA&T1PINTCLEAR))
{
T1Num += 1;
if(T1Num == 3) //触发3次ADC
{
*T1CON &= 0xFFBF; //关闭定时器
T1Num = 0;
}
*EVAIFRA |=T1PINTCLEAR; //清除中断标志位
}
if((*EVAIFRA&T1CINTCLEAR))
{
*EVAIFRA |=T1CINTCLEAR; //清除中断标志位
}
if((*EVAIFRA&T1UFINTCLEAR))
{
*EVAIFRA |=T1UFINTCLEAR; //清除中断标志位
}
if((*EVAIFRA&T1OFINTCLEAR))
{
*EVAIFRA |=T1OFINTCLEAR; //清除中断标志位
}
asm(" clrc INTM");
}
interrupt void AD_Isr(void)
{
ADCNum += 1;
ADCResult[i] = (*RESULT0>>6);
ADCResult[i+3] = (*RESULT1>>6);
ADCResult[i+6] = (*RESULT2>>6);
ADCResult[i+9] = (*RESULT3>>6);
i += 1;
//*ADCCTRL1 |= 0x4000;//复位排序器指针至CONV00 SEQ SEQ1
//为什么加上复位后,ADC中断服务程序只产生一次
/*
ADCNum += 1;
ADCResult[i] = i+1;
ADCResult[i+3] = i+2;
ADCResult[i+6] = i+3;
ADCResult[i+9] = i+4;
i += 1;
//*ADCCTRL1 |= 0x4000;//复位排序器指针至CONV00 SEQ SEQ1
//为什么加上复位后,ADC中断服务程序只产生一次
//*ADCCTRL1 |= 0x0040;//复位排序器指针至CONV08 SEQ2
*/
*ADCCTRL2 |=0x0200;//清中断标志
asm(" clrc INTM");
}
interrupt void PHANTOM(void)
{
P=2;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -