⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 TMS320LF2407A片内十位A/D转换程序
💻 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 + -