/*
 * UART.c
 *
 *  Created on: 2019-8-30
 *      Author: charles_cai
 */
#include"main.h"

#ifndef UART_C_
#define UART_C_
/*
 * 串口初始化
 * 输入：0——UART1/波特率9600/8位数据、1位停止位、无奇偶校验
 * 输入：1——UART1/波特率9600/8位数据、1位停止位、有奇偶校验
 * UART2——Lin模式，波特率9600/8位数据、1位停止位、无奇偶校验
 */
void Init_uart(unsigned char mode)
{
	RSCTL1 =0x90;//使能串口模块、使能接收器
	BRCTL1 =0x40;//接收器空闲
	TSCTL1=0x22;//使能发送功能、移位寄存器空
	EUBRGL1= 0x32;//波特率寄存器设置为50，当前波特率是9600，波特率为Fosc/【m*（EUBRGH：EUBRGL+1）】，m的设置方法参考手册
	EUBRGH1 =0;
	if(mode)
	{
		T1X9 =1;
		R1X9 =1;//使能9位接收
	}
}

/* 函数功能：偶校验函数，软件校验。
 * 如果1的个数为奇数个，则返回1，如果1的个数为偶数个，则返回0。
 * 中断里调用的函数不能被外部其他函数调用，所以偶校验函数还有一个同功能的函数Parity_Check_even_1。
 *
 */
unsigned char Parity_Check_even(unsigned char x)
{
unsigned char  val=0;
while(x)
{
	val^=x;//val 和x进行异或运算
	x>>=1;//x右移一位
}
return (val&0x1) ;//取末位运算. val的二进制形式最后一位位1则返回1，为0则返回0.
}

/* 函数功能：奇校验函数，软件校验。
 * 如果1的个数为奇数个，则返回0，如果1的个数为偶数个，则返回1。
 * 中断里调用的函数不能被外部其他函数调用，所以偶校验函数还有一个同功能的函数Parity_Check_odd_1。
 *
 */
unsigned char Parity_Check_odd(unsigned char x)
{
unsigned char  val=0;
while(x)
{
	val^=x;//val 和x进行异或运算
	x>>=1;//x右移一位
}
return !(val&0x1) ;//取末位运算. val的二进制形式最后一位位1则返回1，为0则返回0.
}

//接收一个字节，和第9位奇偶校验正确 返回 数据,数据放在缓冲区，错误的话返回 0.
/*
 * mode：1——奇校验模式，2——偶校验模式
 */
unsigned char  Rec_Byte(unsigned char mode)
{
 unsigned char Temp,D9, check=0;

 D9=RX9D1;
 Temp=RXSDR1;
 if(mode ==1)
	 check =Parity_Check_odd(Temp);
 else if(mode ==2)
	 check =Parity_Check_even(Temp);
 if(check ==D9)
 return Temp;
 else
 return 0;
}


/* 函数功能：偶校验函数，软件校验。
 * 如果1的个数为奇数个，则返回1，如果1的个数为偶数个，则返回0。
 * 用于非中断函数的奇偶校验调用
 */
unsigned char Parity_Check_even_1(unsigned char x)
{
unsigned char  val=0;
while(x)
{
	val^=x;//val 和x进行异或运算
	x>>=1;//x右移一位
}
return (val&0x1) ;//取末位运算. val的二进制形式最后一位位1则返回1，为0则返回0.
}

/* 函数功能：奇校验函数，软件校验。
 * 如果1的个数为奇数个，则返回0，如果1的个数为偶数个，则返回1。
 * 用于非中断函数的奇偶校验调用
 */
unsigned char Parity_Check_odd_1(unsigned char x)
{
unsigned char  val=0;
while(x)
{
	val^=x;//val 和x进行异或运算
	x>>=1;//x右移一位
}
return !(val&0x1) ;//取末位运算. val的二进制形式最后一位位1则返回1，为0则返回0.
}

/******************************UART发送字节函数*************************/
/*
 * Send_Dat:待发送的单字节
 * mode：1——奇校验模式，2——偶校验模式
 */
void UartPutchar(unsigned char Send_Dat,unsigned char mode)
{
	if(mode ==1)
		TX9D1 =Parity_Check_odd_1(Send_Dat);
	else if(mode ==2)
		TX9D1 =Parity_Check_even_1(Send_Dat);
	TXSDR1=Send_Dat;//原值返回
	while(TXSRS1==0);
}

/************************
 * 函数名   ：Uart_send
 * 函数功能：UART多字节发送
 * 入口参数：K，发送BUF1中前k个字节
 * 返回      ：无
 ************************/
void Uart_send(unsigned char k)
{
	unsigned char i=0;
	for(i=0;i<k;i++)
	{
		TXSDR1=BUF1[i];
		while(TXSRS1==0);
	}
}
/************************
 * 函数名   ：Write_hello
 * 函数功能：在发送缓存BUF1中填写“HELLO！”
 * 入口参数：无
 * 返回      ：无
 ************************/
void Write_hello()
{
	unsigned char i=0;
	for(i=0;i<10;i++)
	{
		BUF1[i]=0;
	}

	BUF1[0]='H';
	BUF1[1]='E';
	BUF1[2]='L';
	BUF1[3]='L';
	BUF1[4]='O';
	BUF1[5]='!';
	BUF1[6]='\r';
}
/************************
 * 函数名   ：Write_hello
 * 函数功能：在发送缓存BUF1中填写“ByeBye！”
 * 入口参数：无
 * 返回      ：无
 ************************/
void Write_Bye()
{
	unsigned char i=0;
	for(i=0;i<10;i++)
	{
		BUF1[i]=0;
	}

	BUF1[0]='B';
	BUF1[1]='y';
	BUF1[2]='e';
	BUF1[3]='B';
	BUF1[4]='y';
	BUF1[5]='e';
	BUF1[6]='!';
	BUF1[7]='\n';
}

#endif /* UART_C_ */
