DebugLab 发表于 2025-3-17 17:45:05

串口收发框架,带不断电下载功能

串口收发框架,带不断电下载功能
单片机:AI8G1K08A
根据
https://www.stcaimcu.com/thread-4598-1-1.html
修改
新增不断电下载功能、485软件控制收发、串口数据原样返回
#include <AI8G.H>
#include "define.h"
#include <intrins.h>
#include <absacc.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>

#define                RXD                        P30
#define                TXD                        P31
#define                FOSC                11059200UL
#define                BAUD                9600UL                                                //波特率
#define                TMRF                200UL                                                //定时器频率
#define                BRT                        (0x10000-(FOSC/BAUD+2)/4)      //波特率发生器值
#define                TMR                        (0x10000-FOSC/TMRF/12)                //定时器值
#define                R_Buf_Len      64                                                      //Uart1接收缓存长度
#define                T_Buf_Len      64                                                      //Uart1发送缓存长度
#define                R                        0                                                      //485接收
#define                T                        1                                                      //485发送

unsigned char                RP;                                        //Uart1接收指针
unsigned char                TP;                                        //Uart1发送指针
unsigned char                Uart_R_Len;                        //Uart1接收长度
unsigned char                Uart_T_Len;                        //Uart1发送长度
unsigned char xdata      R_Buf;      //Uart1接收缓存
unsigned char xdata      T_Buf;      //Uart1发送缓存

char USER_STCISPCMD[]="@STCISP#";      //下载命令(用户自定义,可修改,必须和ISP软件中设置的一致)

///*----------------------------延时10us@STC-Y6@11.0592MHz----------------------------*/
//void Delay_10us(void)
//{
//      unsigned char i;
//      i=35;
//      while(--i);
//}

///*----------------------------延时x10us----------------------------*/
//void Delay_x10us(unsigned char x)
//{
//      while(x--)
//                Delay_10us();
//}

/*----------------------------延时10ms@STC-Y6@11.0592MHz----------------------------*/
void Delay_10ms(void)
{
      unsigned char i,j;
      _nop_();
      _nop_();
      i=144;
      j=157;
      do
      {
                while(--j);
      }while(--i);
}

/*----------------------------延时x10ms----------------------------*/
void Delay_x10ms(unsigned char x)
{
      while(x--)
                Delay_10ms();
}

void UART_Send(unsigned int x)
{
      TP=0;
      Uart_T_Len=x;
      TI=1;
}

void Uart_Printf(unsigned char *v,...)
{
      va_list ap;
      va_start(ap,v);
      while(Uart_T_Len);
      UART_Send(vsprintf(T_Buf,v,ap));
      va_end(ap);
}

void UART_Return(unsigned char temp)
{
      memcpy(T_Buf,R_Buf,temp);
      UART_Send(temp);
}

void Init(void)
{
      P_SW2|=EAXFR;
      
      P0M1=0x00;      P0M0=0x00;      //设置IO模式
      P1M1=0x00;      P1M0=0x00;      //设置IO模式
      P2M1=0x00;      P2M0=0x00;      //设置IO模式
      P3M1=0x00;      P3M0=0x00;      //设置IO模式
      P4M1=0x00;      P4M0=0x00;      //设置IO模式
      P5M1=0x00;      P5M0=0x00;      //设置IO模式
      P6M1=0x00;      P6M0=0x00;      //设置IO模式
      P7M1=0x00;      P7M0=0x00;      //设置IO模式
      
      AUXR=0x40;                //设置定时器0时钟为12T模式,设置定时器1为1T模式,设置定时器1为波特率发生器
      TMOD=0x01;                //设置定时器0为16位不自动重装载模式,设置定时器1为16位自动重装载模式
      TH0=TMR>>8;                //设置定时器0初始值
      TL0=TMR;                //设置定时器0初始值
      TF0=0;                        //清除TF0中断标志位
      ET0=1;                        //启用定时器0中断
      
      SCON=0x50;                //设置UART1模式为8位数据可变波特率
      TH1=BRT>>8;                //设置UART1波特率
      TL1=BRT;                //设置UART1波特率
      TR1=1;                        //打开定时器1
      ES=1;                        //启用UART1中断
      
      EA=1;                        //启用总中断
}

void main(void)
{
      Init();
      Uart_Printf("AI8G1K08A auto download test.\r\n");
      while(1)
      {
                Uart_Printf("AI8G1K08A running.\r\n");
                Delay_x10ms(100);
      }
}

void Uart_Start(void)
{
      TL0=0x00;
      TH0=0xEE;
      TR0=1;
}

void Uart_Stop(void)
{
      TR0=0;
      TL0=0x00;
      TH0=0xEE;
      RP=0;
      memset(R_Buf,0x00,sizeof R_Buf);
}

void Timer0_Isr(void) interrupt 1
{
      UART_Return(RP);      //超时原样返回
      Uart_Stop();
}

void Uart_Isr(void) interrupt 4
{
      if(RI)
      {
                RI=0;
                Uart_Start();
                R_Buf=SBUF;
                if((RP==sizeof USER_STCISPCMD-2)&&(memcmp(R_Buf,USER_STCISPCMD,sizeof USER_STCISPCMD-1)==0))      //收到用户命令后复位到ISP区
                {
                        IAP_CONTR=0x60;
                }
                if(RP==R_Buf_Len-1)
                {
                        Uart_Stop();
                }
                else if(TR0)
                {
                        RP++;
                }
      }
      if(TI)
      {
                TI=0;
                if(TP==Uart_T_Len)
                {
//                        TR=R;      //485软件收发控制
                        TP=0;
                        Uart_T_Len=0;
                }
                if(Uart_T_Len!=0)
                {
//                        TR=T;      //485软件收发控制
                        SBUF=(T_Buf);
                        TP++;
                }
      }
}
硬件选项的时钟频率11.0592M
注意下载端口一定要选CDC,不要选HID,否则不能正确发送下载命令
用户命令按图设置:



页: [1]
查看完整版本: 串口收发框架,带不断电下载功能