找回密码
 立即注册
查看: 1704|回复: 13

STC8H8K64U-软件实现串口不断电烧录程序

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

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-1-31 19:15:24 | 显示全部楼层 |阅读模式
本帖最后由 challis 于 2024-2-1 08:45 编辑

主要原理是利用识别串口命令后进行软件复位,操作IAP_CONTR寄存器来重启芯片后从ISP区开始执行代码,来实现不断电烧录程序
完整代码在14楼
回复

使用道具 举报 送花

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

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-1-31 19:16:21 | 显示全部楼层
首先,利用STC工具,生成5.5296MHz,波特率为19200的串口代码
  1. void Uart1_Isr(void) interrupt 4
  2. {
  3.         if (TI)                                //检测串口1发送中断
  4.         {
  5.                 TI = 0;                        //清除串口1发送中断请求位
  6.         }
  7.         if (RI)                                //检测串口1接收中断
  8.         {
  9.                 RI = 0;                        //清除串口1接收中断请求位
  10.         }
  11. }
  12. void Uart1_Init(void)        //19200bps@5.5296MHz
  13. {
  14.         SCON = 0x50;                //8位数据,可变波特率
  15.         AUXR &= 0xBF;                //定时器时钟12T模式
  16.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  17.         TMOD &= 0x0F;                //设置定时器模式
  18.         TL1 = 0xFA;                        //设置定时初始值
  19.         TH1 = 0xFF;                        //设置定时初始值
  20.         ET1 = 0;                        //禁止定时器中断
  21.         TR1 = 1;                        //定时器1开始计时
  22.         ES = 1;                                //使能串口1中断
  23. }
复制代码
回复 支持 反对

使用道具 举报 送花

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

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-1-31 19:27:24 | 显示全部楼层
构造结构体做缓存,用来缓存接收的数据
  1. struct BUFF_DATA
  2. {
  3.     uchar rptr;
  4.     uchar wptr;
  5.     char buff[256];
  6. };
复制代码
回复 支持 反对

使用道具 举报 送花

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

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-1-31 19:29:25 | 显示全部楼层
定义如果5ms没有收到数据,则输出传输完成.
使用双缓冲机制,uart_buff用来缓存串口接收到的信息,str_buff用来储存一条一条的命令
新建2个BUFF_DATA的对象,并且定义一些常用操作宏
  1. struct BUFF_DATA xdata uart_buff,xdata str_buff;
  2. #define BUFF_POP(x) x.buff[x.rptr++]
  3. #define BUFF_PUSH(x,d) x.buff[x.wptr++] = d
  4. #define BUFF_HAS_DATA(x) (x.rptr != x.wptr)
  5. #define BUFF_RESET(x) x.rptr=0;x.wptr=0
复制代码
回复 支持 反对

使用道具 举报 送花

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

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-1-31 19:30:49 | 显示全部楼层
串口中断中逻辑为:如果发送完成,则将TI置0,且设置send_busy=0;
如果接收到数据,则将RI置0,且将数据存入缓存,将timeout置为5;
  1. void Uart1_Isr(void) interrupt 4
  2. {
  3.         if (TI)                               
  4.         {
  5.                 TI = 0;                       
  6.         send_busy = 0;
  7.         }
  8.         if (RI)                               
  9.         {
  10.                 RI = 0;                       
  11.         BUFF_PUSH(uart_buff,SBUF);
  12.         recv_timeout = 5;
  13.         }
  14. }
复制代码
回复 支持 反对

使用道具 举报 送花

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

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-1-31 19:31:32 | 显示全部楼层
串口初始化中添加设置send_busy=0;且初始化uart_buff
  1. void Uart1_Init(void)        //19200bps@5.5296MHz
  2. {
  3.         SCON = 0x50;                //8位数据,可变波特率
  4.         AUXR &= 0xBF;                //定时器时钟12T模式
  5.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  6.         TMOD &= 0x0F;                //设置定时器模式
  7.         TL1 = 0xFA;                        //设置定时初始值
  8.         TH1 = 0xFF;                        //设置定时初始值
  9.         ET1 = 0;                        //禁止定时器中断
  10.         TR1 = 1;                        //定时器1开始计时
  11.         ES = 1;                                //使能串口1中断
  12.     EA = 1;
  13.     send_busy = 0;
  14.     BUFF_RESET(uart_buff);
  15. }
复制代码
回复 支持 反对

使用道具 举报 送花

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

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-1-31 19:32:10 | 显示全部楼层
实现串口发送函数,发送前检测,如果send_busy,则等待
  1. void UartSend(char dat)
  2. {
  3.     while(send_busy);
  4.     send_busy = 1;
  5.     SBUF = dat;
  6. }
  7. void UartSendStr(char *p)
  8. {
  9.     while(*p)
  10.         UartSend(*p++);
  11. }
复制代码
回复 支持 反对

使用道具 举报 送花

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

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-1-31 19:34:15 | 显示全部楼层
主函数中循环处理,如果recv_timeout>0,则证明接收到了数据,这时,循环将串口缓存的数据取出,放入字符串缓存中,直到传输超时.传输超时则认为命令传输完成,则调用DealString函数进行处理
  1. while(1)
  2.     {
  3.         if(recv_timeout>0)
  4.         {
  5.             BUFF_RESET(str_buff);
  6.             while(recv_timeout>0)
  7.             {
  8.                 while(BUFF_HAS_DATA(uart_buff))
  9.                 {
  10.                     tmp = BUFF_POP(uart_buff);
  11.                     BUFF_PUSH(str_buff,tmp);
  12.                 }
  13.                 recv_timeout--;
  14.                 Delay1ms();
  15.             }
  16.             BUFF_PUSH(str_buff,0);
  17.             DealString(str_buff.buff);
  18.         }
  19.         /*if(BUFF_HAS_DATA(uart_buff))
  20.         {
  21.             UartSend(BUFF_POP(uart_buff));
  22.         }*/
  23.     }
复制代码
回复 支持 反对

使用道具 举报 送花

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

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-1-31 19:35:18 | 显示全部楼层
DealString函数中,判断接收到的字符串,如果是hello,则发送world,如果是reboot,则等待2s后复位到ISP模式,其余情况则将字符串原封不动发送回去
  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(2000);
  10.         IAP_CONTR = 0x60;
  11.     }
  12.     else
  13.     {
  14.         UartSendStr(p);
  15.     }
  16. }
复制代码
回复 支持 反对

使用道具 举报 送花

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

13

主题

198

回帖

1175

积分

金牌会员

积分
1175
发表于 2024-1-31 19:37:36 | 显示全部楼层
烧录程序,打开STC的串口助手测试一下,发送hello,能正确收到world,发送123,能正确收到123
微信截图_20240131193708.png
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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