⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 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 + -