PC机发送ABCD给单片机串口1接收到数据后由串口2转发给PC机得到的是ABC。是不是数据丢失啦,,处理接收的速度比处理数据的速度要快才不会出现丢失数据的情况(这样要怎么该程序呢)单片机通过串口一接收数据,通过定时器中断来判断是否接收数据完毕,,接收任意字节的数据
/************************************************
* 芯 片 : STC12C5A60S2
* 时 钟 :11.0592MHz
* 开发环境 :Keil uVision V4.00a
* 备 注 :
*/
//文件包含
#include "stc12c5a60s2.h"
unsigned char receive_number[]={0};//接收串口发送来的数据的数组
unsigned char rec1_count=0;//串口1接收计数器
unsigned int rec1_flag=0; //串口1接收标志位
//全局变量
unsigned int p_send=0;
unsigned char ser_receive; //串口1接收到的数据
unsigned char flag1,flag2,temp1,temp2,temp3,k,h,i=0;
//函数声明
void Uart2_Init(void); //串口初始化
void Timer0_Init(); //定时器0初始化
void Uart2_SendChar(unsigned char Udat);
void Uart2_SendString(unsigned char *PBuf,unsigned char a);
void UART_1SendOneByte(unsigned char c);
void UART_1Sendstr(unsigned char *s,unsigned char b);
void Display_Menu(void);
void delayms(unsigned int n) ///1毫秒
{
unsigned int i;
while(n--)
{
for ( i=0;i<113;i++ );
}
}
//定时器0初始化
void Timer0_Init() //0微秒@11.0592MHz//定时器0 工作方式2
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x02; //设置定时器模 TMOD=0x01;
TL0 = 0x00; //设置定时初值
TH0 = 0x00; //设置定时重载值
TF0 = 0; //清除TF0标志
TR0 = 0; //定时器0开始计时
ET0=1;
EA=1;
}
///
/***********************************************
函数名称:Uart2_Init
功 能:串口2初始化函数
入口参数:无
返 回 值:无
备 注:STC12C5A60S2单片机串口2
只能选择独立的波特率发生器,
不能使用定时器1做为波特率发生器
************************************************/
void UartInit(void) [url=]//115200bps@11.0592MHz[/url]
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
//TL1 = 0x00; //设定定时初值
//TH1 = 0x00; //设定定时器重装值
TL1 = 0xFD; //设定定时初值
TH1 = 0xFD; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
REN=1; //允许串口接收
ES=1; //开串口 中断
EA=1;
//// S2BUF
AUXR &= 0xF7; //波特率不倍速
S2CON = 0x50; //8位数据,可变波特率
AUXR |= 0x04; //独立波特率发生器时钟为Fosc,即1T
BRT = 0xFD; //设定独立波特率发生器重装值
AUXR |= 0x10; //启动独立波特率发生器
IE2=0x01; //允许串口2中断
}
//////////////
/****************串行口1发送****************/
void UART_1SendOneByte(unsigned char c)
{
SBUF = c;
while(!TI); //若TI=0,在此等待
TI = 0;
}
void UART_1Sendstr(unsigned char *s,unsigned char b)
{
while(b) // 表示字符串结束标志,通过检测字符串末尾
{
UART_1SendOneByte(*s); //发送一个字符
s++;//移动到下一个字符
b--;
}
}
/////////////
/***********************************************
*函数名称:Uart2_SendChar
*功 能:串口2发送单个字符函数
*入口参数:Udat:欲发送的数据
*返 回 值:无
*备 注:无
************************************************/
void Uart2_SendChar(unsigned char Udat)
{ ES=0;
S2BUF=Udat; //将数据放入发送缓冲区
while(!(S2CON&0x02)); //等待发送完成
S2CON=S2CON & 0xfd; //清零S2TI
ES=1;
}
/***********************************************
*函数名称:Uart2_SendString
*功 能:串口发送字符串函数
*入口参数:*PBuf:指向字符串的指针
*返 回 值:无
*备 注:串口发送时需禁止全局中断,防止出错
************************************************/
void Uart2_SendString(unsigned char *PBuf,unsigned char a)
{
ES=0; //关闭中断,防止对发送缓冲区影响
while(a) //未到字符串末尾
{
Uart2_SendChar(*PBuf);
PBuf++;
a--;
}
ES=1;
}
/////////
/************串行口1中断处理函数*************/
void UART_1Interrupt(void) interrupt 4
{
if(RI==1)
{
RI = 0;
//定时器从0开始计数
// TF1=0;
//开定时器,定时器开始计数
TR0=1;
TH0= 0x00;
TL0= 0x00;
if(SBUF!=0xff)//接收数据
{
receive_number[rec1_count++]=SBUF;
}
}
}
/*******************串行口2中断处理函数*****************************/
void Uart2_ISR(void) interrupt 8
{
if(S2CON&0x01) //发送和接收共用一个中断向量,需在程序中判断
{
S2CON=S2CON & 0xfe; //串口接收中断标记需软件清零
}
}
void Timer0_Rountine(void) interrupt 1 //定时器0 工作方式2
{
rec1_flag=1; ////当定时器0溢出中断时让rec1_flag=1。
}
//主函数
void main(void)
{
unsigned char j;
UartInit(); //串口2初始化
Timer0_Init(); //定时器0初始化
delayms(20);
while(1)
{
if(rec1_flag==1 ) //如果是1
{
ES=0;
rec1_flag=0;
TR0=0;
while(p_send<=rec1_count)//判断发送指针的值是否小于全局计数器
{ //如果是
Uart2_SendChar(receive_number[p_send]);//开始发送数据
p_send=p_send+1;
}
p_send=0; rec1_count=0;
ES=1;
//如果不是
//停止发送数据
} //开串口1中断
}
}
此帖出自
小平头技术问答
实验16 单片机与PC机虚拟串行通信
⒈ 虚拟串行通信说明 …
⑴ 添加虚拟串口 …
⑵ 下载“串口调试助手” …
⒉ 电路设计 …
⒊ 程序设计 …
⒋ Keil调试 …
⒌ Proteus仿真 …
先Proteus仿真一下,确认有效。
一周热门 更多>