打印

C8051串口返回值问题

[复制链接]
1761|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
blackeye47|  楼主 | 2012-8-2 09:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <compiler_defs.h>
#include <C8051F500_defs.h>            // SFR declarations
#include <stdio.h>
//-----------------------------------------------------------------------------
// Global CONSTANTS
//-----------------------------------------------------------------------------
#define SYSCLK      24000000           // SYSCLK frequency in Hz
#define BAUDRATE      115200           // Baud rate of UART in bps
#define MESSAGE_OBJECTS    32          // Number of message objects to use
                                       // Range is 1-32
#define MESSAGE_SIZE        8          // Size in bytes of each CAN message
                                       // Range is 1-8           
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
U8 UART_Buffer_Size=0;
U8 TX_Ready = 1;
U8 UART_Buffer[10];
U8 TER_ter=0;
static U8 Byte;
//-----------------------------------------------------------------------------
// Bit Definition Masks
//-----------------------------------------------------------------------------
// CAN0STAT
#define BOff  0x80                     // Busoff Status
#define EWarn 0x40                     // Warning Status
#define EPass 0x20                     // Error Passive
#define RxOk  0x10                     // Receive Message Successfully
#define TxOk  0x08                     // Transmitted Message Successfully
#define LEC   0x07                     // Last Error Code
//-----------------------------------------------------------------------------
// Pin Definitions
//-----------------------------------------------------------------------------
//SBIT (LED, SFR_P1, 3);                 // LED = 1 turns on the LED
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
bit CAN_ERROR = 0;                     // 0 = No Errors during transmission
                                       // 1 = Some error(s) occurred
//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void);
void UART0_Init (void);
void PORT_Init (void);
void CAN0_Init (void);
void CAN0_TransferMO (U8 obj_num);
void *memset(void *s,int c,size_t n);
INTERRUPT_PROTO (UART0_ISR, INTERRUPT_UART0);
//INTERRUPT_PROTO (CAN0_ISR, INTERRUPT_CAN0);
//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------
void main (void)
{
   // U8 SFRPAGE_save;
   SFRPAGE = ACTIVE_PAGE;              // Change for PCA0MD
   PCA0MD &= ~0x40;                    // Disable watchdog timer
   OSCILLATOR_Init ();                 // Initialize Oscillator
   PORT_Init ();                       // Initialize Port I/O
   UART0_Init ();                      // Initialize UART
   CAN0_Init ();        // Start CAN peripheral
   EIE2 |= 0x02;                       // Enable CAN interupts
   EA = 1;                             // Enable global interrutpts
   memset(UART_Buffer,0,10*sizeof(U8));
//   putchar('A');
   while (1)
   {
      // If the complete word has been entered via the terminal followed by
      // carriage return
      if((TX_Ready == 1) && (UART_Buffer_Size != 0) && (Byte == 35))
      {  
      TER_ter++;
         TX_Ready = 0;                 // Set the flag to zero
         TI0 = 1;                     
   if(TER_ter>5)
   {
      TER_ter=0;
   }
   CAN0_TransferMO (TER_ter);
  // SFRPAGE_save = SFRPAGE;
  // SFRPAGE = CAN0_PAGE;
        // while (CAN0TR1 | CAN0TR2)
        // {
        //    LED = !LED;
        //    for (iter = 0; iter < 6500; iter++);   
        // }
  // SFRPAGE=SFRPAGE_save;
      }
     // if (CAN_ERROR)
     // {                                   // If any errors occurred
     //   LED = 1;                         // Turn off LED
     // }                       
     // else
     // {
     //   LED = 0;                         // No error, so keep LED on
     // }
   }
}
//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
   U8 SFRPAGE_save = SFRPAGE;
   SFRPAGE = CONFIG_PAGE;
   OSCICN |= 0x87;                     // Configure internal oscillator for
                                       // its maximum frequency
   RSTSRC  = 0x04;                     // Enable missing clock detector
   SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
   U8 SFRPAGE_save = SFRPAGE;
   SFRPAGE = CONFIG_PAGE;
   SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
                                       // clear RI0 and TI0 bits
   // Baud Rate = [BRG Clock / (65536 - (SBRLH0:SBRLL0))] x 1/2 x 1/Prescaler
#if   ((SYSCLK / BAUDRATE / 2 / 0xFFFF) < 1)
      SBRL0 = -(SYSCLK / BAUDRATE / 2);
      SBCON0 |= 0x03;                  // Set prescaler to 1
#elif ((SYSCLK / BAUDRATE / 2 / 0xFFFF) < 4)
      SBRL0 = -(SYSCLK / BAUDRATE / 2 / 4);
      SBCON0 &= ~0x03;
      SBCON0 |= 0x01;                  // Set prescaler to 4
#elif ((SYSCLK / BAUDRATE / 2 / 0xFFFF) < 12)
      SBRL0 = -(SYSCLK / BAUDRATE / 2 / 12);
      SBCON0 &= ~0x03;                 // Set prescaler to 12
#else
      SBRL0 = -(SYSCLK / BAUDRATE / 2 / 48);
      SBCON0 &= ~0x03;
      SBCON0 |= 0x02;                  // Set prescaler to 48
#endif
   SBCON0 |= 0x40;                     // Enable baud rate generator
   ES0 = 1;                            // Enable UART0 interrupts
   TX_Ready = 1;                            // Indicate TX0 ready
   TI0 = 0;
   SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters   : None
//
// Configure the Crossbar and GPIO ports.
//
// P0.4   digital   push-pull    UART TX
// P0.5   digital   open-drain   UART RX
// P0.6   digital  push-pull        CAN TX
// P0.7   digital  open-drain       CAN RX
//
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
   U8 SFRPAGE_save = SFRPAGE;
   SFRPAGE = CONFIG_PAGE;
   P0MDOUT |= 0x50;                    // Enable UTX and CAN_TX as push-pull output
  // P1MDOUT |= 0x08;                   // P1.3 (LED) is push-pull
   XBR0    = 0x03;                     // Enable UART on P0.4(TX) and P0.5(RX) CAN_TX, CAN_RX routed to Port pins P0.6 and P0.7.
   XBR2    = 0x40;                     // Enable crossbar and weak pull-ups
   SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// CAN0_Init
//-----------------------------------------------------------------------------
void CAN0_Init (void)
{
   U8 iter;
   U8 SFRPAGE_save = SFRPAGE;
   SFRPAGE  = CAN0_PAGE;               // All CAN register are on page 0x0C
   CAN0CN |= 0x01;                     // Start Intialization mode
   //---------Initialize general CAN peripheral settings
   CAN0CN |= 0x4E;                     // Enable Status, Error,
                                       // Module Interrupts
                                       // Enable access to bit timing register
   // See the CAN Bit Timing Spreadsheet for how to calculate this value
   CAN0BT = 0x1402;                    // Based on 24 Mhz CAN clock, set the
                                       // CAN bit rate to 1 Mbps
   //---------Initialize settings common to all message objects
   // Command Mask Register
   CAN0IF1CM = 0x00F0;                 // Write Operation
                                       // Transfer ID Mask, MDir, MXtd
                                       // Transfer ID, Dir, Xtd, MsgVal
                                       // Transfer Control Bits
                                       // Don't set TxRqst or transfer data
   // Mask Registers
   CAN0IF1M1 = 0x0000;                 // Mask Bits 15-0 not used for filtering
   CAN0IF1M2 = 0x5FFC;                 // Ignore Extended Identifier for
                                       // filtering
                                       // Used Direction bit for filtering
                                       // Use ID bits 28-18 for filtering
   // Arbitration Registers
   CAN0IF1A1 = 0x0000;                 // 11-bit ID, so lower 16-bits not used
   // Message Control Registers
   CAN0IF1MC = 0x0880 | MESSAGE_SIZE;  // Enable Transmit Interrupt
                                       // Message Object is a Single Message
                                       // Message Size set by #define
   //---------Initialize unique settings for each valid message object
   for (iter = 0; iter < MESSAGE_OBJECTS; iter++)
   {
      // For example purposes, set 11-bit identifier based on the message
      // object that is used to send it.
      // Arbitration Registers
      CAN0IF1A2 = 0xA000 | (iter << 2);  // Set MsgVal to valid
                                         // Set Direction to write
                                         // Set 11-bit Identifier to iter
      CAN0IF1CR = iter;                // Start command request
   
      while (CAN0IF1CRH & 0x80) {}       // Poll on Busy bit
   }
   //---------Initialize settings for unused message objects
   for (iter = MESSAGE_OBJECTS; iter < 32; iter++)
   {
      // Set remaining message objects to be Ignored
      CAN0IF1A2 = 0x0000;              // Set MsgVal to 0 to Ignore
      CAN0IF1CR = iter;                // Start command request
   
      while (CAN0IF1CRH & 0x80) {}     // Poll on Busy bit
   }
   CAN0CN &= ~0x41;                    // Return to Normal Mode and disable
                                       // access to bit timing register
   SFRPAGE = SFRPAGE_save;
}
//-----------------------------------------------------------------------------
// Supporting Subroutines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// CAN0_TransferMO
//-------------------------------------------------------------------------
void CAN0_TransferMO (U8 obj_num)
{
   // This function assumes that the message object is fully initialized
   // in CAN0_Init and so all it has to do is fill the data registers and
   // initiate transmission
   U8 SFRPAGE_save = SFRPAGE;
   SFRPAGE  = CAN0_PAGE;               // All CAN register are on page 0x0C
   // Initialize all 8 data bytes even though they might not be sent
   // The number to send was configured earlier by setting Message Control
   CAN0IF1DA1H = obj_num;              // Initialize data registers based
   CAN0IF1DA1L = obj_num + 1;          // on message object used
   CAN0IF1DA2H = obj_num + 2;
   CAN0IF1DA2L = obj_num + 3;           
   CAN0IF1DB1H = obj_num + 4;
   CAN0IF1DB1L = obj_num + 5;
   CAN0IF1DB2H = obj_num + 6;
   CAN0IF1DB2L = obj_num + 7;
   CAN0IF1CM = 0x0087;                 // Set Direction to Write
                                       // Write TxRqst, all 8 data bytes
   CAN0IF1CR = obj_num;                // Start command request
   
   while (CAN0IF1CRH & 0x80) {}        // Poll on Busy bit
}
//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// UART0_Interrupt
//-----------------------------------------------------------------------------
//
// This routine is invoked whenever a character is entered or displayed on the
// Hyperterminal.
//
//-----------------------------------------------------------------------------
INTERRUPT(UART0_ISR, INTERRUPT_UART0)
{
   if (RI0 == 1)
   {
      TX_Ready=1;
      RI0 = 0;                         // Clear interrupt flag
      Byte = SBUF0;                    // Read a character from UART
      UART_Buffer[UART_Buffer_Size] = Byte; // Store in array
   UART_Buffer_Size++;           // Update array's size
   }
   if (TI0 == 1)                       // Check if transmit flag is set
   {
      TI0 = 0;                         // Clear interrupt flag
   if(UART_Buffer_Size<10)
   {
       UART_Buffer_Size--;
       if (UART_Buffer[UART_Buffer_Size-1]==97)       // If buffer not empty
        {
           Byte =65;
     }
     else if(UART_Buffer[UART_Buffer_Size-1]==98)
     {
        Byte =66;
     }
     else
     {
        Byte=78;
     }
        SBUF0 = Byte;                 // Transmit to Hyperterminal
        UART_Buffer_Size = 0;          // Update counter
     memset(UART_Buffer,0,10*sizeof(U8));
  }
  else
  {
        UART_Buffer_Size=0;          // Update counter
     memset(UART_Buffer,0,10*sizeof(U8));
  }
   }
}
//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

相关帖子

沙发
blackeye47|  楼主 | 2012-8-2 09:50 | 只看该作者
我发送a#能返回A,可是为什么只返回一次,再发就不返回了,can能正常发送

使用特权

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

本版积分规则

0

主题

7

帖子

0

粉丝