西格玛mmmm 2023-11-24 17:01 采纳率: 0%
浏览 5

51单片机串口发送小问题

问题遇到的现象和发生背景

目的是实现时间在串口助手上打印
例如2022 01 01 00-00-00-MON

遇到的现象和发生背景,请写出第一个错误信息

串口接收的格式很奇怪

2022 不能在同一行打印

这是串口i接受的信息(每次两行)

[16:37:04.698]接收←2
[16:37:04.761]接收←022-01-01-00-01-23-MON

[16:37:06.208]接收←2
[16:37:06.255]接收←022-01-01-00-01-24-MON

[16:37:07.698]接收←2
[16:37:07.760]接收←022-01-01-00-01-25-MON

[16:38:59.328]接收←2
[16:38:59.375]接收←022-01-01-00-00-03-MON

用代码块功能插入代码,请勿粘贴截图。 不用代码块回答率下降 50%


#include <reg52.h>


sbit SegmentG1 = P2^3; //定义数码管1
sbit SegmentG2 = P2^2; //定义数码管2
sbit SegmentG3 = P2^1; //定义数码管3
sbit SegmentG4 = P2^0; //定义数码管4

int mode=1,tick=1,year=2022,month=1,m=0,day=1,hour=0,min=0,sec=1,w=0,ws=0;

static unsigned char s_arrNumber[] = {0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09}; //定义数码管显示数字0-9

static unsigned char arrmonth[]={31,29,31,30,31,30,31,31,30,31,30,31};
static unsigned char arrweek[7][3]={"MON","TUE","WED","THR","FRI","STA","SUN"};


static void DelayNms(int nms);
static void InitLED(void);


static void InitLED(void)
{
  P2 = 0xff;
}


static void DelayNms(int nms)
{
    unsigned int i,j;
    for(i=0;i<nms;i++)
    {
        for(j=0;j<123;j++)
     {
        
     }
  }
}


static void InitUART()
{
  SCON = 0x50;  //设置串口工作模式1,并打开接收允许
  TMOD = 0x20;  //设置定时器1工作模式2(8位自动重装载)
  PCON = 0x80;  //设置波特率加倍
  TL1 = 0xf3;   //设置定时器1 计数初值,波特率为4800
  TH1 = TL1;    //设置定时器1 重装载值,等于计数初值
  TR1 = 1;      //打开定时器1
}

static void InitInterrupt()
{
     IT0 = 1; //设置外部中断0触发方式为下降沿触发
  EX0 = 1; //打开外部中断0中断允许
  
  IT1 = 1; //设置外部中断1触发方式为下降沿触发
  EX1 = 1; //打开外部中断1中断允许x
    
  ES = 1; //打开串口接收中断允许
  EA = 1; //打开总中断允许
}

void main()
{
    unsigned char i,temp;
    int a,b,c,d;
    
  InitInterrupt(); //初始化中断
  InitUART();      //初始化串口
    InitLED();       //LED初始化
  while(1)
  {
        temp = ~0xef;
    //第一阶段,从1-3轮流点亮
    for(i = 0; i < 3; i++)
    {
      P2 = ~temp;
      DelayNms(200);            //延时200ms
      temp <<= 1;               //左移一位,轮流点亮
    }
    //第二阶段,从4-1轮流点亮
    for(i = 0; i < 3; i++)      //i<3 为了让循环流畅,i<4的时候上一循环结束跟下一循环开始为同一状态,耗时400ms
    {
      P2 = ~temp;               //取反是因为temp右移产生的是0
      DelayNms(200);            //延时200ms 
      temp >>= 1;               //右移一位,轮流点亮
    }
        
        
        
        
        
        
   DelayNms(50);
        
      tick++;
        sec=tick%60;
        if(sec==0)
        {
         min++;
         if(min==60)
         {
             min=0,hour++;
          if(hour==24)
          {
              hour=0;
               day++;
               ws++;
               w=ws%7;
               if(day>arrmonth[m])
              {
                 m++;month++;day=1;
                 if(m==13)
                 {
                     year++;
                     month=1,m=0;
                 }
              }
           }
          }
        }
        if(mode==1)
        {
            a=hour/10;
            b=hour%10;
            c=min/10;
            d=min%10;
        }
        else
        {
            a=month/10;
            b=month%10;
            c=day/10;
            d=day%10;
        }
        
        for(i=0;i<10;i++)
        {
        P0 = s_arrNumber[a]; //数码管1显示为数字1
    SegmentG1 = 0;       //打开数码管1
    DelayNms(5);         //延时5ms
    SegmentG1 = 1;       //关闭数码管1
    
    P0 = s_arrNumber[b]; //数码管2显示为数字2
    SegmentG2 = 0;       //打开数码管2
    DelayNms(5);         //延时5ms
    SegmentG2 = 1;       //关闭数码管2
    
    P0 = s_arrNumber[c]; //数码管3显示为数字3
    SegmentG3 = 0;       //打开数码管3
    DelayNms(5);         //延时5ms
    SegmentG3 = 1;       //关闭数码管3
    
    P0 = s_arrNumber[d]; //数码管4显示为数字4
    SegmentG4 = 0;       //打开数码管4
    DelayNms(5);         //延时5ms
    SegmentG4 = 1;       //关闭数码管4
        }
        
        SBUF= '\n';


  }// end of while(1)
}

void UART_Handler() interrupt 4
{
  
    unsigned char arrSBUF[24];
    unsigned char i;//用指针?
    
    arrSBUF[0]=(year/1000)+'0';
    arrSBUF[1]=(year%1000)/100+'0';
    arrSBUF[2]=(year%100)/10+'0';
    arrSBUF[3]=year%10+'0';
    arrSBUF[4]='-';
    
    arrSBUF[5]=month/10+'0';
    arrSBUF[6]=month%10+'0';
    arrSBUF[7]='-';
    
    arrSBUF[8]=day/10+'0';
    arrSBUF[9]=day%10+'0';
    arrSBUF[10]='-';
    
    arrSBUF[11]=hour/10+'0';
    arrSBUF[12]=hour%10+'0';
    arrSBUF[13]='-';
    
    arrSBUF[14]=min/10+'0';
    arrSBUF[15]=min%10+'0';
    arrSBUF[16]='-';
    
    arrSBUF[17]=sec/10+'0';
    arrSBUF[18]=sec%10+'0';
    arrSBUF[19]='-';
    
    arrSBUF[20]=arrweek[w][0];
    arrSBUF[21]=arrweek[w][1];
    arrSBUF[22]=arrweek[w][2];

  arrSBUF[23]='\n';

    for(i=0;i<24;i++)
    {
    SBUF = arrSBUF[i];; //将数据放入到寄存器
    while(!TI)  //等待发送数据完成
    {

        }            
        TI = 0;  //清除发送中断请求标志位
  }
}


void Exrernal0_Handler() interrupt 0
{
  mode= ~mode; //反转mode
}

运行结果及详细报错内容

这是串口接收到的:

[16:37:04.698]接收←2
[16:37:04.761]接收←022-01-01-00-01-23-MON

我的解答思路和尝试过的方法,不写自己思路的,回答率下降 60%

在main 函数里的while(1)
{
最后的SBUF= 可能对下面的产生了影响
}

我想要达到的结果,如果你需要快速回答,请尝试 “付费悬赏”

将2022放到同一行

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-11-24 18:09
    关注

    【以下回答由 GPT 生成】

    如何正确在串口助手上打印时间?

    根据问题描述,你想要在串口助手上打印显示时间,但遇到了一些问题。下面是解决这个问题的步骤和建议。

    1. 检查串口通信设置:首先,你需要确保串口通信设置是正确的,包括波特率、数据位、停止位和校验位等。你可以在代码中查找相关的设置。以下是一个示例:
    // 设置波特率为9600
    TMOD = 0x20;
    TH1 = 0xFD;
    SCON = 0x50;
    TR1 = 1;
    
    1. 处理接收的数据:接收到的数据似乎是没有按照你期望的格式进行解析,你需要对接收的数据进行处理。根据你的描述,可以尝试使用字符串操作函数(例如strtoksscanf)从接收的数据中提取时间和日期信息。

    下面是一个简单的示例,用于从接收的字符串中提取日期和时间信息:

    #include <stdio.h>
    #include <string.h>
    
    void processReceivedData(const char* data) {
      char date[11];
      char time[9];
      char weekday[4];
    
      // 提取日期和时间信息
      sscanf(data, "%10s-%8s-%3s", date, time, weekday);
    
      // 输出日期和时间到串口
      printf("日期:%s\n", date);
      printf("时间:%s\n", time);
      printf("星期:%s\n", weekday);
    }
    
    1. 格式化输出时间:使用C语言的标准库函数可以将日期和时间格式化为你期望的格式。下面是一个示例代码:
    #include <stdio.h>
    #include <time.h>
    
    void printFormattedTime() {
      time_t currentTime;
      struct tm *localTime;
      char formattedTime[30];
    
      // 获取当前时间
      currentTime = time(NULL);
      localTime = localtime(&currentTime);
    
      // 格式化时间
      strftime(formattedTime, sizeof(formattedTime), "%Y年%m月%d日 %H:%M:%S (周%a)", localTime);
    
      // 输出到串口
      printf("时间:%s\n", formattedTime);
    }
    
    1. 调试代码:在修改代码后,使用调试工具(如STM32CubeIDE)进行调试,逐步验证代码的正确性。

    切记,我无法确保问题绝对解决,因为问题可能出现在其他地方或者有其他不明确的因素。但是上述步骤应该能够帮助你识别和解决串口打印时间的问题。请根据你的具体情况和代码进行相应的调整和优化。



    【相关推荐】



    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 11月24日