找回密码
 立即注册
查看: 1322|回复: 17

学习串口调用STC调试接口

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-2-1 10:48:58 | 显示全部楼层 |阅读模式
之前研究了如何通过串口命令来进行不断电烧录程序,减少了每次烧录测试代码之前需要手动重启mcu的工作量后,调试代码功能舒服多了!

接下来进行测试STC的各个调试接口
这块STC已有封装好的库,但是自己再实现一遍,能锻炼能力的同时,加深对串口通信的理解
STC调试接口协议是模态对话框,用着不方便,我直接拿到了对应的html文件

STCE642.html

218.6 KB, 下载次数: 114

STC调试接口协议

回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-2-1 11:00:32 | 显示全部楼层
先实现串口通信中的缓存数据模块C_BUFF.h
定义BUFF_DATA的结构体,并实现对其的pop,push,reset,Has_Data,copy的操作
pop:读取1字节数据
push:写入1字节数据
has_data:判断是否有数据
reset:清空数据
cpy:复制一个buff_data的数据到另一个buff_data
  1. #ifndef C_BUFF_H
  2. #define C_BUFF_H
  3. #include "STC\STC8H.h"
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. //buff_size 必须是2的倍数-1
  7. #define BUFF_SIZE 0x0f
  8. struct BUFF_DATA
  9. {
  10.     uchar rptr;
  11.     uchar wptr;
  12.     char buff[BUFF_SIZE+1];
  13. };
  14. #define BUFF_POP(x,d) d=x.buff[x.rptr++];x.rptr&=BUFF_SIZE
  15. #define BUFF_PUSH(x,d) x.buff[x.wptr++] = d;x.wptr&=BUFF_SIZE
  16. #define BUFF_HAS_DATA(x) (x.rptr != x.wptr)
  17. #define BUFF_RESET(x) x.rptr=0;x.wptr=0
  18. #define BUFF_CPY(src,dest) while(BUFF_HAS_DATA(src)){dest.buff[dest.wptr++] = src.buff[src.rptr++];src.rptr&=BUFF_SIZE;dest.wptr&=BUFF_SIZE;}
  19. #define PBUFF_POP(x,d) d=x->buff[x->rptr++];x->rptr&=BUFF_SIZE
  20. #define PBUFF_PUSH(x,d) x->buff[x->wptr++] = d;x->wptr&=BUFF_SIZE
  21. #define PBUFF_HAS_DATA(x) (x->rptr != x->wptr)
  22. #define PBUFF_RESET(x) x->rptr=0;x->wptr=0
  23. #define PBUFF_CPY(src,dest) while(PBUFF_HAS_DATA(src)){dest->buff[dest->wptr++] = src->buff[src->rptr++];src->rptr&=BUFF_SIZE;dest->wptr&=BUFF_SIZE;}
  24. #endif //C_BUFF_H
复制代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-2-1 11:03:12 | 显示全部楼层
串口通信模块的头文件C_UART.h:
UartSend 是发送1字节的数据
UartSendStr 是发送字符串数据,以\0结尾
UartSendData 是发送指定长度的数据
UartReceived 是接收串口数据,如果返回1,则表示有数据,返回0表示未收到数据,接收的数据储存在str_buff中
  1. #ifndef C_UART_H
  2. #define C_UART_H
  3. #include "C_BUFF.h"
  4. extern struct BUFF_DATA xdata str_buff;
  5. void Delay1ms(void);        //@5.5296MHz
  6. void Delay_ms(uint times);        //@5.5296MHz
  7. void Uart1_Init(void);        //19200bps@5.5296MHz
  8. void UartSend(char dat);
  9. void UartSendStr(const char *p);
  10. void UartSendData(const char *p,uchar len);
  11. bit UartReceived(); //串口接收数据,如果返回1,则表示有数据,返回0表示未收到数据,接收的数据储存在str_buff中
  12. #endif //C_UART_H
复制代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-2-1 11:06:52 | 显示全部楼层
串口通信模块的实现:C_UART.c
send_busy 用来判断是否发送繁忙
recv_timeout 用来检测一次数据是否接收完成

uart_buff 是串口数据缓存
str_buff 是接收的数据的缓存

UartReceived中会判断,如果recv_timeout>0,则代表接收到了数据,然后循环将数据存入str_buff中,直到对方发送结束,并返回1代表有数据
  1. #include "C_UART.h"
  2. #include "INTRINS.H"
  3. bit send_busy;
  4. uchar recv_timeout;
  5. struct BUFF_DATA xdata uart_buff,xdata str_buff;
  6. void Delay1ms(void)        //@5.5296MHz
  7. {
  8.         unsigned char data i, j;
  9.         _nop_();
  10.         _nop_();
  11.         i = 8;
  12.         j = 43;
  13.         do
  14.         {
  15.                 while (--j);
  16.         } while (--i);
  17. }
  18. void Delay_ms(uint times)        //@5.5296MHz
  19. {
  20.         unsigned char data i, j;
  21.     while (times-->0)
  22.     {
  23.        _nop_();
  24.         _nop_();
  25.         i = 8;
  26.         j = 43;
  27.         do
  28.         {
  29.             while (--j);
  30.         } while (--i);
  31.     }
  32. }
  33. void Uart1_Isr(void) interrupt 4
  34. {
  35.         if (TI)                               
  36.         {
  37.                 TI = 0;                       
  38.         send_busy = 0;
  39.         }
  40.         if (RI)                               
  41.         {
  42.                 RI = 0;                       
  43.         BUFF_PUSH(uart_buff,SBUF);
  44.         recv_timeout = 5;
  45.         }
  46. }
  47. void Uart1_Init(void)        //19200bps@5.5296MHz
  48. {
  49.         SCON = 0x50;                //8位数据,可变波特率
  50.         AUXR &= 0xBF;                //定时器时钟12T模式
  51.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  52.         TMOD &= 0x0F;                //设置定时器模式
  53.         TL1 = 0xFA;                        //设置定时初始值
  54.         TH1 = 0xFF;                        //设置定时初始值
  55.         ET1 = 0;                        //禁止定时器中断
  56.         TR1 = 1;                        //定时器1开始计时
  57.         ES = 1;                                //使能串口1中断
  58.     EA = 1;
  59.     send_busy = 0;
  60.     BUFF_RESET(uart_buff);
  61. }
  62. void UartSend(char dat)
  63. {
  64.     while(send_busy);
  65.     send_busy = 1;
  66.     SBUF = dat;
  67. }
  68. void UartSendStr(const char *p)
  69. {
  70.     while(*p)
  71.         UartSend(*p++);
  72. }
  73. void UartSendData(const char *p,uchar len)
  74. {
  75.     while (len-->0)
  76.         UartSend(*p++);
  77. }
  78. //串口接收数据,如果返回1,则表示有数据,返回0表示未收到数据,接收的数据储存在str_buff中
  79. bit UartReceived()
  80. {
  81.     if(recv_timeout>0)
  82.     {
  83.         BUFF_RESET(str_buff);
  84.         while(recv_timeout>0)
  85.         {
  86.             BUFF_CPY(uart_buff,str_buff)
  87.             recv_timeout--;
  88.             Delay1ms();
  89.         }
  90.         BUFF_PUSH(str_buff,0);
  91.         return 1;
  92.     }
  93.     return 0;
  94. }
复制代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-2-1 11:09:05 | 显示全部楼层
主函数中循环接收,并调用UartSendStr处理数据
  1. #include "C_UART.h"
  2. #include "C_STC_TOOLS.h"
  3. #include <STRING.H>
  4. void DealString(char *p)
  5. {
  6.     if(strcmp(p,"hello") == 0)
  7.     {
  8.         UartSendStr("world!");
  9.     }
  10.     else if(strcmp(p,"reboot") == 0)
  11.     {
  12.         Delay_ms(1000);
  13.         UartSendStr("bye!");
  14.         IAP_CONTR = 0x60;
  15.     }
  16.     else
  17.     {
  18.         UartSendStr(p);
  19.     }
  20. }
  21. void main()
  22. {
  23.     Uart1_Init();
  24.    
  25.     UartSendStr("Uart Test!\r\n");
  26.     while(1)
  27.     {
  28.         if(UartReceived())
  29.             DealString(str_buff.buff);
  30.         Delay1ms();
  31.     }
  32. }
复制代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-2-1 11:13:43 | 显示全部楼层
现在先测试STC调试接口的 功能1:        在数码管上显示字符串
新建C_STC_TOOLS.h
添加函数void STC_SEG7_ShowString(const char *str);
  1. #ifndef C_STC_TOOLS_H
  2. #define C_STC_TOOLS_H
  3. //功能1:        在数码管上显示字符串
  4. void STC_SEG7_ShowString(const char *str);
  5. #endif //C_STC_TOOLS_H
复制代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-2-1 11:17:42 | 显示全部楼层
在C_STC_TOOLS.c中发送对应的数据
先设置8位的头信息,然后复制需要发送的数据,因为数码管只能显示8个数字,所以我们最多复制8字节数据就break,然后将最后一位置0,并调用串口发送
这里一定要调用UartSendData函数,而不是UartSendStr函数,因为UartSendStr会在字符串有'\0'的时候就停止发送,导致实际发送的数据只有 37H 53H 45H 47H 53H
之前我就是犯了这个错误,导致一直不显示
  1. #include "C_STC_TOOLS.h"
  2. #include "C_UART.h"
  3. #define L_BUFF_LEN 64
  4. char xdata stc_buff[L_BUFF_LEN];
  5. uchar pos;
  6. //功能1:        在数码管上显示字符串
  7. void STC_SEG7_ShowString(const char *str)
  8. {
  9.     stc_buff[0] = 0x37;
  10.     stc_buff[1] = 0x53;
  11.     stc_buff[2] = 0x45;
  12.     stc_buff[3] = 0x47;
  13.     stc_buff[4] = 0x53;
  14.     stc_buff[5] = 0x00;
  15.     stc_buff[6] = 0x00;
  16.     stc_buff[7] = 0x00;
  17.     for(pos=8;pos<16;pos++)
  18.     {
  19.         if(*str)
  20.             stc_buff[pos] = *str++;
  21.         else
  22.             break;
  23.     }
  24.     stc_buff[pos] = 0;
  25.     UartSendData(stc_buff,pos+1);
  26. }
复制代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-2-1 11:19:49 | 显示全部楼层
主函数中接收串口信息判断,如果是以seg开头,则测试数码管的功能
  1. void DealString(char *p)
  2. {
  3.     if(strcmp(p,"hello") == 0)
  4.     {
  5.         UartSendStr("world!");
  6.     }
  7.     else if(strcmp(p,"reboot") == 0)
  8.     {
  9.         Delay_ms(1000);
  10.         UartSendStr("bye!");
  11.         IAP_CONTR = 0x60;
  12.     }
  13.     else if(strncmp(p,"seg",3) == 0)
  14.     {
  15.         STC_SEG7_ShowString(p+3);
  16.     }
  17.     else
  18.     {
  19.         UartSendStr(p);
  20.     }
  21. }
复制代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-2-1 11:20:53 | 显示全部楼层
烧录,打开串口测试,发送seg12.3.3后,能正常在数码管上显示
1.png
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:247
  • 最近打卡:2025-02-25 19:02:50

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-2-1 11:24:43 | 显示全部楼层
我发现  数据中的.不进行占位,且不管多少'.'连一起就只显示一个'.',如果强制按只发送8位来算,那么无法输出1.2.3.4.5.6.7.8这样的数据,我们得对应修改下STC_SEG7_ShowString的逻辑
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-7 03:11 , Processed in 0.134819 second(s), 102 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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