新近购置一台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;
}
}