📄 uart.c
字号:
/******************************************************
File name: uart.c
Description:
Current version: V1.00.00
Author: Liu Zheng
The latest modified data:
Replacement version:V1.1
Author:WangRD
The latest modified data:2006-7-11 22:03
CPU type: M30263F8
Copyright Renesas System Solutions (Beijing) Co.,Ltd
******************************************************/
#ifdef M_Slave
#include "sfr26a.h"
#include "typedefine.h"
#define UARTVAL (1)
#include "uart.h"
/******************************************************
Function Description:
Initiate UART and related timerA4 and pins
Input parameters: void
Output parameters:
Return value: void
******************************************************/
#define RXD_PORT p7_0
#define RXD_PORT_DIR pd7_0
void InitUart (void)
{
RXD_PORT_DIR = 0;// rxd input
u2brg = 0x33; //M_FOSC/8/16/M_Baud - 1;
u2mr = 0x05; // UART: 8 bit, 1 stop bit, no parity
u2c0 = 0x19; // f8sio is selected, CTS/RTS disable,CMOS output,falling edge output,LSB first,
// u2c1 = 0x02; // no mean
s2ric = 0x00; // disable UART receive interrupt
s2tic = 0x00; // disable UART transmit interrupt
re_u2c1 = 1; // enable UART reception
te_u2c1 = 0; // disable UART transmission
ucon = 0;
}
/******************************************************
Function Description:
Wait for new data
Transmit data
Input parameters: void
Output parameters:
Return value: void
******************************************************/
void CheckUart (void)
{
//CheckError(); // Find first data of a frame
if( true == s_TxdFlag) // Txd sub-routine
{
TxdUart(); // UART0 transmit sub-routine
}
else // Rxd sub-routine
{
if ( false == s_RxdTxdSwDelay )
{
switch(RxdUart()) // error handle reserved
{
case 'N': // no new data
break;
case 'F': // frame verify error
break;
case 'S': // source address error
break;
case 'D': // dest address error
break;
case 'V': // check sum error
break;
case 'C': // frame receive completed
break;
}
}
else
{
if ( 0 == s_RxdTxdSwTim )
{
te_u2c1 = 1; // enable UART0 transmission
s_TxdFlag = true; // ready to transmit
s_RxdTxdSwTim = M_RxdTxdDelay;
s_RxdTxdSwDelay = false;
}
else
{
s_RxdTxdSwTim --;
}
}
}
}
/******************************************************
Function Description:
Check whether timeout
Input parameters: void
Output parameters:
Return value: void
******************************************************/
void CheckError(void)
{
//if(ir_tb2ic) // 10ms timeout
//{
// ir_tb0ic = 0; // clear timer B0 overflow flag
if(s_100msCnt < M_FraIntval1) // if time check < 100ms
{
s_100msCnt ++; // 100ms counter ++
}
if(s_30sCnt < M_ErrIntval) // if time check < 30s
{
s_30sCnt ++;// 30s error counter ++
g_ErrFlag = false;
}
else
{
g_ErrFlag = true; // set communication error flag
g_TxdDat[3] = M_ErrUart;
s_30sCnt = 0; // reset 30s error counter
}
//}
}
/******************************************************
Function Description:
Receive data from upper PC
Judge the error type
Input parameters: void
Output parameters:
Return value: UINT_8
'N': no new data received
'E': frame error (detected by hardware)
'W': one data received successfully, wait for next
'V': check sum is not correct
'C': valid command receive completed, no error
******************************************************/
static UINT_8 RxdUart(void)
{
static T_UARTSTEPS s_RxdStep = SrcAddr;// receive step
static UINT_8 s_RxdCnt;// receive counter
static UINT_8 s_RxdChkSum;
UINT_8 t_TempRxd; // temp receive buffer
if(ri_u2c1) // new data received
{ // store data
if(s_100msCnt >= M_FraIntval1)
{
s_RxdStep = SrcAddr;
}
s_100msCnt = 0; // clear 100ms counter
if( 0 == (u2rbh&0xf8) )// no frame error?
{
t_TempRxd = u2rbl; // clear high 8 bit of receive data
switch(s_RxdStep)
{
case SrcAddr:
if(t_TempRxd == M_SrcAddr) // source address correct?
{
s_RxdComFrm.SrcAddr = M_SrcAddr;
s_RxdStep = TarAddr; // next step
}
else
{
s_RxdStep = SrcAddr;
return 'S'; // source address error
}
break;
case TarAddr:
if(t_TempRxd == M_TarAddr) // target address correct?
{
s_RxdComFrm.TarAddr = M_TarAddr;
s_RxdStep = Cmd; // next step
}
else
{
s_RxdStep = SrcAddr; // reset step
return 'T'; // target address error
}
break;
case Cmd:
s_RxdComFrm.Cmd = t_TempRxd; // judge command
switch(s_RxdComFrm.Cmd)
{
case C_Ini: // initiate command
s_RxdComFrm.DataHdPt = s_RxdIniData;
break;
case C_Dat: // speed command
s_RxdComFrm.DataHdPt = s_RxdDat;
break;
case C_Err0: // bus command
s_RxdComFrm.DataHdPt = s_RxdErr0; // pointer != NULL?
break;
case C_Err1: // phase command
s_RxdComFrm.DataHdPt = s_RxdErr1; // pointer != NULL?
break;
case C_HtCmd: // temperature command
s_RxdComFrm.DataHdPt = s_RxdHtCmd; // pointer != NULL?
break;
default: // duty command
s_RxdComFrm.DataHdPt = NULL; // pointer != NULL?
break;
}
s_RxdStep = DataLen; // next step
break;
case DataLen:
s_RxdComFrm.DataLen = t_TempRxd; // store data length
// if(s_RxdComFrm.DataLen > 0) // data > 0
// {
s_RxdStep = DataHd; // next step
// }
// else // no data
// {
// s_RxdComFrm.DataHdPt = NULL; // clear pointer
// s_RxdStep = ChkSum; // go check sum
// }
s_RxdCnt = 0; // clear receive counter
break;
case DataHd:
if(s_RxdCnt < s_RxdComFrm.DataLen) // data
{
if(s_RxdComFrm.DataHdPt != NULL) // pointer != NULL?
{
* (s_RxdComFrm.DataHdPt + s_RxdCnt) = t_TempRxd;
}
s_RxdCnt ++; // receive counter ++
s_RxdStep = DataHd; // still data
}
else
{
if(s_RxdComFrm.DataHdPt != NULL) // pointer != NULL?
{
* (s_RxdComFrm.DataHdPt + s_RxdCnt) = t_TempRxd;
}
s_RxdCnt = 0; // clear receive counter
s_RxdStep = ChkSum; // next step
}
break;
case ChkSum:
s_RxdComFrm.ChkSum = t_TempRxd; // store check sum
s_RxdStep = SrcAddr;
if ( true == CheckSum(&s_RxdComFrm,&s_RxdChkSum))
{
if( s_RxdChkSum == (256 - s_RxdComFrm.ChkSum) ) // check sum correct?
{
s_RxdComFrm.DataHdPt = NULL; // clear pointer
UpdateData(); // update receive data and prepare transmint
re_u2c1 = 0; // disable UART0 reception
s_RxdTxdSwDelay = true;
s_30sCnt = 0; // clear 30s error counter
return 'C';
}
else
{
s_RxdComFrm.DataHdPt = NULL; // clear pointer
return 'V';
}
}
else
{
s_RxdComFrm.DataHdPt = NULL; // clear pointer
return 'V';
}
break;
}
return 'N'; // no error and next step
}
re_u2c1 = 0; // clear error flags of UART0
re_u2c1 = 1;
s_RxdStep = 0; // reset receive step
return 'F'; // frame error
}
return 'N'; // no new data
}
/******************************************************
Function Description:
Calculate check sum
Input parameters: T_COMFRAME *
T_ComFrmPt: pointer of buffer
Output parameters:
Return value: Sum of input buffer
******************************************************/
static BOOLEAN CheckSum(T_COMFRAME * const ComFrmPt, UINT_8 * const ChkSumAddr)
{ // clear check sum
UINT_8 t_TempCnt;
if ( NULL == ComFrmPt)
{
return (false);
}
else
{
* ChkSumAddr = 0;
t_TempCnt = 0; // temp counter
* ChkSumAddr += ComFrmPt -> SrcAddr; // add source address to check sum
* ChkSumAddr += ComFrmPt -> TarAddr; // add target address to check sum
* ChkSumAddr += ComFrmPt -> Cmd; // add command to check sum
* ChkSumAddr += ComFrmPt -> DataLen; // add data length to check sum
for(t_TempCnt = 0; t_TempCnt <= (ComFrmPt -> DataLen); t_TempCnt ++)
{
* ChkSumAddr += *(ComFrmPt -> DataHdPt + t_TempCnt); // add data to check sum
}
return (true);
}
}
/******************************************************
Function Description:
Update data received
Prepare data transmitted
Input parameters: void
Output parameters:
Return value: void
******************************************************/
const UINT_8 TxdIniData[M_TxdIniData] = {0x10, 0x15, 0x00, 0x02};
static void UpdateData (void)
{
UINT_8 t_TempCnt = 0;
s_TxdComFrm.SrcAddr = M_TarAddr; // exchange source address and target address
s_TxdComFrm.TarAddr = M_SrcAddr;
s_TxdComFrm.Cmd = s_RxdComFrm.Cmd; // prepare command
switch(s_TxdComFrm.Cmd)
{
case C_Ini: // initiate command
s_TxdComFrm.DataLen = M_TxdIniData - 1;
s_TxdComFrm.DataHdPt = s_TxdIniData;
for(t_TempCnt = 0; t_TempCnt < M_RxdIniData; t_TempCnt ++)
{
g_RxdIniData[t_TempCnt] = s_RxdIniData[t_TempCnt];
s_RxdIniData[t_TempCnt] = 0;
}
for(t_TempCnt = 0; t_TempCnt < M_TxdIniData; t_TempCnt ++)
{
s_TxdIniData[t_TempCnt] = TxdIniData[t_TempCnt];
}
break;
case C_Dat: // speed command
s_TxdComFrm.DataLen = M_TxdDat - 1;
s_TxdComFrm.DataHdPt = s_TxdDat;
for(t_TempCnt = 0; t_TempCnt < M_RxdDat; t_TempCnt ++)
{
g_RxdDat[t_TempCnt] = s_RxdDat[t_TempCnt];
s_RxdDat[t_TempCnt] = 0;
}
g_TxdDat[0] = g_RxdDat[0];
for(t_TempCnt = 0; t_TempCnt < M_TxdDat; t_TempCnt ++)
{
s_TxdDat[t_TempCnt] = g_TxdDat[t_TempCnt];
}
s_TxdDat[2] = 50;
s_TxdDat[4] = 0x59;
break;
case C_Err0: // bus command
s_TxdComFrm.DataLen = M_TxdErr0 - 1;
s_TxdComFrm.DataHdPt = s_TxdErr0;
for(t_TempCnt = 0; t_TempCnt < M_RxdErr0; t_TempCnt ++)
{
g_RxdErr0[t_TempCnt] = s_RxdErr0[t_TempCnt];
s_RxdErr0[t_TempCnt] = 0;
}
for(t_TempCnt = 0; t_TempCnt < M_TxdErr0; t_TempCnt ++)
{
s_TxdErr0[t_TempCnt] = g_TxdErr0[t_TempCnt];
}
if( 0x5a == g_RxdErr0[0] )
{
g_TxdDat[3] = 0;
s_TxdErr0[0] = 0xa5;
g_RxdDat[0] = 0; /*target speed equals zero */
}
break;
case C_Err1: // phase command
s_TxdComFrm.DataLen = M_TxdErr1 - 1;
s_TxdComFrm.DataHdPt = s_TxdErr1;
for(t_TempCnt = 0; t_TempCnt < M_RxdErr1; t_TempCnt ++)
{
g_RxdErr1[t_TempCnt] = s_RxdErr1[t_TempCnt];
s_RxdErr1[t_TempCnt] = 0;
}
for(t_TempCnt = 0; t_TempCnt < M_TxdErr1; t_TempCnt ++)
{
s_TxdErr1[t_TempCnt] = g_TxdErr1[t_TempCnt];
}
if( 0x5a == g_RxdErr1[0] )
{
g_TxdDat[3] = 0;
s_TxdErr1[0] = 0xa5;
g_RxdDat[0] = 0;
}
break;
case C_HtCmd: // temperature command
s_TxdComFrm.DataLen = M_TxdHtCmd - 1;
s_TxdComFrm.DataHdPt = s_TxdHtCmd;
for(t_TempCnt = 0; t_TempCnt < M_RxdHtCmd; t_TempCnt ++)
{
g_RxdHtCmd[t_TempCnt] = s_RxdHtCmd[t_TempCnt];
s_RxdHtCmd[t_TempCnt] = 0;
}
for(t_TempCnt = 0; t_TempCnt < M_TxdHtCmd; t_TempCnt ++)
{
s_TxdHtCmd[t_TempCnt] = g_TxdHtCmd[t_TempCnt];
}
break;
default: // duty command
s_TxdComFrm.DataLen = 0;
s_TxdComFrm.DataHdPt = NULL;
// for(t_TempCnt = 0; t_TempCnt < M_TxdDutyData; t_TempCnt ++)
// {
// s_TxdDutyData[t_TempCnt] = 0;
// }
break;
}
CheckSum(&s_TxdComFrm, &s_TxdComFrm.ChkSum); // calculate check sum
s_TxdComFrm.ChkSum = 256 - s_TxdComFrm.ChkSum;
}
/******************************************************
Function Description:
Transmit data in transmit buffer
Input parameters: void
Output parameters:
Return value: void
******************************************************/
static void TxdUart (void)
{
static T_UARTSTEPS s_TxdStep = SrcAddr; // transmit step
static UINT_8 s_TxdCnt = 0; // transmit counter
if(ti_u2c1) // transmit buffer empty?
{
switch(s_TxdStep)
{
case SrcAddr: // send source address
u2tbl = s_TxdComFrm.SrcAddr;
s_TxdStep = TarAddr; // next step
break;
case TarAddr: // send target address
u2tbl = s_TxdComFrm.TarAddr;
s_TxdStep = Cmd; // next step
break;
case Cmd: // send command
u2tbl = s_TxdComFrm.Cmd;
s_TxdStep = DataLen; // next step
break;
case DataLen: // send data length
u2tbl = s_TxdComFrm.DataLen;
s_TxdCnt = 0; // clear transmit counter
s_TxdStep = DataHd; // next step
break;
case DataHd: // send data
if(s_TxdCnt < s_TxdComFrm.DataLen)
{
if(s_TxdComFrm.DataHdPt != NULL) // store pointer != NULL?
{
u2tbl = * (s_TxdComFrm.DataHdPt + s_TxdCnt);
}
s_TxdCnt ++; // transmit counter ++
s_TxdStep = DataHd; // still data
}
else
{
if(s_TxdComFrm.DataHdPt != NULL) // store pointer != NULL?
{
u2tbl = * (s_TxdComFrm.DataHdPt + s_TxdCnt);
}
s_TxdComFrm.DataHdPt = NULL;
s_TxdCnt = 0; // clear transmit counter
s_TxdStep = ChkSum; // next step
}
break;
case ChkSum: // send check sum
u2tbl = s_TxdComFrm.ChkSum;
s_TxdStep = End; // next step
break;
case End: // wait shift buffer empty
if(txept_u2c0)
{
te_u2c1 = 0; // disable transmission
re_u2c1 = 1; // enable reception
s_TxdFlag = false;
s_TxdStep = SrcAddr; // reset step
}
else
{
s_TxdStep = End; // wait loop
}
break;
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -