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

📄 uart.c

📁 MAXIM的DS3231时钟,温度都具备的芯片.驱动IC为AVRmega16或者mega32.全功能.内附全部驱动程序.绝对原创.
💻 C
字号:
#include "uart.h"
#include "system.h"

#define MSGHEAD 	 	0xfa	//数据头
//#define DeviceAddr  	1		//设备地址  01

#define ReadCommand  	0x0f	//读设备功能码
#define WriteCommand 	0x10	//写设备功能码
#define sendCommand  	0x04	//设备主动发送功能码

#define fosc F_CPU
#define baud 115200
#define ubrr (fosc/16/baud-1)
#define OutLEN 	50   //串口发送缓冲大小
#define InLEN 	20   //串口接收缓冲大小

volatile unsigned char firstinflag=1;		//程序第一次执行,上传各个参数
volatile unsigned char Uartshortkeyflag=0;	//UART接收到快捷键标志位
volatile unsigned char UartReceiveErrorflag=0;	//UART接收错误标志位
volatile unsigned char UartReceiveflag=0;	//UART接收标志位
volatile unsigned char UartReadflag=0;		//UART接收读取设备信息标志位
volatile unsigned char UartWriteflag=0;		//UART接收写入设备信息标志位
volatile unsigned char ReceiveCounter=0;		//UART接收计数器
volatile unsigned char SendCounter=0;		//UART发送计数器
volatile unsigned char ReceiveBuffer[InLEN];	//UART接收缓冲区
volatile unsigned char SendBuffer[OutLEN];	//UART发送缓冲区

void UartIntit(void)	//UART初始化
{
	UCSRC&=~(1<<URSEL); 
    UBRRH=(unsigned char)(ubrr>>8); 
    UBRRL=(unsigned char)ubrr; 
	UCSRA=0x00;
	UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);		//使能接收中断、接收器与发送器使能
	UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);	//设置帧格式:8个数据位,1个停止位
}

void UARTSend(unsigned char data)	//发送8位的帧数据
{
	while(!(UCSRA&(1<<UDRE)))		//等待发送缓冲器为空
	{
		;//此处可以去刷新显示或者读一次按键,等等
	}
	UDR=data;						//将数据放入缓冲器,发送数据
}

void UARTSendArray(unsigned char *SendStartAddress,unsigned char SendByte)	//发送SendBuffer数据
{
	while(SendByte--)UARTSend(*SendStartAddress++);
	UARTSend(0x0D);
	UARTSend(0x0A);	//结尾发送回车换行
}

void UARTSendString(unsigned char *ptr)
{
	while (*ptr)UARTSend(*ptr++);
	UARTSend(0x0D);
	UARTSend(0x0A);	//结尾发送回车换行
}

void uart(void)
{
	if(firstinflag/*|timechangeflag|temperaturechangeflag|radiomodechangeflag|mp3modechangeflag*/)
	{
		if(firstinflag)
		{
			firstinflag=0;
			return;
		}
	}
	ProcessReceiveData();
}


//---------------------------------------------------------------
//
//			串口接收中断服务程序
//
//	1.接收PC机发来的快捷键读命令:
//	S:读取当前时间;	T:读取当前温度;	M:读取当前工作模式;	E:读取系统错误号
//	用户无论按下哪种快捷键,紧接着再次按下J键都会显示其具体的工作状态;
//
//	2.接收PC机发来的读写命令
//	用户需按照通讯协议:
//	写命令:数据头+写功能码+编号+内容;
//	读命令:数据头+读功能码+编号;
//	编号如下:
//	01:时间;	02:温度;	03:工作模式;	04:未定义
//
//---------------------------------------------------------------
ISR(USART_RXC_vect)	  	//串口接收中断服务程序
{
	ReceiveBuffer[ReceiveCounter++]=UDR;
	if(UDR!='a')
	{
		ReadDate();
	UARTSendString(NowDATE);	//发送到电脑
	}
	switch(ReceiveBuffer[0])
	{
		case 'S':
		case 's':
		case 'T':
		case 't':
		case 'M':
		case 'm':
		case 'E':
		case 'e':
			UartReceiveflag=1;
			Uartshortkeyflag=1;
			UCSRB&=0xef;		//禁止接收
			break;
		default:
		
			UartReceiveErrorflag=1;
			break;
	}
	if(ReceiveBuffer[0]==MSGHEAD)
	{
		UartReceiveErrorflag=0;
		if(ReceiveBuffer[1]==ReadCommand)
		{
			if(ReceiveCounter>2)
			{
				UartReceiveflag=1;
				UartReadflag=1;
				UCSRB&=0xef;	//禁止接收
			}
		}
		else if(ReceiveBuffer[1]==WriteCommand)
		{
			if(ReceiveCounter>9)
			{
				UartReceiveflag=1;
				UartWriteflag=1;
				UCSRB&=0xef;	//禁止接收
			}
		}
	}
	else ReceiveCounter=0;
}

void  ProcessReceiveData(void)	//解析接收缓冲区中的数据
{
	/*if(UartReceiveErrorflag)
	{
		UartReceiveErrorflag=0;
		ResponseErro();
	}*/
	if(UartReceiveflag)
	{
		UartReceiveflag=0;  	//清接收标志
		ReceiveCounter=0;
		if(UartReadflag|Uartshortkeyflag)ResponseRead();	//处理读命令
		else if(UartWriteflag)ResponseWrite();				//处理写命令
		else systemerror=0xfa;
	}
	else UCSRB=0x98;//使能接收
}

void ResponseRead(void)
{
	//unsigned char i;
	ReadDate();
	UARTSendString(NowDATE);	//发送到电脑
	if(Uartshortkeyflag)
	{
		Uartshortkeyflag=0;
		if((ReceiveBuffer[0]=='s')|(ReceiveBuffer[0]=='S'))ReceiveBuffer[2]=1;
		else if((ReceiveBuffer[0]=='t')|(ReceiveBuffer[0]=='T'))ReceiveBuffer[2]=2;
		else if((ReceiveBuffer[0]=='m')|(ReceiveBuffer[0]=='M'))UARTSendString((unsigned char *)&"^_^");
		else if((ReceiveBuffer[0]=='e')|(ReceiveBuffer[0]=='E'))UARTSendString((unsigned char *)&"^_^");
		goto ShortkeyflagPro;
	}
	else 
	{
		UartReadflag=0;
		if(ReceiveBuffer[2]<5)
		{
			ShortkeyflagPro:
			/*SendCounter=0;
			SendBuffer[SendCounter++]=MSGHEAD;
			SendBuffer[SendCounter++]=ReadCommand;
			SendBuffer[SendCounter++]=ReceiveBuffer[2];*/
			if(ReceiveBuffer[2]==1)
			{
				UARTSendString((unsigned char *)&"读取当前时间...");
				ReadDate();					//读取当前时间,解释
				UARTSendString(NowDATE);	//发送到电脑
				//for(i=0;i<7;i++)SendBuffer[SendCounter++]=RealTimeDate[i];
				//UARTSendArray(SendBuffer,SendCounter);
			}
			else if(ReceiveBuffer[2]==2)ReadTemperatureflag=1;
			else if(ReceiveBuffer[2]==2);
			else if(ReceiveBuffer[2]==2);
			else ResponseErro();
		}
		else ResponseErro();
	}
}

void ResponseWrite(void)//
{
	unsigned char i;
	UartWriteflag=0;
	if(ReceiveBuffer[2]<5)
	{
		if(ReceiveBuffer[2]==1)
		{
			for(i=0;i<7;i++)RealTimeDate[i]=ReceiveBuffer[3+i];
			DS3231WriteTime();
			ReadDate();					//读取当前时间,解释
			UARTSendString(NowDATE);	//发送到电脑
			//for(i=0;i<7;i++)SendBuffer[SendCounter++]=RealTimeDate[i];
		}
		else if(ReceiveBuffer[2]==2);
		else if(ReceiveBuffer[2]==3);
		else if(ReceiveBuffer[2]==4);
	}
	else ResponseErro();
}

void ResponseErro(void)
{
	UARTSendString((unsigned char *)&"指令无效!");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -