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

📄 m_usart.c

📁 PIC单片机模拟串口 11.0592时钟 支持2400波特及以下稳定收发 一位起始
💻 C
字号:
#include <pic.h>

#include "m_usart.h"
#include "gobal_ram.h"


//=============================================================================


unsigned char	m_TXBUF;		//(全局)模拟发送缓冲字节
unsigned char	m_RXBUF;		//(全局)模拟接收缓冲字节
bit				m_TX_BIT9;		//(全局)模拟发送第九位
bit				m_RX_BIT9;		//(全局)模拟接收第九位
unsigned char	p_m_TXBUF;		//(全局)发送指针		
unsigned char	p_m_RXBUF;		//(全局)接收指针

bit				m_8_OR_9;		//(全局收发模式标志:1为9位收发,0位8位收发

//bit				m_TXIF;			//(全局发送完标志(1发送完,0正在发)
bit				m_TX_enble;		//发送允许

bit				m_RCIF;			//(全局接收完标志(1接收完,0在接收或等待接收)
bit				m_RX_enble;		//接收允许

unsigned char	m_BT_reLoad_H;	//(全局时钟1初值重载_H
unsigned char	m_BT_reLoad_L;	//(全局时钟1初值重载_L
//======================================================================
//缓冲区
unsigned int	TIMER_M_BYTE_OVER_count;	//模拟字节超时计时
unsigned char	M_RXBuf[M_RX_PKG_LEN];		//模拟包缓冲区
unsigned char	p_M_RXBuf;					//模拟包缓冲区指针
bit				Flag_M_byte_time;			//模拟字节间隔计时标志			
bit				Flag_M_PKG_Over;			//模拟包结束(1为收完一包,0未收完)
//-----------------------------------------------------------------------------


//初始化模拟串口
//Bt:		波特率代码
//Flag89:	9位还是8位收发
void	Init_m_usart(unsigned long Foc, unsigned long Bt, unsigned char Flag89)
{

	//字节部分
	//=========================================================
	//初始化全局内存变量
	if(Flag89)
	{
		m_8_OR_9=1;	
	}
	else
	{
		m_8_OR_9=0;	
	}//9位接收标志

	p_m_TXBUF=0;		//发送初始
	p_m_RXBUF=0;		//接收初始

	//m_TXIF=1;			//初始发送完
	m_TX_enble=0;		//发送允许(不允许)

	m_RCIF=0;			//初始等待接收
	m_RX_enble=0;		//接收允许(不允许)

	//初始波特率时钟T1
	//m_BT_reLoad_H=0xF7;	//(全局时钟1初值重载_H 	11.0592M 1200
	//m_BT_reLoad_L=0x00;	//(全局时钟1初值重载_L
	//m_BT_reLoad_H=0xEE;	//(全局时钟1初值重载_H	11.0592M 600
	//m_BT_reLoad_L=0x00;	//(全局时钟1初值重载_L

	m_BT_reLoad_H=(FULL_U16-Foc/(4*Bt))/FULL_U8;
	m_BT_reLoad_L=(FULL_U16-Foc/(4*Bt))%FULL_U8;
	T1CON=1;			//不分频,时钟开起来

	//m_BT_reLoad_H=0x00;	//(全局时钟1初值重载_H
	//m_BT_reLoad_L=0x00;	//(全局时钟1初值重载_L
	//T1CON=0x31;			//不分频,时钟开起来

	TMR1H=m_BT_reLoad_H;
	TMR1L=m_BT_reLoad_L;
	TMR1IE=1;			//允许时钟1中断

	//模拟串口的口线输入输出类型设定
	IOStyle_TX_Line=0;	//发送口线类型	(输出)
	TX_Line=1;			//发送口线		(高)


	IOStyle_RX_Line=0;	//接收口线类型	(输出)
	RX_Line=1;			//接收口线		(高)
	IOStyle_RX_Line=1;	//接收口线类型	(输入)

	//接收外部中断(PB端口电瓶变化)开起来
	RBIF=0;
	RBIE=1;
	//===============================================================

	
	//包部分
	//===============================================================
	TIMER_M_BYTE_OVER_count=0;	//模拟字节超时计时
	p_M_RXBuf=0;				//模拟包缓冲区指针
	Flag_M_PKG_Over=0;			//模拟包结束(1为收完一包,0未收完)
	Flag_M_byte_time=0;			//模拟字节间隔计时标志	
	//===============================================================		
	
}
//---------------------------------------------------------------------------

//模拟串口发送字节
//Ch:		要发送的字节
void 	m_putch(unsigned char Ch)
{
	RBIE=0;
	RBIF=0;
	///////////////////////////////	
	m_TXBUF=Ch;
	//让停止位保持一个波特宽的高电平
	p_m_TXBUF=0;
	m_TX_enble=1;
	while(m_TX_enble);
	///////////////////////////////	
	RBIF=0;
	RBIE=1;		
}
//--------------------------------------------------------------------------

//模拟包接收查询服务
//在背景中执行
//起动
void	SERVER_M_PKG_REC(void)
{
	//收到新字节
	if(m_RCIF)
	{
		if(!Flag_M_PKG_Over)
		{
			//======================================
			//清字节间定时器
			TIMER_M_BYTE_OVER_count=0;
			Flag_M_byte_time=1;
			//======================================
			//防止越界
			if(M_RX_PKG_LEN==p_M_RXBuf) p_M_RXBuf--;
			//接收
			M_RXBuf[p_M_RXBuf++]=m_RXBUF;

			//======================================	
		}
		m_RCIF=0;
	}
}
//--------------------------------------------------------------------------


//收发波特,电平中断服务
void	M_USART_INTFACE(void)
{
	//时钟1中断
	if(TMR1IF)
	{
		//重入
		TMR1IF=0;
		TMR1H=m_BT_reLoad_H;
		TMR1L=m_BT_reLoad_L;

		//发送时序
		if(m_TX_enble)
		{
			if(0==p_m_TXBUF) 
			{
				TX_Line=0;
				p_m_TXBUF++;
			}
			else if(p_m_TXBUF<9)
			{
				if(1&m_TXBUF)
				{
					TX_Line=1;
				}
				else
				{
					TX_Line=0;
				}
				m_TXBUF>>=1;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
				p_m_TXBUF++;				
			}
			else if(9==p_m_TXBUF)
			{
				//是否要发第九位
				if(m_8_OR_9)
				{
					TX_Line=m_TX_BIT9;
				}
				else
				{
					//停止
					TX_Line=1;
				}
				p_m_TXBUF++;
			}
			else if(10==p_m_TXBUF)
			{
				//停止
				TX_Line=1;
				p_m_TXBUF++;
			}
			else
			{
				//发完标志
				m_TX_enble=0;	
			}
		}


		//接收时序
		if(m_RX_enble)
		{
			if(p_m_RXBUF<8)
			{
				m_RXBUF>>=1;
				if(RX_Line)	
				{
					m_RXBUF|=0x80;		
				}
				//
				p_m_RXBUF++;
			}
			else
			{
				//是否要收第九位
				if(m_8_OR_9)
				{
					m_RX_BIT9=RX_Line;
				}

				//接收结束
				m_RX_enble=0;
				p_m_RXBUF=0;
				//开检测中断
				RBIF=0;
				RBIE=1;

				//////////////////////////////////////
				m_RCIF=1;		//模拟接收到新数据标志
				//////////////////////////////////////
			}
		}

		//模拟字节间定时
		if(Flag_M_byte_time)
		{
			TIMER_M_BYTE_OVER_count++;
			if(TIMER_M_BYTE_OVER_count>TIMER_M_BYTE_OVER)
			{
				//字节超时了,一包结束
				Flag_M_byte_time=0;	
				Flag_M_PKG_Over=1;
			}		
		}
	}
	//=============================================================

	//模拟端口接收中断起始
	if(RBIE)
	{
		if(RBIF)
		{
			RBIF=0;
			if(0==p_m_RXBUF)
			{
				if(!RX_Line)
				{
					//
					m_RXBUF=0;
					TMR1IF=0;
					TMR1H=m_BT_reLoad_H;
					TMR1L=m_BT_reLoad_L;

					//关检测中断
					RBIE=0;
					//起始位到了
					m_RX_enble=1;
					//重入模拟波特率
				}
			}
		}
	}
	//====================================================


	//模拟包接收查询服务
	//在背景中执行
	//起动
	SERVER_M_PKG_REC();
	//===================================================
}

⌨️ 快捷键说明

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