找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8080|回复: 7
收起左侧

PC机发送ABCD给单片机串口1接收到数据后由串口2转发给PC机得到的是ABC。是不是数据...

[复制链接]
ID:142973 发表于 2016-11-13 15:44 | 显示全部楼层 |阅读模式
本帖最后由 幻听你的温柔 于 2016-11-13 15:51 编辑

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)   // \0表示字符串结束标志,通过检测字符串末尾
{
  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中断

     
  }

}
回复

使用道具 举报

ID:142973 发表于 2016-11-13 15:50 | 显示全部楼层
单片机通过串口一接收数据,通过定时器中断来判断是否接收数据完毕,,接收任意字节的数据,,,,求大神
回复

使用道具 举报

ID:140371 发表于 2016-11-13 18:46 来自手机 | 显示全部楼层
幻听你的温柔 发表于 2016-11-13 15:50
单片机通过串口一接收数据,通过定时器中断来判断是否接收数据完毕,,接收任意字节的数据,,,,求大神

接收數据完成。與定時器有什関係。一般而言是在傳輸数組中有判斷数組已結束的協定。
回复

使用道具 举报

ID:142973 发表于 2016-11-13 20:11 | 显示全部楼层
a0931727149 发表于 2016-11-13 18:46
接收數据完成。與定時器有什関係。一般而言是在傳輸数組中有判斷数組已結束的協定。

但是我接收的是任意数据,,不确定的数据额
回复

使用道具 举报

ID:140371 发表于 2016-11-14 08:09 | 显示全部楼层
,,接收任意字节的数据(不确定的数据额)是否到達這一串數據的最後ㄧ個數據... 跟定时器無關 ,,例如串列使用 Time 1 來控制傳輸率  ...傳輸一個數據時 .與其他計時器皆無關...
一串數據(多個數據)的傳輸是否是到達最後一個數據...要靠傳輸協定(傳輸規則)來判斷....
又題意:串口1接收到数据后由串口2转发.....好像沒有必要知道傳輸到最後的一個數據.....改成串口1接收到數據驅動串口2 發送....如何?
回复

使用道具 举报

ID:142973 发表于 2016-11-14 10:27 | 显示全部楼层
a0931727149 发表于 2016-11-14 08:09
,,接收任意字节的数据(不确定的数据额)是否到達這一串數據的最後ㄧ個數據... 跟定时器無關 ,,例如串列使 ...

感觉这不是我想要的
,,,,谢谢
回复

使用道具 举报

ID:140371 发表于 2016-11-14 12:13 | 显示全部楼层
看過你的程式......這樣解讀不知對嗎? ... 當串口1未再設定時間內繼續接收到數據,則將接收到的數據由串口2傳送出去
您在程式中 宣告這個數組
unsigned char receive_number[]={0};//接收串口发送来的数据的数组
我覺得該給個長度...
修改試試看
回复

使用道具 举报

ID:111634 发表于 2016-11-14 18:19 | 显示全部楼层
本帖最后由 zl2168 于 2016-11-14 18:21 编辑

实验16  单片机与PC机虚拟串行通信


虚拟串行通信说明   


添加虚拟串口   


下载“串口调试助手”   


电路设计   


程序设计   


Keil调试   


Proteus仿真   


Proteus仿真一下,确认有效。
实验16 与PC机虚拟串行通信.rar (151.41 KB, 下载次数: 19)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表