
//修改记录

//2014.5.6
//修改了字符发送底层函数, 去掉了方向选择端口, 这个放在具体的模块封装文件中去提供接口
//去掉了发送延时, 现在是检测硬件寄存器判断字符是否可以发送以及是否发送完毕
//增加了波特率设置函数作为接口


	public const int16 max_length = 32;
	public const int32 baud = 9600;
	public [int8*max_length] buffer;
	public int16 length;
	public int16 start;
	public uint8 OS_EventFlag;
	
	public int32 XTAL;
	
	//加载芯片底层代码
	#include "$chip$.txt"
	
	unit protocol0
	{
		public link bool IsReady( int32 j ) {}
		public link int8 GetData( int32 i ) {}
		public link void Clear( int32 n) {}
	}
	protocol0.IsReady = is_ready;
	protocol0.GetData = get_data;
	protocol0.Clear = clear;
	
	//----------------------------------------------------
	//串口初始化,波特率:9600,8个数据位,1个停止位,没有奇偶校验
	public void init()
	{
		OS_EventFlag = 0;
		
		//io.RDE_DIR = 1;
		//io.RDE_OUT = 0;
		
		//io.RXD_DIR = 0;
		//io.RXD_OUT = 1;
		
		//io.TXD_DIR = 1;
		//io.TXD_OUT = 1;
		
		PORT.D2_DIR = 0;
		PORT.D2_OUT = 1;
		
		PORT.D3_DIR = 1;
		PORT.D3_OUT = 1;
		
		XTAL = 11059200;
		//XTAL = 16000000;
		
		//设置默认波特率
		set_baud( baud );
		
		length = 0;
		start = 0;
	}
	//---------------------------------------------------
	//获取指定位置的数据
	public int32 get_data( int32 i )
	{
		int16 n = start + (int16)i;
		if( n >= max_length ) n - max_length;
		return buffer[n];
	}
	//---------------------------------------------------
	//判断指定位置的数据是否有效
	public bool is_ready( int32 j )
	{
		//注意 length 是临界变量,不能直接访问
		#asm "cli"
		int16 t_length = length;
		#asm "sei"
		
		int16 i = (int16)j;
		if( start == t_length ) return false;
		if( start < t_length ) {
			if( start + i < t_length ) {
				return true;
			} else {
				return false;
			}
		} else {
			if( start + i < t_length + max_length ) {
				return true;
			} else {
				return false;
			}
		}
	}
	//---------------------------------------------------
	//清除指定数目的数据
	public void clear( int32 n)
	{
		int16 i = (int16)n;
		start + i;
		if( start >= max_length ) start - max_length;
	}
	//=================================================================================
	
	//发送一个字符串
	public void print_string( [int8*?] s )
	{
		uint8 i = 0;
		while( s[i] != 0 ) {
			print_byte( s[i] );
			i + 1;
		}
	}
	//发送一个字符
	public void print_char( int32 data )
	{
		uint32 d = (uint)data;
		print_byte( (int)d.0(uint8) );
	}
	//发送一个数字
	[int8*11] number_buffer;
	public void print_number( int32 data0 )
	{
		//计算正负数
		bool isNeg;
		uint32 data;
		if( data0 >= 0 ) {
			data = (uint)data0;
			isNeg = false;
		} else {
			data = (uint)-data0;
			isNeg = true;
		}
		//解析数字到缓冲区中
		int16 i = 0;
		forever {
			int8 ch = '0' + (int)(uint8)(uint16)(data % 10);
			number_buffer[i] = ch;
			i + 1;
			data / 10;
			if( data == 0 ) {
				if( isNeg ) {
					number_buffer[i] = '-';
					i + 1;
				}
				break;
			}
		}
		do {
			i - 1;
			print_byte( number_buffer[i] );
		}
		while( i != 0 );
	}
	//=================================================================================
	//发送一个字节
	public void print_byte( int8 data )
	{
		WAIT_SEND_OK();
		UDR = (uint)data;
	}
	//发送延时
	void delay()
	{
		loop( 15 ) loop( 100 ) {}
	}
	//数据接收中断
	INTERRUPT_UART
	void RXC()
	{
		//必须在中断程序中读取 UDR,否则在退出后会重新进入中断
		buffer[length] = (int)UDR;
		length + 1;
		if( length == max_length ) length = 0;
		OS_EventFlag.0(bit) = 1;
	}




	//----------------------------------------------------
	//发送一个字符
//	public void print_char( int8 data )
//	{
//		io.RDE_OUT = 1;
//		delay();
//		CHIP.UDR = (uint)data;
//		repeat until CHIP.UCSRA.5(bit) == 1; {}
//		CHIP.UCSRA.5(bit) = 1;
//		delay();//这个延时很重要! 去掉之后可以接收但是发送有错
//		io.RDE_OUT = 0;
//	}















