IO 模拟 Uart Printf 函数

用IO延时模拟Uart数据,printf 函数

目前 8M情况能支持到 38400

 

 

#include "printf.h"


/********************************************************************
Function:
INPUT   :
OUTPUT  :
NOTE    :调用函数周期,通常需要根据MCU 修改
		:这里面有指令周期固定调试为4us
		:系统CLK =0.5us *4 = 2us
********************************************************************/
void fun_delay()// 1us
{	
// call 2个机器周
//	mov     a, AH  //
//	mov     ra, a  //2个机器周
//	_L3:
//	sdz     ra   // 4个机器周期 2*10 = 11
//	jmp     _L3  2+1 =3 *0.5 
//	ret
	unsigned char i;//这个变量只能命名为I 编译会进行优化
	i = (THE_DELAY_TIME-4)/2;
	do{
		i--;
		asm("nop"); //
	} 	
	while(i!=0);//2
}

/********************************************************************
Function:
INPUT   :
OUTPUT  :
NOTE    :
********************************************************************/
void put_Char(unsigned char data)
{
	unsigned char i;
	SET_UART_PIN_OUT();
	// 0xaa
	//开始信号
	UART_PIN_OUT_LOW();
	fun_delay();
	// 传送字符
	for(i=0;i<8;i++)
	{
		
		if(data&0x01)
		{
			UART_PIN_OUT_HIHG();	
		}
		else
		{
			UART_PIN_OUT_LOW();	
		}
		fun_delay();
		data=data>>1;
	}
	//结束幸好
	UART_PIN_OUT_HIHG();
	fun_delay();
}


/********************************************************************
Function:
INPUT   :
OUTPUT  :
NOTE    :
********************************************************************/
void printf(char *Char_Data,volatile unsigned long temp)
{
	unsigned char data_Flag,data_H_Is_None_Zero,data_base,inteProtect; // 可以
	inteProtect = ISR_RESITER;
	ISR_RESITER = 0;
	data_Flag = 0;
	while(*Char_Data != '\0')
	{
		//当前字符是%d 表示数据输出

		if(*Char_Data=='%')
		{
		
			Char_Data++;
			if(*Char_Data=='d')
			{
				data_Flag = 1;	//发送数据	
				data_base =10;
			}
			if(*Char_Data=='x')
			{
				data_Flag = 1;
				data_base = 16;
			}
			Char_Data++;
		}	
		if(data_Flag)//
		{
			data_Flag = 0;//
			data_H_Is_None_Zero = 0;
			//数据转字符
		volatile	unsigned char i;
		volatile 	unsigned char Data_buf[12];
			for (i = 0; i < 10; i++)
			{
				Data_buf[10-i] = temp % data_base;
				temp /= data_base;
			}	
			for(i=0;i<11;i++) 
			{
				if(Data_buf[i]!=0)
				{
					data_H_Is_None_Zero = 1;
				}
				if(i==10)
				{	
					if(Data_buf[10]==0)
					{
						data_H_Is_None_Zero = 1;
					}
				}
				if(data_H_Is_None_Zero)
				{
					if(Data_buf[i]>9)
					{
						put_Char(Data_buf[i]+55); 	
					}
					else
					{
						put_Char(Data_buf[i]+48); //开始打印数据 如果分解完成都是直接输出0
					}
					
				}		
			}

		}
		else
		{
			
			put_Char(*Char_Data);
			Char_Data++;
		}
	}
	ISR_RESITER=inteProtect;
}
#ifndef _PRINFTF_H
#define  _PRINFTF_H

//字符串长度限制为 10

//#define long unsigned (SYS_CLK)  80000000 // 特别注意 部分编译器只支持16位
//#define UART_BOUND 9600 // 建议用这个波特率。提高兼容性 104 us
// #define UART_BOUND 19200 //  52 支持
//#define UART_BOUND 38400  //  25 支持
//#define UART_BOUND 57600  //  20 时间太短,不支持
// 注意指令周期和系统周期不不一定一样 在设配fun_delay函数特别注意
// 合泰是四个时钟周期为一个指令周期 

#define UART_PIN _pa5
#define SET_UART_PIN_OUT() { _pac5 = 0;}
#define UART_PIN_OUT_HIHG() { UART_PIN=1;}
#define UART_PIN_OUT_LOW()  {UART_PIN=0;}



#define ISR_RESITER     _emi 

#define THE_DELAY_TIME 25

void fun_delay();
void put_Char(unsigned char data);
void printf(char *Char_Data,unsigned long temp);

// V1.0.0
#endif
















 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
外部中断模拟串口,波特率不能超过65536 实验测试:发送57600可以正常,但接收只能 <= 38400 #include "Uart_EXT0.h" #include "MAIN.h" #define FOCS 22114800ul bit Over; bit bRxflag; unsigned char IEN0_NOW,IEN1_NOW; //中断临时变量 unsigned char idata bRxstate=0; //接收状态 unsigned char idata tmp_Len=0; //缓存数组下标 unsigned char idata bRxlen; //接收字节数 unsigned char xdata EX_buf[64]; //接收存放区 /*************************************************** baud = 56000 接收一字节 =178.6us ,接收会出现错误 baud = 38400 接收一字节 =260.4us //快速接收都容易出现错误 baud = 19200 接收一字节 =520us | baud = 14400 接收一字节 =694.5us | baud = 9600 接收一字节 =1041.6us | baud = 4800 接收一字节 =2.083ms 接收过长,定时器MODE2无法满足 //主机发送的数据最好加上校验字 发送:最大57600,发送还能正常。 ****************************************************/ void Time0_Uart(unsigned int baud) { TMOD &= 0XF0; TMOD |= 0X02; //使用定时器0方式2,使用方式1则2400波特也能有 TH0 = 256-(FOCS/12)/baud; TL0 = TH0; IP0 |= 0x02; //设置为最高优先级 IP1 |= 0x02; TR0 = 1; ET0 = 1; EA = 1; } void Time0_isr() interrupt 1 { //方式1则重装值 Over = 1; } /* 发送数据,1起始位,8数据,1停止位 发送波特率实验57600都不会错误,大量发送数据待测试 */ void Uart_set(unsigned char dat) { unsigned char i; Over = 0; TL0 = TH0; //防止发送数据开始时不知道TL0是多少 T_uart = 0; //起始位 while(Over==0); Over = 0; for(i=0;i>= 1; } // Over = 0; //数据位清零了 T_uart = 1; //停止位,此后如果没有数据则一直为高 while(Over==0); } unsigned char get_Uart() { unsigned char I=0,get_dat=0; Over = 0; TL0 = TH0; //重新赋值,防止出错 while(Over==0); Over = 0; for(I=0;I>= 1; if(Get_ex == 1) get_dat |= 0x80; else get_dat &= 0x7f; while(Over==0); Over = 0; } if(Get_ex == 1) { Over = 0; } return get_dat; } void EXuart_isr() interrupt 0 { unsigned char _chr; IEN0_NOW = IEN0; //进入接收1字节,关闭中断 IEN1_NOW = IEN1; IEN0 = 0X82; IEN1 = 0; _chr=get_Uart(); switch(bRxstate) { case 0: if(_chr==0x55) { bRxstate=1; } else bRxstate=0; break; case 1: if(_chr==0xaa) { bRxstate=2; } else bRxstate=0; break; case 2: //取得数据长度 bRxlen=_chr; bRxstate=3; break; case 3: EX_buf[tmp_Len]=_chr; tmp_Len++; if(tmp_Len==bRxlen) { bRxstate=0; tmp_Len=0; bRxflag=1; //一帧数据接收完毕,置位完成标志位 } break; default: break; } IE0 = 0; //清外部0中断标志,防止下次接收不到 IEN0 = IEN0_NOW; IEN1 = IEN1_NOW; } void main() { Time0_Uart(9600); EX_uart(); if(bRxflag==1) { bRxflag = 0; for(i=0;i<10;i++) RevBuffer[i] = EX_buf[i]; T0Uart_TX(10,RevBuffer); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值