amobbs.com 阿莫电子技术论坛

标题: C8051F020 定时器3溢出转换问题 望大神指教 [打印本页]

作者: chenweigang    时间: 2012-4-28 13:28
标题: C8051F020 定时器3溢出转换问题 望大神指教
#include <c8051f020.h>                 
#include <stdio.h>
#include "ZLG7289.h"                     

//-----------------------------------------------------------------------------
// 16-bit SFR 定义
//-----------------------------------------------------------------------------


sfr16 RCAP2    = 0xca;                 // 定时器2捕捉/重载
sfr16 RCAP3    = 0x92;                 // 定时器3捕捉/重载  TMR3RLL
sfr16 TMR2     = 0xcc;                 // 定时器2
sfr16 TMR3     = 0x94;                 // 定时器3                        TMR3L

//-----------------------------------------------------------------------------
// 全局常量
//-----------------------------------------------------------------------------


#define SYSCLK       24000000          // 外部系统时钟
#define SAMPLE_RATE  500000             // 采样频率

#define SAR_CLK      1000000           // 转换时钟

#define SAMPLE_DELAY 50                // 采样前延时50ms



//-----------------------------------------------------------------------------
// 功能函数声明
//-----------------------------------------------------------------------------

void OSCILLATOR_Init (void);           
void PORT_Init (void);
void ADC0_Init (void);
void TIMER3_Init (int counts);
void ADC0_ISR (void);
void Wait_MS (unsigned int ms);

//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------

long Result;                           // ADC0 平均值

unsigned char int_dec;


//-----------------------------------------------------------------------------
// 主函数
//-----------------------------------------------------------------------------
/*void DelayMs(unsigned int n)//延时(n)MS
{
        unsigned int i;
        for(;n>0;n--)
        {
                for(i=2211;i>0;i--);
        }
}*/

void main (void)
{
   long measurement;                   // 电压值以毫伏为单位
   unsigned char qian,bai,shi,ge;
   WDTCN = 0xde;                       // 关闭开门狗
   WDTCN = 0xad;
   
   OSCILLATOR_Init ();                 // 初始化振荡器
   PORT_Init ();                       // 初始化数据交叉开关和GPIO
   TIMER3_Init (SYSCLK/SAMPLE_RATE);   // 初始化定时器3以ADC0采样速率溢出                                      
   ADC0_Init ();                       // 初始化 ADC
   TMR3CN |= 0x04;
   AD0EN = 1;                          // 打开 ADC
   
   EA = 1;                             // 开全局中断
//   while(Result==0);                                  
   while (1)
   {
               
                EA = 0;                          // 关闭中断
             //                           Vref (mV)
             //         measurement (mV) =   --------------- * Result (bits)
             //                               (2^12)-1 (bits)
              measurement =  Result * 2435 / 4096;

                qian = measurement / 1000;
                ZLG7289_Download(1,0,0,qian);
                bai = (measurement - qian * 1000) / 100;
                ZLG7289_Download(1,1,0,bai);
                shi = (measurement - qian * 1000 - bai * 100) /10;
                ZLG7289_Download(1,2,0,shi);
                ge = measurement - qian * 1000 - bai * 100 - shi * 10;
                ZLG7289_Download(1,3,0,ge);       

             EA = 1;                          // 打开中断
             Wait_MS(SAMPLE_DELAY);           
               
                                     
   }
}


void OSCILLATOR_Init (void)
{
   int i;                              // 延时计数器

   OSCXCN = 0x67;                      // 启动外部振荡器(24M)


   for (i=0; i < 256; i++) ;           // 等待1ms

   while (!(OSCXCN & 0x80)) ;          // 等待是否稳定振荡

   OSCICN = 0x88;                      // 选择外部振荡器为系统时钟源并
                                       //允许时钟丢失检测器
}


void PORT_Init (void)
{

  XBR2    |= 0x40;                    // 使能交叉开关
  P3MDOUT = 0xff;
  P1MDIN  = 0xFD;
  P1MDOUT = 0x00;
  P1          = 0xFF;
}  




void ADC0_Init (void)
{

   ADC0CN = 0x04;                      // ADC0 disabled; normal tracking
                                       // mode; ADC0 conversions are initiated
                                       // on overflow of Timer3; ADC0 data is
                                       // right-justified

   REF0CN = 0x07;                      // Enable temp sensor, on-chip VREF,
                                       // and VREF output buffer

   AMX0CF = 0x00;                      // AIN inputs are single-ended (default)

   AMX0SL = 0x00;                      // Select AIN0.1 pin as ADC mux input

   ADC0CF = (SYSCLK/SAR_CLK) << 3;     // ADC conversion clock = 2.5MHz
   ADC0CF |= 0x00;                     // PGA gain = 1 (default)

   EIE2 |= 0x02;                       // enable ADC interrupts

}



void TIMER3_Init (int counts)
{

   TMR3CN = 0x02;                      // Stop Timer3; Clear TF3; set sysclk
                                       // as timebase
   RCAP3   = -counts;                  // Init reload values
   TMR3    = RCAP3;                    // Set to reload immediately
   EIE2   &= ~0x01;                    // Disable Timer3 interrupts
//   TMR3CN |= 0x04;                     // start Timer3

}


void ADC0_ISR (void) interrupt 15
{

                                    
   unsigned int accumulator=0;         // Here's where we integrate the
    static long accumulator_1=0L;                                    // ADC samples

   AD0INT = 0;                         // Clear ADC conversion complete                                       // indicator
   accumulator = ((ADC0H <<8))& 0xff00 | ADC0L;// Read ADC value and add to running
   accumulator_1 += accumulator;
   accumulator  = 0x00;                                    // total
   int_dec++;                          // Update decimation counter

   if (int_dec == 9)                   // If zero, then post result
   {
      int_dec = 0;               // Reset counter          
          Result = accumulator ;
      accumulator = 0x00;                // Reset accumulator
          accumulator_1 = 0L;
   }  
   
                                                



            
   
}

//-----------------------------------------------------------------------------
// Support Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// Wait_MS
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters:
//   1) unsigned int ms - number of milliseconds of delay
//                        range is full range of integer: 0 to 65335
//
// This routine inserts a delay of <ms> milliseconds.
//
//-----------------------------------------------------------------------------
void Wait_MS(unsigned int ms)
{

   CKCON &= ~0x20;                     // use SYSCLK/12 as timebase

   RCAP2 = -(SYSCLK/1000/12);          // Timer 2 overflows at 1 kHz          2000*(1/2)=1MS
   TMR2 = RCAP2;

   ET2 = 0;                            // Disable Timer 2 interrupts

   TR2 = 1;                            // Start Timer 2

   while(ms)
   {
      TF2 = 0;                         // Clear flag to initialize
      while(!TF2);                     // Wait until timer overflows
      ms--;                            // Decrement ms
   }

             TR2 = 0;                            // Stop Timer 2

}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------
作者: chenweigang    时间: 2012-4-28 13:30
ADC0寄存器仿真看有值 数码管一直跳 结果不对




欢迎光临 amobbs.com 阿莫电子技术论坛 (https://www.amobbs.com/) Powered by Discuz! X3.4