📄 serial.c
字号:
/*
*******************************************************************************
**
** This device driver was created by Applilet for the 78K0/KB2, 78K0/KC2,
** 78K0/KD2, 78K0/KE2 and 78K0/KF2 8-Bit Single-Chip Microcontrollers.
**
** Copyright(C) NEC Electronics Corporation 2002 - 2005
** All rights reserved by NEC Electronics Corporation.
**
** This program should be used on your own responsibility.
** NEC Electronics Corporation assumes no responsibility for any losses
** incurred by customers or third parties arising from the use of this file.
**
** Filename : serial.c
** Abstract : This file implements device driver for SERIAL module.
** APIlib : NEC78K0KX2.lib V1.01 [09 Aug. 2005]
**
** Device : uPD78F0513(44-pin)
**
** Compiler : NEC/CC78K0
**
*******************************************************************************
*/
#pragma interrupt INTSR0 MD_INTSR0
#pragma interrupt INTST0 MD_INTST0
#pragma interrupt INTSR6 MD_INTSR6
#pragma interrupt INTST6 MD_INTST6
#pragma interrupt INTIIC0 MD_INTIIC0
/*
*******************************************************************************
** Include files
*******************************************************************************
*/
#include "macrodriver.h"
#include "serial.h"
/* uart0 transmission */
UCHAR* UART0_TX_ADDRESS; /* uart transfer buffer address */
UCHAR UART0_TX_CNT; /* uart transfer number */
/* uart0 reception */
UCHAR* UART0_RX_ADDRESS; /* uart receive buffer address */
UCHAR UART0_RX_CNT; /* uart receive data number */
/* uart6 transmission */
UCHAR* UART6_TX_ADDRESS; /* uart transfer buffer address */
UCHAR UART6_TX_CNT; /* uart transfer number */
/* uart6 reception */
UCHAR* UART6_RX_ADDRESS; /* uart receive buffer address */
UCHAR UART6_RX_CNT; /* uart receive data number */
UCHAR iic0_m_sta_flag; /* start flag for send address check by master mode */
UCHAR *iic0_m_send_pbuf; /* send data pointer by master mode */
UINT iic0_m_send_size; /* send data size by master mode */
UCHAR *iic0_m_rev_pbuf; /* receive data pointer by master mode */
UINT iic0_m_rev_size; /* receive data size by master mode */
UCHAR iic0_s_sta_flag; /* start flag for send address check by slave mode */
UCHAR *iic0_s_send_pbuf; /* send data pointer by slave mode */
UINT iic0_s_send_size; /* send data size by slave mode */
UCHAR *iic0_s_rev_pbuf; /* receive data pointer by slave mode */
UINT iic0_s_rev_size; /* receive data size by slave mode */
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function initializes UART0 module.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
void UART0_Init( void )
{
ASIM0 = 0;
SetIORBit(P1, 0x01);
ClrIORBit(PM1, 0x01); /* port setting in reception/transmission mode */
ClrIORBit(ASIM0, 0x04); /* data length 7 bits */
ClrIORBit(ASIM0, 0x02); /* stop length 1 bits */
SetIORBit(ASIM0, 0x18); /* even parity mode */
BRGC0 = UART_BAUDRATE_K0 |
(UART_BAUDRATE_M0 << 6); /* baudrate selection */
ClrIORBit(IF1L, 0x02);
ClrIORBit(MK1L, 0x02); /* receive end interrupt enable */
ClrIORBit(IF0H, 0x04);
ClrIORBit(MK0H, 0x04); /* transfer end interrupt enable */
SetIORBit(PR1L, 0x02); /* interrupt low */
SetIORBit(PR0H, 0x04); /* interrupt low */
SetIORBit(ASIM0, 0x80);
SetIORBit(ASIM0, 0x60);
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function is responsible for UART0 data transfering.
**
** Parameters:
** txbuf: transfer buffer pointer
** txnum: buffer size
**
** Returns:
** MD_OK
** MD_ERROR
**
**-----------------------------------------------------------------------------
*/
MD_STATUS UART0_SendData( UCHAR* txbuf, UCHAR txnum )
{
if( txnum < 1 ){
return MD_ERROR; /* 1 frame data at least */
}
UART0_TX_ADDRESS = txbuf;
UART0_TX_CNT = txnum;
TXS0 = *UART0_TX_ADDRESS++;
return MD_OK;
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function is responsible for UART0 data receiving.
**
** Parameters:
** rxbuf: receive buffer pointer
** rxnum: buffer size
**
** Returns:
** MD_OK
** MD_ERROR
**
**-----------------------------------------------------------------------------
*/
MD_STATUS UART0_ReceiveData( UCHAR* rxbuf, UCHAR rxnum )
{
if( rxnum < 1 ){
return MD_ERROR;
}
UART0_RX_CNT = rxnum;
UART0_RX_ADDRESS = rxbuf;
return MD_OK;
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function is the UART0 transfer end interrupt handler.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
__interrupt void MD_INTST0( void )
{
UART0_TX_CNT--;
if( UART0_TX_CNT == 0 ){
/* transmit complete */
}
else{
TXS0 = *UART0_TX_ADDRESS++;
}
return;
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function is the UART0 receive end interrupt handler.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
__interrupt void MD_INTSR0( void )
{
UCHAR err_type;
UCHAR tmp;
tmp = RXB0;
err_type = ASIS0;
if( err_type != 0 ){
/* error occured */
return;
}
if( UART0_RX_CNT == 0 ){
/* receive data end */
return;
}
/* the interrput generated by receive end */
*UART0_RX_ADDRESS++ = tmp;
UART0_RX_CNT--;
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function initializes UART6 module.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
void UART6_Init( void )
{
ASIM6 = 0;
SetIORBit(P1, 0x08); /* port setting in transmit/receive mode */
ClrIORBit(PM1, 0x08);
ClrIORBit(ASIM6, 0x04); /* data length 7 bits */
ClrIORBit(ASIM6, 0x02); /* stop length 1 bits */
SetIORBit(ASIM6, 0x01);
SetIORBit(ASIM6, 0x18); /* even parity mode */
SetIORBit(ASICL6, 0x02); /* LSB first transfer */
ClrIORBit(ASICL6, 0x01); /* normal output of TxD6 */
CKSR6 = UART_BAUDRATE_M6; /* baudrate selection */
BRGC6 = UART_BAUDRATE_K6;
ClrIORBit(IF0H, 0x02);
ClrIORBit(MK0H, 0x02); /* transfer end interrupt enable */
ClrIORBit(IF0H, 0x01);
ClrIORBit(MK0H, 0x01); /* receive end interrupt enable */
SetIORBit(PR0H, 0x01); /* interrupt low */
SetIORBit(PR0H, 0x02); /* interrupt low */
SetIORBit(ASIM6, 0x80);
SetIORBit(ASIM6, 0x60); /* transmit/receive mode */
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function is responsible for UART6 data receiving.
**
** Parameters:
** rxbuf: receive buffer pointer
** rxnum: buffer size
**
** Returns:
** MD_OK
** MD_ERROR
**
**-----------------------------------------------------------------------------
*/
MD_STATUS UART6_ReceiveData( UCHAR* rxbuf, UCHAR rxnum )
{
if( rxnum < 1 ){
return MD_ERROR;
}
UART6_RX_CNT = rxnum;
UART6_RX_ADDRESS = rxbuf;
return MD_OK;
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function is responsible for UART6 data transfering.
**
** Parameters:
** txbuf: transfer buffer pointer
** txnum: buffer size
**
** Returns:
** MD_OK
** MD_ERROR
**
**-----------------------------------------------------------------------------
*/
MD_STATUS UART6_SendData( UCHAR* txbuf, UCHAR txnum )
{
if( txnum < 1 ){
return MD_ERROR; /* 1 frame data at least */
}
UART6_TX_ADDRESS = txbuf;
UART6_TX_CNT = txnum;
if( txnum == 1) { /* only 1 frame data to transfer doesn't need contiously transfer */
if((ASIF6 & 0x02) == 0){
TXB6 = *UART6_TX_ADDRESS++;
}
else{
return MD_DATAEXISTS;
}
}
else {
if((ASIF6 & 0x02) == 0){
TXB6 = *UART6_TX_ADDRESS++;
while((ASIF6 & 0x02) == 1); /* wait */
UART6_TX_CNT--;
TXB6 = *UART6_TX_ADDRESS++;
}
else{
return MD_DATAEXISTS;
}
}
return MD_OK;
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function is the UART6 receive end interrupt handler.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
__interrupt void MD_INTSR6( void )
{
UCHAR err_type;
UCHAR tmp;
err_type = ASIS6;
tmp = RXB6;
if( err_type != 0 ){
return;
}
if( UART6_RX_CNT == 0 ){
/* receive data end */
return;
}
/* the interrut generated by receive end */
*UART6_RX_ADDRESS ++= tmp;
UART6_RX_CNT--;
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function is the UART6 transfer end interrupt handler.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
__interrupt void MD_INTST6( void )
{
if( UART6_TX_CNT == 0 ){
/* send data complete */
return;
}
if(((ASIF6 & 0x02) == 0) && ((ASIM6 & 0x80) == 0x80)){
UART6_TX_CNT--;
if( UART6_TX_CNT != 0 ){
TXB6 = *UART6_TX_ADDRESS++;
}
}
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** This function initializes IIC0 module.
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
void IIC0_Init( void )
{
ClrIORBit(IICC0, 0x80); /* stop IIC0 */
SetIORBit(MK1H, 0x1); /* disable interrupt */
ClrIORBit(PM6, 0x03); /* port setting */
ClrIORBit(P6, 0x03);
SetIORBit(IICF0, 0x02); /* start-condition doesn't need stop-condition */
SetIORBit(IICF0, 0x01); /* comunication reserve - disable */
SetIORBit(IICC0, 0x10); /* stop-condition interrupt - enable */
ClrIORBit(IICC0, 0x08); /* interrupt control - 8 clock falling edge */
/* transfer clock */
/* fprs/344 */
ClrIORBit(IICCL0, 0x08); /* normal mode */
ClrIORBit(IICCL0, 0x3); /* CL00 = 0 CL01 = 1 */
SetIORBit(IICCL0, 0x2);
ClrIORBit(IICX0, 0x1); /* disable extension */
/* selection interrupt priority */
SetIORBit(PR1H, 0x1); /* interrupt priority low */
ClrIORBit(MK1H, 0x1); /* enable interrupt */
return;
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** IIC0 interrupt service routine
**
** Parameters:
** None
**
** Returns:
** None
**
**-----------------------------------------------------------------------------
*/
__interrupt void MD_INTIIC0( void )
{
MD_STATUS sta;
if( IICS0 & 0x80 ) {
sta = IIC0_MasterHandler();
}
else {
sta = IIC0_SlaveHandler();
}
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** The function call at IIC0 interrupt request
**
** Parameters:
** None.
**
** Returns:
** MD_OK
** MD_ERROR : cannot get address
** not slave mode
** MD_SLAVE_RCV_END : all data received
** MD_SLAVE_SEND_END : all data sended
** MD_SPT : get stop condition
**
**-----------------------------------------------------------------------------
*/
MD_STATUS IIC0_SlaveHandler( void )
{
/* control for stop condition */
if( IICS0 & 0x01 ){ /* get stop condition */
/* slave send end and get stop condition */
if( iic0_s_sta_flag &&( iic0_s_send_size == 0 ) ){
return MD_SLAVE_SEND_END;
} else {
return MD_SPT;
}
}
/* control for get address */
if( iic0_s_sta_flag == 0 ){
if( !(IICS0 & 0x20) ){ /* check EXC0 -> external code */
if( IICS0 & 0x10 ){ /* check COI0 -> address */
iic0_s_sta_flag = 1;
CALL_IIC0_SlaveAddressMatch(); /* slave address match */
}
else{
return MD_ERROR;
}
}
else{
return MD_ERROR;
}
}
/* slave send control */
else if( IICS0 & 0x08 ){
if(!( IICS0 & 0x04 )){ /* check ACKD0 -> acknowledge */
return MD_NACK;
}
IIC0 = *iic0_s_send_pbuf ++ ;
iic0_s_send_size--;
}
/* slave receive control */
else{
*iic0_s_rev_pbuf ++ = IIC0;
iic0_s_rev_size--;
SetIORBit(IICC0, 0x20); /* WREL1 = 1 start receive */
if( iic0_s_rev_size == 0 ){ /* check all data received */
ClrIORBit(IICC0, 0x04); /* clear ACKE0 */
return MD_SLAVE_RCV_END;
}
}
return MD_OK;
}
/*
**-----------------------------------------------------------------------------
**
** Abstract:
** The function call at IIC0 interrupt request.
**
** Parameters:
** None.
**
** Returns:
** MD_OK
** MD_ERROR : cannot get ack after sended address
** not master mode
** slave did not send ack
** MD_MASTER_RCV_END : all data received
** MD_MASTER_SEND_END : all data sended
**
**-----------------------------------------------------------------------------
*/
MD_STATUS IIC0_MasterHandler( void )
{
/* control for stop condition */
if( !( IICF0 & 0x40 ) ){ /* get stop condition */
return MD_SPT;
}
/* control for sended condition */
if( !iic0_m_sta_flag ){
if( IICS0 & 0x4 ){ /* check ACK */
iic0_m_sta_flag = 1; /* address complete */
CALL_IIC0_MasterFindSlave();
}
else{
return MD_NACK;
}
}
/* master send control */
else if( IICS0 & 0x8 ){
if( !(IICS0 & 0x4) ){ /* check ACK */
SetIORBit(IICC0, 0x01); /* generate stop condition */
return MD_NACK;
}
if( !iic0_m_send_size ){ /* sended finish */
SetIORBit(IICC0, 0x01); /* generate stop condition */
return MD_MASTER_SEND_END;
}
IIC0 = *iic0_m_send_pbuf ++ ; /* send data */
iic0_m_send_size--;
}
/* master receive control */
else {
*iic0_m_rev_pbuf ++ = IIC0; /* receive data */
iic0_m_rev_size--;
if( iic0_m_rev_size == 0 ){ /* receive finish */
ClrIORBit(IICC0, 0x04); /* ACK STOP */
SetIORBit(IICC0, 0x01); /* generate stop condition */
return MD_MASTER_RCV_END;
}
SetIORBit(IICC0, 0x20); /* start receive */
}
return MD_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -