打印
[51单片机]

c8051f040 PCA可编程计数器模块 只有一个CCF0能捕获数据,其他五个进不了中断,求指点

[复制链接]
4524|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主




#include <C8051F040.h>                 // SFR declarations
#include <stdio.h>

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F04x
//-----------------------------------------------------------------------------


//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------

#define BAUDRATE     115200            // Baud rate of UART in bps

// SYSCLK = System clock frequency in Hz
#define SYSCLK       22118400L         
#define T0_CLOCKS 245                  // Use 245 clocks per T0 Overflow
                                       //    (245 = 10 us)
#define T2_RELOAD_CLOCKS 6125  
#define uint        unsigned int
#define        uchar        unsigned char

sfr16 PCA0CP0 = 0xFB;                  // PCA0 Compare Register Definition
sfr16 RCAP2 = 0xCA;                    // Timer2 Reload Register
sfr16 TMR2 = 0xCC;                     // Timer2 counter

//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------
sbit LED1    = P3^3;

bit busy;
void OSCILLATOR_Init (void);
void PORT_Init_UART0 (void);
void UART0_Init (void);
void tx() ;
  void PORT_Init (void);
void PCA0_Init (void);

void TestTimerInit (void);
  
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------

uint Uart;                    // Global variable -- when '0', UART0
                                       // is used for stdio; when '1', UART1
uint   k0,k1,k2,k3,k4,k5;                                      // is used for stdio



void TxSend(char dat)
{         char SFRPAGE_SAVE;

   SFRPAGE_SAVE = SFRPAGE;
    SFRPAGE = UART0_PAGE;
    while (busy);               //等待上个数据发送完成
    busy = 1;


     

    SBUF0 = dat;                //发送数据
         SFRPAGE = SFRPAGE_SAVE;  
}

void tx()
{
        TxSend('P');
        TxSend('C');
        TxSend('A');
       // TxSend(id + '0');
        TxSend('=');
        TxSend(Uart/10000 + '0');
        TxSend(Uart%10000/1000 + '0');
        TxSend(Uart%1000/100 + '0');
        TxSend(Uart%100/10 + '0');
        TxSend(Uart%10 + '0');
        TxSend(0x0d);                  
        TxSend(0x0a);
}

   void SendString(char *s)
{
    while (*s)                  //判断字符串结束标志
    {
        TxSend(*s++);         //发送字符
    }
}


void main (void)
{
   SFRPAGE = CONFIG_PAGE;

   WDTCN = 0xDE;                       // Disable watchdog timer
   WDTCN = 0xAD;

   OSCILLATOR_Init ();                 // Initialize oscillator
   PORT_Init_UART0 ();                 // Initialize crossbar and GPIO

   UART0_Init ();
                        // Initialize UART0
    PCA0_Init ();                       // Initialize PCA0
   TestTimerInit ();                   // Configure Timer2 for test signal
   EA = 1;
   while (1)
   {
      // print something to UART0
      //PORT_Init_UART0 ();              // Configure Crossbar to pinout
       Uart=k0;
            tx() ;                           // UART0 TX and RX to P0.0 and P0.1
       Uart=k1;
            tx() ;                           // UART0 TX and RX to P0.0 and P0.1
              Uart=k2;
            tx() ;
                 Uart=k3;
            tx() ;
                 Uart=k4;
            tx() ;
                 Uart=k5;
            tx() ;
   }
}



void OSCILLATOR_Init (void)
{
   int i;                              // Software timer

   char SFRPAGE_SAVE = SFRPAGE;        // Save Current SFR page

   SFRPAGE = CONFIG_PAGE;              // Set SFR page

   OSCICN = 0x80;                      // Set internal oscillator to run
                                       // at its slowest frequency

   CLKSEL = 0x00;                      // Select the internal osc. as
                                       // the SYSCLK source

   // Initialize external crystal oscillator to use 22.1184 MHz crystal

   OSCXCN = 0x67;                      // Enable external crystal osc.
   for (i=0; i < 256; i++);            // Wait at least 1ms

   while (!(OSCXCN & 0x80));           // Wait for crystal osc to settle

   CLKSEL = 0x01;                      // Select external crystal as SYSCLK
                                       // source

   SFRPAGE = SFRPAGE_SAVE;             // Restore SFRPAGE
}


void PORT_Init_UART0 (void)
{
   char SFRPAGE_SAVE = SFRPAGE;        // Save Current SFR page

   SFRPAGE = CONFIG_PAGE;              // Set SFR page

   XBR0     = 0x34;                    // Enable UART0       
   XBR1     = 0x00;
   XBR2     = 0x40;                    // Enable crossbar and weak pull-up
  XBR3     = 0x00;

   P0MDOUT |= 0x01;                    // Set TX pin to push-pull
   P1MDOUT |= 0x40;                    // Set P1.6(LED) to push-pull
   P3MDOUT |= 0x08;
   LED1=0;
   SFRPAGE = SFRPAGE_SAVE;             // Restore SFR page
}



void UART0_Init (void)
{
   char SFRPAGE_SAVE;

   SFRPAGE_SAVE = SFRPAGE;             // Preserve SFRPAGE

   SFRPAGE = TMR2_PAGE;

   TMR2CN = 0x00;                      // Timer in 16-bit auto-reload up timer
                                        // mode
   TMR2CF = 0x08;                      // SYSCLK is time base; no output;
                                       // up count only
   RCAP2 = - ((long) SYSCLK/BAUDRATE/16);
   TMR2 = RCAP2;
   TR2= 1;                             // Start Timer2

   SFRPAGE = UART0_PAGE;

   SCON0 = 0x50;                       // 8-bit variable baud rate;
                                       // 9th bit ignored; RX enabled
                                       // clear all flags
   SSTA0 = 0x15;                       // Clear all flags; enable baud rate
                                       // doubler (not relevant for these
                                       // timers);
                                       // Use Timer2 as RX and TX baud rate
                                       // source;
   TI0 = 1;                            // Indicate TX0 ready
        ES0 = 1;
   IP |= 0x10;
   SFRPAGE = SFRPAGE_SAVE;             // Restore SFRPAGE
}

void UART0_Interrupt (void) interrupt 4
{                   
          SFRPAGE = UART0_PAGE;

   if (RI0 == 1)
   {
      
      RI0 = 0;                           // Clear interrupt flag

      //Byte = SBUF0;                      // Read a character from UART

   }

   if (TI0 == 1)                   // Check if transmit flag is set
   {
      TI0 = 0;                           // Clear interrupt flag

             //        SBUF0 = 0x01;
                    busy = 0;
      }
      
         
}
void PCA0_Init (void)
{
   char SFRPAGE_save = SFRPAGE;        // Save current SFR Page

   SFRPAGE = PCA0_PAGE;

   // Configure PCA time base; overflow interrupt disabled
   PCA0CN = 0x00;                      // Stop counter; clear all flags
   PCA0MD = 0x02;                      // 使用  系统时钟/4


   PCA0CPM0 = 0x21;                    // Module 0 = Rising Edge Capture Mode
                                       // enable CCF flag.

   // Start PCA counter
   CR = 1;        //=PCA0CN=0x40

   SFRPAGE = CONFIG_PAGE;
   EIE1 |= 0x08;                       // Enable PCA interrupts
   SFRPAGE = SFRPAGE_save;

}



void TestTimerInit (void)
{
   char SFRPAGE_save = SFRPAGE;        // Save current SFR Page

   
   SFRPAGE = TMR3_PAGE;

   RCAP3L = -(int)T2_RELOAD_CLOCKS;     // Set up Timer 2 reload rate
   TMR3L = -(int)T2_RELOAD_CLOCKS;      // Preload timer

   TMR3CN = 0x04;                      // Timer 2 run in 16b auto-reload
   SFRPAGE = CONFIG_PAGE;
        EIE2=0X01;
   SFRPAGE = SFRPAGE_save;
}



void PCA0_ISR (void) interrupt 9
{
   static unsigned int current_capture_value0,current_capture_value1,current_capture_value2,current_capture_value3,
                                                   current_capture_value4,current_capture_value5, previous_capture_value;
   static unsigned int capture_period;

   
          
   
   if (CCF0)                           // If Module 0 caused the interrupt
   {
      CCF0 = 0;                        // Clear module 0 interrupt flag.
      capture_period = PCA0CPH0;
      capture_period = (capture_period  << 8)   + PCA0CPL0;
      previous_capture_value =capture_period- current_capture_value0;
          current_capture_value0 =  capture_period;
           k0= 0xff;
   }

if (CCF1)                           // If Module 0 caused the interrupt
   {
      CCF1 = 0;                        // Clear module 0 interrupt flag.
      capture_period = PCA0CPH1;
      capture_period = (capture_period  << 8)   + PCA0CPL1;
      previous_capture_value =capture_period- current_capture_value1;
          current_capture_value1 =  capture_period;
           k1= 0xff;
          
   }
if (CCF2)                           // If Module 0 caused the interrupt
   {
      CCF2 = 0;                        // Clear module 0 interrupt flag.
      capture_period = PCA0CPH2;
      capture_period = (capture_period  << 8)   + PCA0CPL2;
      previous_capture_value =capture_period- current_capture_value2;
          current_capture_value2 =  capture_period;
           k2= 0xff;
          
   }
        if (CCF3)                           // If Module 0 caused the interrupt
   {
      CCF3 = 0;                        // Clear module 0 interrupt flag.
      capture_period = PCA0CPH3;
      capture_period = (capture_period  << 8)   + PCA0CPL3;
      previous_capture_value =capture_period- current_capture_value3;
          current_capture_value3 =  capture_period;
           k3= 0xff;
          
   }
  if (CCF4)                           // If Module 0 caused the interrupt
   {
      CCF4 = 0;                        // Clear module 0 interrupt flag.
      capture_period = PCA0CPH4;
      capture_period = (capture_period  << 8)   + PCA0CPL4;
      previous_capture_value =capture_period- current_capture_value4;
          current_capture_value4 =  capture_period;
           k4=0xff;
          
   }
  if (CCF5)                           // If Module 0 caused the interrupt
   {
      CCF5 = 0;                        // Clear module 0 interrupt flag.
      capture_period = PCA0CPH5;
      capture_period = (capture_period  << 8)   + PCA0CPL5;
      previous_capture_value =capture_period- current_capture_value5;
          current_capture_value5 =  capture_period;
           k5= 0xff;
          
   }
         
        if(CF == 1)        //PCA溢出中断
       {
             CF = 0;                        //清PCA溢出中断标志
                           
    }
  
   
         
}
void Timer2_ISR (void) interrupt 14
{
          
          if (TF3)
      {          LED1    =~LED1;
         TF3 = 0;                      // Clear T2 overflow
      }       
                }

相关帖子

沙发
若是射手|  楼主 | 2013-9-16 11:36 | 只看该作者
第一次发帖  求指点  各位大神

使用特权

评论回复
板凳
若是射手|  楼主 | 2013-9-16 11:37 | 只看该作者
在线等

使用特权

评论回复
地板
ayb_ice| | 2013-9-16 11:51 | 只看该作者
每个通道都有自己的中断使能位的

使用特权

评论回复
5
若是射手|  楼主 | 2013-9-16 12:52 | 只看该作者
ayb_ice 发表于 2013-9-16 11:51
每个通道都有自己的中断使能位的

每个通道都有一个中断标志位,CCF0~CCF5;但中断使能位只有一个EPCA0(EIE1.3)

使用特权

评论回复
6
ayb_ice| | 2013-9-16 13:27 | 只看该作者
本帖最后由 ayb_ice 于 2013-9-16 13:39 编辑
若是射手 发表于 2013-9-16 12:52
每个通道都有一个中断标志位,CCF0~CCF5;但中断使能位只有一个EPCA0(EIE1.3)


无语了

未命名.JPG (23.67 KB )

未命名.JPG

未命名.JPG (23.67 KB )

未命名.JPG

使用特权

评论回复
7
若是射手|  楼主 | 2013-9-16 13:38 | 只看该作者
ayb_ice 发表于 2013-9-16 13:27
无语了

:L  数据手册看十几遍了,还是不明白,请前辈 细说点

使用特权

评论回复
8
ayb_ice| | 2013-9-16 13:41 | 只看该作者
若是射手 发表于 2013-9-16 13:38
数据手册看十几遍了,还是不明白,请前辈 细说点

骗人也要像点嘛,还看了十几遍了

使用特权

评论回复
9
若是射手|  楼主 | 2013-9-16 13:43 | 只看该作者
ayb_ice 发表于 2013-9-16 13:27
无语了

谢前辈   明白了   ECCFn  

使用特权

评论回复
10
受不了了| | 2013-9-16 13:45 | 只看该作者
ayb_ice 发表于 2013-9-16 13:41
骗人也要像点嘛,还看了十几遍了

;P第一次用也是稀里糊涂的,不过我好像至今也没看过十几遍。这个PCA需要很多个机关来负责

使用特权

评论回复
11
若是射手|  楼主 | 2013-9-16 13:51 | 只看该作者
ayb_ice 发表于 2013-9-16 13:41
骗人也要像点嘛,还看了十几遍了

不懂 就是不懂 应该是我比较笨  看了那么多遍 ,没看懂,,但是前辈我绝对没骗人  绝对;很感谢你前辈  

使用特权

评论回复
12
laoxu| | 2013-9-17 08:03 | 只看该作者
笨鸟先飞嘛,呵呵。。。 ;P

使用特权

评论回复
13
tergy2012| | 2013-9-17 11:31 | 只看该作者
路过学习的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

25

帖子

0

粉丝