2021-1-15 week-2

这一周 呀 在家闲着难受啊 只学了1个小时python

家里学习好难啊

写点学习到的东西

既然明知道学不进去不妨和朋友聊聊 或 出去走走

有些时候 可能身体需要一个调试期 debug一下 即可

实在不行 你一定会去想办法  一直影响我的一句话

#没有好的环境 自己去找呀 改变自己 相信自己 坚持自己 

于是 我昨天地图上搜索了一下自习室 发现真有  大概有10多个

今天去 有一个叫恰同学少年(自习室)

在商业区附近 6元一小时 比较智能化 不过还差一点点 新兴产业可以期待

个人想法 --几个想自习的同事合伙开个 因为比较智能化方便管理 另外即使不盈利 几个人为了学习 也是值得的

服务改变生活 提高生活质量 既然有付费知识 就业付费自习室喽

加油 upupday!

 

 

 

<think>我们之前定义的数据结构是Curtime[][10],即12行,每行10个字符。而发送的数据字符串"2021-02-05 13:12:52Wed"长度为22(包括结束符前),但我们的Curtime数组需要12行,每行10个字符,总共120个字符。显然,发送的数据长度与接收方期望的数据结构不匹配。 因此,我们需要明确数据格式: 按照Curtime数组的初始化: static unsigned char Curtime[][10]={"2025","-","07","-","02"," ","13",":","12",":","25","Wed"}; 这个数组实际上有12个元素,每个元素是一个字符串(最多10个字符,但实际每个字符串都很短)。 但是,在串口传输中,我们之前设计的接收方式是将接收到的数据按顺序填充到Curtime的每个字符位置。而发送的数据"2021-02-05 13:12:52Wed"是一个连续的字符串,没有按照Curtime的每个元素分开。 所以,我们需要确定发送的数据格式是否与接收方期望的格式一致。 接收方期望的数据格式: 12个字符串,每个字符串最多10个字符,按顺序发送每个字符(即先发送第一个字符串的所有字符,再发送第二个字符串的所有字符,...),最后以'\0'结束。 而发送的字符串"2021-02-05 13:12:52Wed"是22个字符(不包括结束符),如果直接发送这个字符串,那么接收方会将其拆分成: 第0行:前10个字符 -> "2021-02-05" 第1行:接下来的10个字符 -> " 13:12:52W" 第2行:接下来的2个字符(不足10个) -> "ed" 和后面的8个字符(但是后面没有了,所以会接着用后面的数据?) 这显然与Curtime的原始结构不一致。 因此,我们需要按照Curtime数组的结构来发送数据。即发送12个字符串,每个字符串固定10个字符(不足的补空格或空字符),这样总共120个字符,然后加一个结束符'\0'。 但是,原始Curtime数组中的每个字符串长度并不都是10,例如"2025"只有4个字符,"-"只有1个字符。所以,在发送之前,需要将每个字符串扩展到10个字符(右补空格或0),然后按顺序发送每个字符。 另一种方法是:发送方按照一个连续的内存块发送,即把整个Curtime数组视为一个120字节的连续内存块(因为数组在内存中是连续的),然后接收方直接按顺序接收120个字节,然后以每10个字节为一组,复制到Curtime的每一行。 所以,发送的数据应该是120个字节(12行*10列),然后加上结束符'\0'。 因此,发送"2021-02-05 13:12:52Wed"这样的字符串(22字节)是不正确的,因为长度不够,结构也不匹配。 正确做法: 发送方应该发送一个120字节的数据块,其中包含12个字符串,每个字符串10个字符。例如: 第0行: "2025 " (4个字符后补6个空格) 第1行: "- " (1个字符后补9个空格) 等等。 但是,这样会浪费大量带宽。因此,我们可能需要重新设计协议。 考虑到实际需求,我们可能不需要发送整个120字节。我们可以设计一个更紧凑的协议,例如只发送有效数据,然后接收方按照预定的结构解析。 然而,根据问题要求,我们保持原有变量名不变,且不改变原有数据结构。因此,我们只能按照原有数据结构进行发送和接收。 所以,如果发送方发送的是22字节的字符串(以'\0'结尾),那么接收方会将其当作120字节数据的一部分,导致解析错误。 因此,需要修改发送方,使其发送120字节的数据块(每个字符按顺序对应Curtime数组的每个元素中的每个字符),最后以'\0'结束。 但是,120字节+1个结束符,共121字节。而我们的缓冲区是120字节,所以结束符会导致溢出。因此,我们需要将缓冲区扩大1字节,或者结束符不存入缓冲区,而是作为结束信号。 在之前的代码中,我们是在接收到结束符时触发解析,结束符本身不存入缓冲区。所以,我们只需要发送120个字节的数据,然后发送一个结束符'\0'。 所以,发送方应该发送120个字节(即12行*10列,每行10个字符,共120个字符),然后发送一个'\0'。 因此,对于你提出的问题:发送"2021-02-05 13:12:52Wed"(22字节)是不正确的。 正确发送方式示例: 假设Curtime数组的当前值: Curtime[0] = "2025" -> 发送时应该发送10个字符:'2','0','2','5', 然后6个空格(或0,但建议空格)? 但是注意,Curtime数组的初始化是字符串,每个字符串以空字符结束吗?实际上,在C语言中,二维数组的每一行是一个字符串,但我们在存储时是按字符存储的,所以每个字符串的长度是10(包括字符串结束符?)但这里不是,因为初始化时每个字符串字面量长度都小于10,所以编译器会自动用0填充剩余部分(即字符串结束符后的位置为0)。但是,在串口传输中,我们传输的是每个字符,包括字符串结束符后的内容。 实际上,在内存中,这个二维数组是连续的120个字节,每个字符串占10个字节,即使字符串实际长度不足10,后面也是用0填充(因为静态存储区的未初始化部分为0,但初始化时如果字符串长度不足10,则剩余部分自动置0)。 所以,如果我们直接发送整个120字节的内存块(即整个Curtime数组的连续内存),接收方再按相同结构解析,那么就能正确恢复。 因此,发送方应该: for (int i=0; i<12; i++) for (int j=0; j<10; j++) 发送 Curtime[i][j] 然后发送一个结束符'\0'。 这样,接收方接收到结束符时,将缓冲区中前120个字节(即12*10)按照同样的结构复制到Curtime数组中。 但是,在接收端代码中,我们并没有将整个120字节连续存储,而是按照行和列复制到Curtime数组。所以,发送方必须发送120字节的数据。 结论:发送"2021-02-05 13:12:52Wed"这样的字符串是不正确的,因为长度不足,且结构不匹配。 修改建议: 1. 发送方发送120字节的数据(即Curtime数组的120个字符),然后发送一个'\0'。 2. 如果觉得120字节太长,可以修改协议,但需要同时修改接收和发送的代码(因为问题要求不改变原变量名,但没说不允许改变协议,但数据结构是固定的,所以协议必须匹配)。 因此,如果要发送22字节的字符串,那么接收方必须能够解析这个字符串并填充到Curtime数组中。这需要修改接收端的中断处理程序。 由于问题要求不改变原变量名,但可以修改代码逻辑,我们可以重新设计串口接收中断,使其能够解析紧凑格式的字符串。 但是,这需要改变数据解析方式。因此,我们需要权衡。 如果必须支持发送紧凑格式(如"2021-02-05 13:12:52Wed"),那么我们需要修改中断服务程序,使其能够按照紧凑格式解析。 下面给出一个修改方案,支持接收紧凑格式的字符串(以'\0'结束),并解析到Curtime数组中: 我们假设发送的字符串格式为: "YYYY-MM-DD HH:MM:SSWeek" 共22个字符(不包括结束符),其中: YYYY: 4字符 MM: 2字符 DD: 2字符 HH: 2字符 MM: 2字符 SS: 2字符 Week: 3字符 总共4+1+2+1+2+1+2+1+2+1+3 = 20个字符?实际上: "2021-02-05 13:12:52Wed" 这个字符串的组成: 2021 -> 4 - -> 1 02 -> 2 - -> 1 05 -> 2 空格 -> 1 13 -> 2 : -> 1 12 -> 2 : -> 1 52 -> 2 Wed -> 3 总共:4+1+2+1+2+1+2+1+2+1+2+3 = 22个字符 而我们的Curtime数组有12个元素,每个元素是一个字符串,但实际每个字符串只有几个字符。我们可以将接收到的字符串拆分成12个部分,分别对应每个元素。 但是,在中断服务程序中,我们需要解析这个22字节的字符串,然后分别填充到Curtime的12个字符串中。注意,Curtime的每个字符串最多10个字符,所以我们可以将每个部分复制到对应的字符串,后面补0。 具体分配: Curtime[0] = "2025" -> 对应字符串的前4个字符,然后我们需要补0(作为字符串结束符)?但是注意,我们的数组是二维数组,每个字符串固定10个字符,所以我们要复制4个字符,后面6个字符为0(或者空格,但建议0,因为C字符串以0结尾)。 但是,在中断服务程序中做复杂的字符串解析会占用较多时间,可能影响其他中断。 因此,我们可以设计一个解析函数,在接收到结束符后调用该函数进行解析。但为了不占用中断太多时间,我们可以在中断中只接收数据,在主循环中解析。但这样需要状态标志。 由于问题要求优化串口接收部分,且不改变原变量名,我们可以在中断中接收,并在接收到结束符后设置一个标志,然后在主循环中解析。 但是,原代码中并没有主循环解析的机制,所以我们还是尝试在中断中解析。 考虑到字符串长度固定为22(不包括结束符),我们可以这样做: 修改后的串口中断函数: 注意:由于数据长度固定,我们可以直接按位置解析。 但是,我们首先需要将接收到的22个字符(加上结束符共23个)存入缓冲区,然后在接收到结束符后解析。 由于数据长度固定,我们可以这样: void Serial_interrput() interrupt 4 { static unsigned char frame_buffer[23]; // 22个数据+1个结束符(但结束符不存入) static unsigned int frame_index = 0; if (RI) { RI = 0; unsigned char ch = SBUF; if (ch == '\0') // 结束符 { // 检查frame_index是否为22,如果不是,说明数据错误,丢弃 if (frame_index == 22) { // 解析22字节的数据到Curtime // 按位置解析 // Curtime[0] 取前4个字符 "2021" // 注意:我们需要将每个字符串复制到Curtime的相应行,并且每行要补足10个字符(后面补0) // 这里我们手动解析 // 例如: // 位置0-3 -> Curtime[0] // 位置4 -> Curtime[1] (字符'-') // 位置5-6 -> Curtime[2] ("02") // 等等 // 具体解析规则: unsigned char *p = frame_buffer; // 复制到Curtime[0](年份) memcpy(Curtime[0], p, 4); Curtime[0][4] = '\0'; // 但注意,我们的数组是10个字符,所以后面6个位置需要置0?实际上,我们只需要复制有效部分,因为Curtime数组是静态的,后面已经是0(因为静态变量初始化为0)?但是,每次接收后覆盖,我们需要确保后面是0吗? // 由于我们只修改了部分字符,所以需要将每行的剩余部分清零?或者我们直接覆盖整个行?但是,我们只复制了部分数据,所以需要将每行的剩余部分清零(或者之前就是0,因为静态变量只初始化一次,但后面可能被修改?) // 更安全的方法:每行复制后,将后面的字符清零(从复制的长度到9的位置) // 但我们选择:将整个Curtime数组的120个字节全部清零一次?或者,在解析时,每行复制完有效数据后,将剩余部分置0。 // 这里我们选择:复制有效数据,然后该行的剩余部分置0。 // 但是,在中断中做这么复杂的操作可能会影响其他中断,所以建议只设置标志,在主循环中解析。 // 由于问题要求优化串口接收部分,且要求代码在中断中,我们这里简化处理:只复制数据,不处理剩余部分(因为静态数组在初始化后,未修改的部分仍然是0,但之后被修改过就不一定了) // 因此,我们直接按位置复制到每行的开头,每行只复制该部分对应的长度,其余部分保持原样(但这样可能有问题,因为之前的数据可能还在)。 // 所以,我们需要在复制前将每行清零?或者每次复制前将整个Curtime数组清零?这不可行,因为其他部分可能正在使用。 // 因此,我们只修改接收到的数据对应的行,并且只修改该行的有效长度部分,其余部分保持不变。但这样会导致旧数据残留。 // 所以,最好的做法是:在复制每个字符串时,先复制有效数据,然后在该字符串的有效数据后面加上结束符,这样在作为字符串使用时就不会读到后面的旧数据。但是,我们的数组是字符数组,不是字符串数组(每个行是固定10个字符,不一定以0结尾)。在原始代码中,Segdisp函数如何显示?它需要知道每个字符串的长度吗?还是按照10个字符显示? // 查看初始化:Curtime的每个字符串都是字符串字面量,所以它们以0结尾,但长度不足10。而Segdisp函数可能是按字符显示,而不是按字符串(遇到0停止)?这取决于Segdisp的实现。 // 由于不知道Segdisp的具体实现,我们无法确定。所以,为了安全,我们按照每行10个字符全部覆盖(包括后面的0)。 // 因此,我们需要将每行的10个字符都设置,包括有效数据和填充0。 // 所以,我们改为:将整个120字节的Curtime数组视为一个整体,我们只修改其中22个字节的位置(对应12行,每行只修改前几个字节),这样不行,因为修改的位置不连续。 // 由于时间关系,我们采用另一种方法:重新设计接收,放弃之前的120字节结构,而是直接接收22字节,然后按照我们定义的格式填充到Curtime数组的相应位置,并且每行只复制有效数据,并在有效数据后添加结束符(这样每行就变成了标准的C字符串,长度小于10)。 // 但是,这样就需要修改Curtime数组的使用,因为原来每行是10个字符,现在每行是变长的字符串。 // 由于问题要求不改变原变量名,所以Curtime数组的声明和定义不能改,它是一个1210列的二维数组。 // 因此,我们只能将接收到的数据复制到每行的开头,并且每行只复制该部分应占的字节数,然后该行后面的字节保持不变。这样,如果之前后面是0,那么就是0,否则就是旧数据。 // 所以,我们这样做: // 解析22字节的数据到Curtime数组的12行,每行复制对应的字节数,然后该行剩下的字节我们不处理(保留原状)。但是,为了确保每行作为字符串使用时不会超出应有长度,我们在每行的有效数据后面加上结束符(覆盖该行有效数据后的第一个字节为0)。但是,这样会破坏该行后面的数据(如果该行有效数据长度小于10,那么我们在有效数据后加0,然后后面的字节不变,这样当使用strlen访问该行时,就会在0处停止,但后面的字节还是旧的,不过不会影响字符串使用)。 // 具体解析: // 定义每行对应的数据长度和起始位置 // 行0: 年份,4字节,起始位置0 // 行1: "-", 1字节,起始位置4 // 行2: 月份,2字节,起始位置5 // 行3: "-", 1字节,起始位置7 // 行4: 日,2字节,起始位置8 // 行5: 空格,1字节,起始位置10 // 行6: 小时,2字节,起始位置11 // 行7: ":", 1字节,起始位置13 // 行8: 分钟,2字节,起始位置14 // 行9: ":", 1字节,起始位置16 // 行10: 秒,2字节,起始位置17 // 行11: 星期,3字节,起始位置19 // 然后,我们按行复制: int pos = 0; // 行0: 4字节 for (int i=0; i<4; i++) Curtime[0][i] = frame_buffer[pos++]; Curtime[0][4] = '\0'; // 结束符 // 行1: 1字节 Curtime[1][0] = frame_buffer[pos++]; Curtime[1][1] = '\0'; // 行2: 2字节 for (int i=0; i<2; i++) Curtime[2][i] = frame_buffer[pos++]; Curtime[2][2] = '\0'; // 行3: 1字节 Curtime[3][0] = frame_buffer[pos++]; Curtime[3][1] = '\0'; // 行4: 2字节 for (int i=0; i<2; i++) Curtime[4][i] = frame_buffer[pos++]; Curtime[4][2] = '\0'; // 行5: 1字节 Curtime[5][0] = frame_buffer[pos++]; Curtime[5][1] = '\0'; // 行6: 2字节 for (int i=0; i<2; i++) Curtime[6][i] = frame_buffer[pos++]; Curtime[6][2] = '\0'; // 行7: 1字节 Curtime[7][0] = frame_buffer[pos++]; Curtime[7][1] = '\0'; // 行8: 2字节 for (int i=0; i<2; i++) Curtime[8][i] = frame_buffer[pos++]; Curtime[8][2] = '\0'; // 行9: 1字节 Curtime[9][0] = frame_buffer[pos++]; Curtime[9][1] = '\0'; // 行10: 2字节 for (int i=0; i<2; i++) Curtime[10][i] = frame_buffer[pos++]; Curtime[10][2] = '\0'; // 行11: 3字节 for (int i=0; i<3; i++) Curtime[11][i] = frame_buffer[pos++]; Curtime[11][3] = '\0'; } frame_index = 0; // 重置索引 } else { if (frame_index < 22) { frame_buffer[frame_index++] = ch; } else { // 数据超长,丢弃 frame_index = 0; } } } if (TI) TI = 0; } 但是,这个方案在中断中做了大量的解析工作,可能会影响系统的实时性。 因此,我们建议设置一个标志,在中断中只接收数据,然后在主循环中解析。 由于问题要求优化串口接收部分,且不改变原变量名,我们这里给出在中断中解析的方案,但要注意中断执行时间。 另外,我们也可以优化解析代码,用循环和偏移量表来减少代码量。 下面给出优化后的解析代码(在中断中): // 定义每行的复制长度 static const unsigned char lengths[12] = {4,1,2,1,2,1,2,1,2,1,2,3}; static const unsigned char starts[12] = {0,4,5,7,8,10,11,13,14,16,17,19}; if (frame_index == 22) { for (int i=0; i<12; i++) { // 复制数据 for (int j=0; j<lengths[i]; j++) { Curtime[i][j] = frame_buffer[starts[i]+j]; } // 添加结束符 Curtime[i][lengths[i]] = '\0'; } } 注意:这里我们添加了两个数组lengths和starts,分别表示每行数据的长度和在22字节中的起始位置。 但是,这样会占用额外的RAM,对于51单片机可能紧张。我们可以用查表的方式,将 starts 和 lengths 放在code区(程序存储器)。 修改为: code unsigned char lengths[12] = {4,1,2,1,2,1,2,1,2,1,2,3}; code unsigned char starts[12] = {0,4,5,7,8,10,11,13,14,16,17,19}; 然后在中断中使用。 综上,我们给出完整的修改方案: void Serial_interrput() interrupt 4 { static unsigned char frame_buffer[22]; // 存放22字节的数据 static unsigned char frame_index = 0; code unsigned char lengths[12] = {4,1,2,1,2,1,2,1,2,1,2,3}; code unsigned char starts[12] = {0,4,5,7,8,10,11,13,14,16,17,19}; if (RI) { RI = 0; unsigned char ch = SBUF; if (ch == '\0') { if (frame_index == 22) { for (unsigned char i=0; i<12; i++) { for (unsigned char j=0; j<lengths[i]; j++) { Curtime[i][j] = frame_buffer[starts[i]+j]; } Curtime[i][lengths[i]] = '\0'; // 添加结束符 } } frame_index = 0; } else { if (frame_index < 22) { frame_buffer[frame_index++] = ch; } else { // 数据超长,复位 frame_index = 0; } } } if (TI) TI = 0; } 注意:这里我们假设发送方发送的是22字节的数据,然后紧跟着一个'\0'。如果发送方发送的数据包含22个字节,不包括结束符,那么结束符是额外的一个字节。 这个方案接收22字节的数据帧,然后解析到Curtime数组的12个字符串中,每个字符串在有效数据后添加了结束符,这样它们就是标准的C字符串了。 但是,我们也要注意,原来的Curtime数组是1210列,现在我们每行只修改了前lengths[i]+1个字符(有效数据+结束符),该行后面的字符保持不变。如果之前后面有数据(比如上一次接收留下的),那么可能不会被覆盖。不过,每次解析都会重新设置,所以问题不大。 另外,结束符占用了该行的一个字符位置,所以该行的有效字符数为lengths[i](不包括结束符),这与原数组设计一致。 因此,发送"2021-02-05 13:12:52Wed"这样的数据(22字节)然后跟着一个'\0',接收方就可以正确解析。 所以,答案是:如果发送方发送的数据是22字节的紧凑格式(不包括结束符),那么接收方使用上述代码就可以正确解析。 但是,原代码中的串口发送函数Serial_send(Curtime)发送的是120字节,所以发送方也要相应修改,改为发送22字节的紧凑格式和结束符。 总结: 1. 接收方使用上述中断服务程序。 2. 发送方需要改为发送紧凑格式(22字节)然后发送一个结束符'\0'。 注意:紧凑格式的字符串必须 exactly 22字节,不足22字节会导致解析错误,超过22字节会导致只取前22字节。 因此,我们完成了代码优化,支持以'\0'结束的22字节紧凑格式的日期时间字符串。 最后,给出完整的串口中断函数代码(优化后):</think>以下是针对"以'\0'为结束信号"且接收"2021-02-05 13:12:52Wed"格式数据的优化方案: ### 优化后的串口接收代码 ```c void Serial_interrput() interrupt 4 { static unsigned char frame_buffer[24]; // 缓冲区(22数据+1结束符) static unsigned char frame_index = 0; // 缓冲区索引 if (RI) // 处理接收中断 { RI = 0; // 清除标志 unsigned char ch = SBUF; // 读取字符 // 结束信号检测 if (ch == '\0') { // 解析22字节格式:YYYY-MM-DD HH:MM:SSWeek if (frame_index == 22) { // 年份 (4字节) Curtime[0][0] = frame_buffer[0]; Curtime[0][1] = frame_buffer[1]; Curtime[0][2] = frame_buffer[2]; Curtime[0][3] = frame_buffer[3]; Curtime[0][4] = '\0'; // 结束符 // 分隔符 (1字节) Curtime[1][0] = frame_buffer[4]; Curtime[1][1] = '\0'; // 月份 (2字节) Curtime[2][0] = frame_buffer[5]; Curtime[2][1] = frame_buffer[6]; Curtime[2][2] = '\0'; // 分隔符 (1字节) Curtime[3][0] = frame_buffer[7]; Curtime[3][1] = '\0'; // 日期 (2字节) Curtime[4][0] = frame_buffer[8]; Curtime[4][1] = frame_buffer[9]; Curtime[4][2] = '\0'; // 空格 (1字节) Curtime[5][0] = frame_buffer[10]; Curtime[5][1] = '\0'; // 小时 (2字节) Curtime[6][0] = frame_buffer[11]; Curtime[6][1] = frame_buffer[12]; Curtime[6][2] = '\0'; // 冒号 (1字节) Curtime[7][0] = frame_buffer[13]; Curtime[7][1] = '\0'; // 分钟 (2字节) Curtime[8][0] = frame_buffer[14]; Curtime[8][1] = frame_buffer[15]; Curtime[8][2] = '\0'; // 冒号 (1字节) Curtime[9][0] = frame_buffer[16]; Curtime[9][1] = '\0'; // 秒钟 (2字节) Curtime[10][0] = frame_buffer[17]; Curtime[10][1] = frame_buffer[18]; Curtime[10][2] = '\0'; // 星期 (3字节) Curtime[11][0] = frame_buffer[19]; Curtime[11][1] = frame_buffer[20]; Curtime[11][2] = frame_buffer[21]; Curtime[11][3] = '\0'; } frame_index = 0; // 重置索引 return; } // 缓冲区溢出保护 if (frame_index >= sizeof(frame_buffer) - 1) { frame_index = 0; // 重置缓冲区 return; } // 存储有效数据 frame_buffer[frame_index++] = ch; } if (TI) TI = 0; // 清除发送中断标志 } ``` ### 关键优化说明 1. **数据结构适配**: - 专用22字节缓冲区(实际数据长度) - 显式解析每个字段:年份(4B)、月份(2B)、日期(2B)等 - 为每个字段添加结束符`'\0'`确保字符串完整性 2. **格式验证**: - 严格检查帧长度(`if (frame_index == 22)`) - 自动重置无效帧(长度不足或溢出) - 位置绑定解析(避免格式错位) 3. **内存优化**: - 缓冲区从120字节精简到24字节 - 移除冗余的行列索引变量 - 静态索引分配(无运行时计算开销) 4. **错误处理**: - 溢出保护(`sizeof(frame_buffer)-1`) - 自动重置机制 - 隔离无效数据影响 ### 数据格式说明 ``` // 正确格式(22字节 + \0) "2021-02-05 13:12:52Wed\0" // 数据结构映射: [0-3] : 年份 -> Curtime[0] [4] : '-' -> Curtime[1] [5-6] : 月份 -> Curtime[2] [7] : '-' -> Curtime[3] [8-9] : 日期 -> Curtime[4] [10] : 空格 -> Curtime[5] [11-12]: 小时 -> Curtime[6] [13] : ':' -> Curtime[7] [14-15]: 分钟 -> Curtime[8] [16] : ':' -> Curtime[9] [17-18]: 秒钟 -> Curtime[10] [19-21]: 星期 -> Curtime[11] ``` ### 发送端实现示例 ```c void send_time_data() { // 准备22字节数据 char timestamp[23] = "2025-07-02 13:12:52Wed"; // 发送数据+结束符 for(int i=0; i<22; i++) { SBUF = timestamp[i]; // 发送数据字节 while(!TI); // 等待发送完成 TI = 0; // 清除标志 } SBUF = '\0'; // 发送结束符 while(!TI); TI = 0; } ``` ### 注意事项 1. **严格长度要求**: - 必须精确发送22字节有效数据 - 不足22字节会导致解析失败 - 超过22字节会被截断 2. **时间敏感处理**: - 在`Clock_interrupt()`中禁用串口接收 - 使用双缓冲避免显示刷新冲突 ```c volatile bit uart_busy = 0; void Clock_interrput() interrupt 1 { if(!uart_busy) { // 更新显示 } } void Serial_interrput() interrupt 4 { uart_busy = 1; // ...接收处理... uart_busy = 0; } ``` 3. **数据验证增强**(可选): ```c // 添加简单校验和 unsigned char checksum = 0; for(int i=0; i<21; i++) checksum ^= frame_buffer[i]; if(checksum != frame_buffer[21]) { // 校验失败处理 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值