导航: 老古网老古论坛XMOS公共讨论区XMOS开源项目区单片机程序设计嵌入式系统广告区域
→C51编程:救命!CYGNAL C8051单片机通信2/3

* 2356: C51编程:救命!CYGNAL C8051单片机通信2/3

   AbrahamGwang 
AbrahamGwang发表的帖子 

 C51编程:救命!CYGNAL C8051单片机通信2/3

请教古班主和各路高手有关CYGNAL C8051F000 单片机与PC 通信的问题, 
请解答讨论。

新近购置一台CYGNAL C8051F000单片机,感觉的确设计不俗。阅读
MANUAL 后, 发现其内置晶振可以由软件设定为2MHZ,4MHZ, 
8MHZ,16MHZ。
同时也可以外接11.059200MHZ,18.432MHZ的晶振。

我想用9600,8,N,1的参数与PC通信,不知道如何编程,CYGNAL C8051F000
单片机的编程指令,是否与普通8051单片机指令相兼容?

曾经采用普通8031单片机,用以下语句,通信(6MHZ晶振,2400,8,N,1)成功:

------------------------------------------------*/
#ifndef MONITOR51
    SCON  = 0x50;            /* SCON: mode 1, 8-bit 
UART, enable rcvr      */
    TMOD  = 0x20;                   /* TMOD: timer 1, mode 2, 8-bit 
reload        */
    PCON  = 0x80;                   /* PCON: Power control frequency 
double       */
        TH1   = 0xf3;            /* 2400 bps, 
TH1:  reload value /6MHz          */
    TL1   = 0xf3;    
    TR1   = 1;                      /* TR1:  timer 1 run                          */
    TI    = 1;                      /* TI:   set TI to send  first char of UART    */
#endif 
------------------------------------------------*/
)
不知道是否可以如法炮制到CYGNAL系统?另外用TH1 RELOAD value 公
式TH1=256 - 2fosc/(384 X bps) [SMOD=1时];
TH1=256 - fosc/(384 X bps) [SMOD=0时], 采用11.0592MHZ晶振,
9600,8,N,1的参数, 计算得TH1=250 [SMOD=1时];
TH1=253 [SMOD=0时];
上述公式是否适用于晶振为2MHZ,4MHZ, 8MHZ,16MHZ? 菜鸟本人不
明白用上述晶振, CYGNAL系统怎样与PC通信?
以下是CYGNAL 公司提供的Keil C51通信范例AN015SW 2/3部分(因帖子有
16K限制,不能一次发完,故分为3部分), 愚夫难以应用, 敬请高手指教。

//---------------------------------------------------------------------------------------
// POLLED_TEST: SW_UART Polled Mode Test
// Test code to transmit and receive 15 characters to/from the HW_UART, with 
SW_UART
// in polled mode.
// - Initializes and enables the SW_UART & HW_UART
// - Clears all test variables & counters
// - Sends 15 characters from the HW_UART to be received by SW_UART.
// - Sends 15 characters from the SW_UART to be received by the HW_UART.
//
void POLLED_TEST(void){

    SW_UART_INIT();                
                    // Initialize 
SW_UART
    SW_UART_ENABLE();                
                    // Enable 
SW_UART
    SREN = 1;                    
                        // 
Enable SW_UART Receiver
    SES=0;                    
                        
    // Disable user-level interrupt support.

    HWU_INIT();                
                        
    // Configure HW_UART for testing routine.
    k=m=0;                    
                        
    // Clear test counter variables.
    HW_DONE=0;                
                        
    // Clear transfer complete indicators
    SW_DONE=0;                
                        
    //
    IE |= 0x10;                    
                        // 
Enable HW_UART interrupts.

   TI = 1;                                   // Initiate a HW_UART transmit
                                             // by forcing TX interrupt.

    // Receive 15 characters with SW_UART; transmit with HW_UART.
    while(SREN){                              // Run while SW_UART Receiver is
                                             // enabled.    
        if (SRI){                
                        // 
If Receive Complete:
            SRI = 0;            
                        
    // Clear receive flag.
            SW_BUF[k++] = RDR;        
                // Read receive buffer.
            if (k==15){            
                        // 
If 15 characters have been received:
                SREN = 0;        
                        // 
Disable SW_UART Receiver.
            }            
                        
            // Indicate 15 characters received.
        }
    }

    // Transmit 15 characters with SW_UART; receive with HW_UART.
    while(STXBSY);                
                        // 
Poll Busy flag.
   STXBSY = 1;                               // Claim SW_UART Transmitter
    TDR=m++;                    
                        
    // Load TX data.
    CCF1=1;                    
                        
    // Initiate first SW_UART TX
                        
                        
            // by forcing a PCA module 1 interrupt.
    while(!SW_DONE){                
                    // SW_UART 
transmitting here; HW_UART receiving.

        if (STI){                
                        // 
If Transmit Complete:
            STI = 0;            
                        
    // Clear transmit flag.
            if (m<16){            
                        // 
Transmit 15 characters.
                STXBSY = 1;                      // 
Claim SW_UART Transmitter.
            TDR = m++;                    
            // Transmit, increment variable.
                CCF1 = 1;        
                        // 
Force module 1 interrupt to initiate TX.
            }
         else                        
                    // If this is 15th 
character,
                SW_DONE=1;    
                        
    // Indicate last character transmitted.
        }
    }
}

//------------------------------------------------------------------------------------------
// HWU_INIT: HW_UART Initialization Routine
// Sets up HW_UART for use in SW_UART testing.
// - HW_UART in mode 1
// - Timer 1 used as baud rate source, clocked by SYSCLK.
//
void HWU_INIT(void) {

    PCON |= 0x80;                
                        // 
SMOD=1 (HW_UART uses Timer 1 overflow
                        
                        
            // with no divide down).

    TMOD = 0x20;                
                        // 
Configure Timer 1 for use by HW_UART
    CKCON |= 0x10;                
                        // 
Timer 1 derived from SYSCLK
    TH1 = -HW_TIME_COUNT;            
                // Timer 1 initial value
    TL1 = -HW_TIME_COUNT;            
                // Timer 1 reload value

    TR1 = 1;                        
                    // Start Timer 1

    RI=0;                    
                        
        // Clear HW_UART receive and transmit
    TI=0;                    
                        
        // complete indicators.

    SCON = 0x50;                
                        // 
Configure HW_UART for mode 1, receiver enabled.
}
//------------------------------------------------------------------------------------------
// SW_UART_INIT: SW_UART initialization routine
// Prepares SW_UART for use.
// - Configures PCA: Module 0 in negative capture mode; module 1 in software 
//       timer mode; PCA time base = SYSCLK/4; PCA interrupt disabled; 
PCA counter
//        disabled.
// - Clears pending PCA module 0 and 1 interrupts
// - Resets TX and RX state variables
//
void    SW_UART_INIT(void){

    PCA0CPM0 = 0x10;                
                    // Module 0 in 
negative capture mode; module
                        
                        
            // 0 interrupt disabled.

    PCA0CPM1 = 0x48;                 
                    // Module 1 in 
software timer mode; module
                        
                        
            // 1 interrupt disabled.    

    PCA0CN = 0;                
                        
    // Leave PCA disabled
    PCA0MD = 0x02;                
                        // 
PCA timebase = SYSCLK/4; PCA counter
                        
                        
            // interrupt disabled.

    CCF0 = 0;                    
                        // 
Clear pending PCA module 0 and
    CCF1 = 0;                    
                        // 
module 1 capture/compare interrupts.

    SRI = 0;                    
                        
    // Clear Receive complete flag.
    STI = 0;                    
                        
    // Clear Transmit complete flag.

   SW_TX = 1;                    
                        // 
TX line initially high.    
    STXBSY = 0;                
                        
    // Clear SW_UART Busy flag

}


………………………………………………………………………………………
…………………………………………………

//------------------------------------------------------------------------------------------
// SW_UART_ENABLE: SW_UART Enable Routine
// Enables SW_UART for use.
// - Enables PCA module 0 interrupts
// - Enables PCA module 1 interrupts
// - Starts PCA counter.
//
void    SW_UART_ENABLE(void){
    
    PCA0CPM0 |= 0x01;                
                    // Enable 
module 0 (receive) interrupts.
    PCA0CPM1 |= 0x01;                
                    // Enable 
module 1 (transmit) interrupts.

    CR = 1;                    
                        
    // Start PCA counter.
    EIE1 |= 0x08;                
                        // 
Enable PCA interrupts
    EA = 1;                    
                        
    // Globally enable interrupts

}

//------------------------------------------------------------------------------------
// Interrupt Service Routines
//------------------------------------------------------------------------------------
//
// PCA_ISR: PCA Interrupt Service Routine.
// This ISR is triggered by both transmit and receive functions, for each bit that
// is transmitted or received. 
// - Checks module 0 interrupt flag (CCF0); if set, services receive state.
// - Checks module 1 interrupt flag (CCF1); if set, services transmit state.
//
void    PCA_ISR(void) interrupt 9 {

    static char     SUTXST = 0;            
            // SW_UART TX state variable
    static char     SURXST = 0;            
            // SW_UART RX state variable
    static unsigned char     RXSHIFT;            
    // SW_UART RX Shift Register
    
    unsigned int    PCA_TEMP;            
            // Temporary storage variable for
                        
                        
            // manipulating PCA module high & low 
bytes.    

    // Check receive interrupt flag first; service if CCF0 is set.
    if (CCF0){
        CCF0 = 0;                
                        // 
Clear interrupt flag.
        switch (SURXST){
            
            // State 0: START bit received.
            // In this state, a negative edge on SW_TX 
has caused the interrupt,
            // meaning a START has been detected and 
the PCA0CP0 registers have 
            // captured the value of PCA0.
            // - Check for receive enable and good 
START bit
            // - Switch PCA module 0 to software 
timer mode
            // - Add 3/2 bit time to module 0 capture 
registers to sample LSB.
            // - Increment RX state variable.
            case 0:
                if (SREN & ~SW_RX){    
                // Check for receive enable 
and a good
                        
                        
            // START bit.  
                        
                        
                
                    PCA_TEMP = 
(PCA0CPH0 << 8);    // Read module 0 contents into
                    PCA_TEMP |= 
PCA0CPL0;            // PCA_TEMP.

                    PCA_TEMP 
+= TH_TIME_COUNT;        // Add 3/2 bit times to PCA_TEMP

                    PCA0CPL0 = 
PCA_TEMP;                // Restore 
PCA0CPL0 and PCA0CPH0
                    PCA0CPH0 = 
(PCA_TEMP >> 8);    // with the updated value

                    PCA0CPM0 = 
0x49;                    // Change 
module 0 to software
                        
                        
            // timer mode, interrupts enabled.

                    SURXST++;    
                        // 
Update RX state variable.
                }
                break;
            
            // States 1-8: Bit Received
            // - Sample SW_RX pin
            // - Shift new bit into RXSHIFT
            // - Add 1 bit time to module 0 capture 
registers
            // - Increment RX state variable
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
            case 8:
                    
                RXSHIFT = RXSHIFT >> 1;
                // Shift right 1 bit
                if (SW_RX)        
                        // 
If SW_RX=1, 
                    RXSHIFT |= 
0x80;                    // shift '1' into 
RXSHIFT msb
                
                PCA_TEMP = (PCA0CPH0 
<< 8);        // Read module 0 contents into
                PCA_TEMP |= PCA0CPL0;
                // PCA_TEMP.

                PCA_TEMP += 
TIME_COUNT;                // Add 1 bit 
time to PCA_TEMP

                PCA0CPL0 = PCA_TEMP;
                    // Restore 
PCA0CPL0 and PCA0CPH0
                PCA0CPH0 = (PCA_TEMP 
>> 8);        // with the updated value
                
                SURXST++;        
                        // 
Update RX state variable.
                break;

            // State 9: 8-bits received, Capture STOP 
bit.
            // - Move RXSHIFT into RDR.
            // - Set SRI (indicate receive complete).
            // - Prepare module 0 for next transfer.
            // - Reset RX state variable.
            // - Trigger IE7 if user-level interrupt 
support is enabled.
            case 9:

                RDR = RXSHIFT;    
                        // 
Move received data to receive register.
                SRI = 1;        
                        
    // Set receive complete indicator.

                PCA0CPM0 = 0x11;    
                    // Switch 
module 0 to negative capture
                        
                        
            // mode; interrupt enabled for START
                        
                        
            // detection.

                SURXST = 0;    
                        
    // Reset RX state variable.

                if (SES){        
                        // 
If user-level interrupt support enabled
                    EIE2 |= 0x20;
                        // 
Enable IE7.
                    PRT1IF |= 
0x80;                    // Trigger IE7.
                }
                break;
                
            }
        }
        


发表时间:2001年11月4日12:03:00

  
回复该帖

本主题共有 1 帖,分页:>>>>>该主题的所有内容[1]条

 *树形目录 只列出部分跟帖的标题以及简单的摘要信息 该主题的部分跟帖如下:

[上一篇帖子]:C51编程:救命!CYGNAL C8051单片机通信3/3请教古班主和各路高手有关CYGN
[下一篇帖子]:硬件:老古请看仿真器的问题没有解决,程序编译、Load完后,全速运行的Run菜单一直是处于灰色状态。