📄 uart.c
字号:
#include "include.h"
typedef enum
{
SCI_INIT,
SCI_READY
}_SCI_STATE;
#define BAUD_RATE_9600 0B11001001
#define BAUD_RATE_4800 0B11010010
#define SET_IDLE_INTERRUPT SetBit(SCICR2,4)
#define CLR_IDLE_INTERRUPT ClrBit(SCICR2,4)
#define TRANSMITTER_ENABLE SCICR2|=0B01001000
#define TRANSMITTER_DISABLE SCICR2&=0B00110111
#define SCI_TX_BUFF_SIZE 14
#define SCI_RX_BUFF_SIZE 5
#define IDLE_COUNT 2
#define ID_PROTOCOL 0X25
#define CMD_DIN_KEY 0X01
#define CMD_TOUCH_POSITION 0X02
#define CMD_NAV_AUDIO 0X03
#define Set_Nav_Power()
#define Clr_Nav_Power()
static _SCI_STATE sci_state;
static int8u sci_tx_buff[SCI_TX_BUFF_SIZE];
static int8u tx_index;
static int8u tx_size;
static int8u sci_rx_buff[SCI_RX_BUFF_SIZE];
static int8u rx_index;
static int8u rx_idle;
static int8u rx_error;
static void Check_Rx_Data(void);
static int8u sci_tx_state;
static void SCI_Enable(void)
{
//8 data bits, odd parity(9th bit is replaced by parity bit), 1 stop bit. 4800baud
//Frame Format: SB(Start Bit),PB(Parity Bit),STB(Stop Bit)
// | SB | 8-bit data | PB | STB
SCICR1=0B00010111;
SCIBRR=BAUD_RATE_9600;
SCICR2=0B00110100;
SET_IDLE_INTERRUPT;
rx_index=0;
rx_idle=0;
rx_error=0;
return;
}
static void SCI_Disable(void)
{
SCICR1=0B00000000;
SCICR2=0B00000000;
tx_index=0;
tx_size=0;
rx_index=0;
rx_idle=0;
rx_error=0;
return;
}
static void Start_Tx(void)
{
tx_index=1;
TRANSMITTER_ENABLE;
SET_IDLE_INTERRUPT;
asm_read(SCISR);
SCIDR=sci_tx_buff[0];
sci_tx_state=1;
return;
}
static void Rx_Invalid_Data(void)
{
asm_read(SCISR);
asm_read(SCIDR);
rx_idle=0;
rx_index=0;
SET_IDLE_INTERRUPT;
rx_error++;
return;
}
extern void Intrupt_SCI()
{
if(ValBit(SCISR,TC))
{
//Transmission complete
asm_read(SCISR);
if(tx_index<tx_size)
{
SCIDR=sci_tx_buff[tx_index];
tx_index++;
}
else
{
TRANSMITTER_DISABLE;
SCIDR=0XFF;
}
}
if(ValBit(SCISR,IDLE))
{
//Idle line is detected
asm_read(SCISR);
asm_read(SCIDR);
//rx_idle++;
//if(rx_idle>=IDLE_COUNT)
//{
// Check_Rx_Data();
// CLR_IDLE_INTERRUPT;
//}
return;
}
if(ValBit(SCISR,OR)||ValBit(SCISR,SCI_PE))
{
//Overrun error occur during receiving,and shift register is overwritten
//Parity error occur.
Rx_Invalid_Data();
return;
}
if(ValBit(SCISR,RDRF))
{
//Received data ready
if(ValBit(SCISR,NF))
{
//Noise is detected
Rx_Invalid_Data();
return;
}
if(ValBit(SCISR,FE))
{
//Frame error is detected
Rx_Invalid_Data();
return;
}
//Receive data is correct
asm_read(SCISR);
if(rx_index<SCI_RX_BUFF_SIZE)
{
sci_rx_buff[rx_index]=SCIDR;
rx_index++;
}
else
{
asm_read(SCIDR);
}
rx_idle=0;
SET_IDLE_INTERRUPT;
}
return;
}
static void Rx_Data_Analyse(void)
{
if(rx_idle<IDLE_COUNT)return;
if(rx_index==0)return;
switch(sci_rx_buff[2])
{
case CMD_DIN_KEY:
break;
case CMD_NAV_AUDIO:
#ifdef NAVI_OVERLAP
if(bAudioGate!=sci_rx_buff[3])
{
bAudioGate=sci_rx_buff[3];
Audio_Gate_Transition(bAudioGate);
}
#endif
break;
}
rx_index=0;
return;
}
//协议如下:
// 协议识别符 帧长度 数据包 校验和
//Protocol-ID Frame-Length Data-packet Frame-Checksum
static void Check_Rx_Data(void)
{
int8u i;
if(rx_error)
{
rx_error=0;
rx_index=0;
return;
}
if(rx_index==0)return;
if(rx_index<4)
{
rx_index=0;
return;
}
//检验协议识别符号
if(sci_rx_buff[0]!=ID_PROTOCOL)
{
rx_index=0;
return;
}
//检验有效数据长度
if((sci_rx_buff[1])!=rx_index)
{
rx_index=0;
return;
}
//检验校验和
rx_error=0;
for(i=rx_index;;)
{
if(i==0)break;
i--;
rx_error+=sci_rx_buff[i];
}
if(rx_error)
{
rx_error=0;
rx_index=0;
return;
}
//协议校验正确
return;
}
static void Transmit_Touch_Position(void)
{
return;
}
//4ms schedule
extern void sci_pro(void)
{
if(!Main_Power())
{
SCI_Disable();
sci_state=SCI_INIT;
sci_tx_state=0;
Clr_Nav_Power();
return;
}
Set_Nav_Power();
switch(sci_state)
{
case SCI_INIT:
if(Machine_Power())
{
SCI_Enable();
sci_state++;
}
break;
case SCI_READY:
if(rx_idle!=0xff)
rx_idle++;
if(FrontSource==SOURCE_NAVI)
{
Transmit_Touch_Position();
Transmit_Key_Logic();
}
sci_tx_pro();
if(rx_idle==(IDLE_COUNT+1))
{
Check_Rx_Data();
CLR_IDLE_INTERRUPT;
Rx_Data_Analyse();
}
break;
}
return;
}
void SCI_Initialize(void)
{
SCIBRR = 0b11001001;
SCICR1 = 0b00000000;
SCICR2 = 0b01100100;
}
#ifndef GLOBALS_UART_DRIVER
#define sci_extern extern
#else
#define sci_extern
#endif
typedef enum
{
PIE,
PS,
PCE,
WAKE,
M,
SCID,
T8,
R8
}SCI_SCICR1;
typedef enum
{
SBK,
RWU,
RE, //接收中断使能
TE, //发送中断使能
ILIE,
RIE,
TCIE,
TIE
}SCI_SCICR2;
typedef enum
{
SCI_PE,
FE,
NF,
OR,
IDLE,
RDRF, //接收数据准备好标志,1表示接收数据已经放到接收移位寄存器
TC, //移位寄存器发送完毕标志,1表示数据发送完毕
TDRE //发送数据寄存器空标志,1表示数据已经放到移位寄存器
}SCI_SCISR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -