菠萝催雪 2022-06-16 16:32 采纳率: 33.3%
浏览 69
已结题

C8051F020串口连续发送出现30延迟

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

使用C8051F020实现ADC读取采样计算后使用串口连续发送,串口发送间隔在20ms左右,但是每发送4K数据就有300ms的延迟。

问题相关代码,请勿粘贴截图
#include <c8051f020.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

//宏声明
#define uchar              unsigned char             //定义uchar类型
#define uint               unsigned int              //定义uint类型
#define BAUDRATE           115200                    //定义串口波特率
#define SAR_CLK            2500000                   //定义SAR时钟熟读
#define SAMPLE_RATE        50000                     //定义12位数模芯片采样率
#define SYSTEMCLOCK        (22118400L)               //定义外部晶振速率
#define UART_SIZE          128                       //定义串口1读取数据位数
#define SAMP_NUM           22                        //定义ADC数组采样数量
#define OPERATING          -((SYSTEMCLOCK / SAMPLE_RATE) * SAMP_NUM) //定义ADC运算转换频率

//16位寄存器声明
sfr16 ADC0                 = 0xbe;                   //12位数模芯片数据定义
sfr16 TMR2                 = 0xcc;                   //定时器/计数器2初值
sfr16 RCAP2                = 0xca;                   //定时器/计数器2重载初值
sfr16 TMR3                 = 0x94;                   //定时器/计数器3初值
sfr16 RCAP3                = 0x92;                   //定时器/计数器3重载初值
sfr16 TMR4                 = 0xF4;                   //定时器/计数器4初值
sfr16 RCAP4                = 0xE4;                   //定时器/计数器4重载初值

//引脚位声明
sbit Auto_LED_RED          = P2^0;                   //Auto红灯控制位
sbit Auto_LED_GREEN        = P2^1;                   //Auto绿灯控制位
sbit ACK_LED_GREEN         = P3^1;                   //ACK绿灯控制位
sbit ACK_LED_RED           = P3^2;                   //ACK红灯控制位
sbit Watchdog              = P3^3;                   //3.3V电源看门狗控制位
sbit Manual_LED_RED        = P3^6;                   //Manual红灯控制位
sbit Manual_LED_GREEN      = P3^7;                   //Manual绿灯控制位

//函数声明
void OSCILLATOR_Init (void);                         //晶振初始化,切换为外部晶振
void PORT_Init (void);                               //单片机端口初始化
void Ext_Interrupt_Init (void);                      //外部中断初始化
void Flash_WRITE(void);                              //非易失128Bety Flash写入
void Flash_READ(void);                               //读取非易失Flash数据
void ReadData(void);                                 //读取非易失区数据
void ReadData1(void);                                //非中断读取非易失区数据
void UART1_Init (void);                              //初始化串口1
void delay(uint num);                                //延迟函数
void TIMER2_Init();                                  //初始化定时计数器2,设置功率轮询输出
void TIMER3_Init (int counts);                       //初始化定时计数器3,设置数模芯片转换速率
void TIMER4_Init ();                                 //初始化定时计数器4,监控串口接受数据间隔
void ADC0_Init (void);                               //初始化12位数模转换器
void UART1_Deal(void);                               //串口数据处理
void AcceptReset(uchar output, uchar outarr[]);      //串口数据清零
void AcceptReset1(uchar output, uchar outarr[]);      //串口数据清零

//全局变量声明
uint idata AckBlink = 0;                             //显示频率
uint idata SampNum = 0;                              //采样循环次数
uint idata Samp = 0;                                 //采样数据
long idata SampArr = 0;                              //存放累积采样数据
long idata SampArrAll= 0;                            //保存组采样值
float xdata Kvaule = 0;                              //ADC斜率
float xdata Bvalue = 0;                              //ADC最小值
float xdata Power = 0;                               //光功率
uchar idata Byte = 0;                                //串口1读一位数据
uchar idata InputCheck = 0;                          //串口1输入累加校验和
uchar idata OutputCheck = 0;                         //串口1输出累加校验和
uchar idata UART_Input_Size= 0;                      //串口1输入数据计数
uchar idata UART_Input_First= 0;                     //串口1输入字符位数
uchar xdata UART_Input[UART_SIZE];                   //串口1读取数据大小    
uchar idata UART_output_Size = 0;                    //串口1输出数据计数
uchar idata UART_output_First= 0;                    //串口1输出字符位数
uchar xdata UART_output[UART_SIZE];                  //串口1读出数据大小
uchar xdata Permanent_data[128];                     //不丢失数据
uchar code outok[] = {0xEF, 0x00, 0x4F, 0x3E};       //正确返回值
uchar code outon[] = {0xEF, 0x00, 0x58, 0x47};       //错误返回值
uchar xdata outarr[128] = {0xEF};                    //返回值
uchar tempchar[4];                                   //char转float数组
float * tempfloat;                                   //char转float指针
uchar pollflag = 0;                                  //轮询功率开关

//主函数
void main(void)
{
     WDTCN = 0xde;                                     //关闭单片机内部看门狗
   WDTCN = 0xad;                                     //关闭单片机内部看门狗
    
     OSCILLATOR_Init();                                //初始化晶振
     ReadData1();                                      //非中断读取非易失区数据
     PORT_Init();                                      //初始端口
     Ext_Interrupt_Init();                             //初始化外部中断
     UART1_Init();                                     //初始化串口1
     TIMER2_Init();                                    //初始化定时计数器2,设置功率轮询输出
     TIMER3_Init(SYSTEMCLOCK/SAMPLE_RATE);             //初始化定时器3,设置数模芯片转换速率
     TIMER4_Init ();                                   //初始化定时计数器4,监控串口接受数据间隔
     ADC0_Init();                                      //初始化12位数模转换器
     AD0EN = 1;                                        //打开12位数模转换器    
     EA    = 1;                                        //打开所有中断  

     Manual_LED_GREEN = 0;                             //关闭Manual灯
     Manual_LED_RED   = 0;                             //关闭Manual灯
     Auto_LED_GREEN   = 0;                             //关闭Auto灯
     Auto_LED_RED     = 0;                             //关闭Auto灯
     ACK_LED_GREEN    = 0;                             //关闭ACK灯
     ACK_LED_RED      = 0;                             //关闭ACK灯
     P4               = 0xFF;                          //将LED1~4号为灯亮红
    
    while(1)
    {
        Watchdog = 0;                                       //更新3.3V电源看门狗
        Watchdog = 1;                                    //更新3.3V电源看门狗
        Auto_LED_RED = Manual_LED_GREEN = 0;             //熄灭串口信号灯        

        if(AckBlink > 0xDFFF)                            //显示间隔
        {
            ACK_LED_GREEN = ~ACK_LED_GREEN;                //闪烁ACK灯
            AckBlink = 0;
        }
        
        //delay(1);
        
        AckBlink++;                                         //显示次数累加
    }

}

//延迟函数
void delay(uint num)
{
    uint i, j;
    for(i = 0; i < num; i++)
        for(j = 0; j < 200; j++);
}

//晶振初始化
void OSCILLATOR_Init (void)
{
   uint i;                                           //定义累加值
   OSCXCN = 0x67;                                    //设置外部晶振22.1184MHz
                                                       //晶体振荡器方式,晶体振荡器未用或未稳定
   for (i=0; i < 256; i++) ;                         //等待晶振运行
   while (!(OSCXCN & 0x80));                         //等待晶振运行稳定
   OSCICN = 0x88;                                    //选择外部振荡器作为系统时钟
                                                     //允许时钟丢失检测器 检测到时钟丢失时间大于 100 微秒时将触发复位

}

//端口初始化
void PORT_Init (void)
{
   XBR0      = 0x07;                                 //设置P1.0为TX1,P1.1为RX1
   XBR1      = 0x14;                                 //设置P1.2为INT0,P1.3为INT1
   XBR2      = 0x44;                                 //设置P0.6为SDA,P0.7为SCL
   
   P0MDOUT   = 0xFF;                                 //设置P0为推挽方式
   P1MDOUT   = 0xFF;                                 //设置P1为推挽方式
   P2MDOUT   = 0xFF;                                 //设置P2为推挽方式
     P3MDOUT   = 0xFF;                                 //设置P3为推挽方式
     P74OUT    = 0xBF;                                 //设置P4-P7为推挽方式
}

//外部中断初始化
void Ext_Interrupt_Init (void)
{
   TCON = 0x05;                        // /INT 0 和INT 1 边沿触发

   EX0 = 1;                            // 使能 /INT0 中断
   EX1 = 1;                            // 使能 /INT1 中断
}

//初始化串口1
void UART1_Init (void)
{
   SCON1     = 0x50;                                 //UART1 接收允许
                                                       //方式 1 8 位 UART 可变波特率
   TMOD     &= ~0xF0;                                //清除定时器 0设置
   TMOD     |= 0x20;                                 //自动重装载的 8 位计数器/定时器
     PCON     |= 0x10;                                 //禁止 UART1 的波特率/2 功能
     CKCON    |= 0x10;                                 //定时器 1 使用系统时钟
     TH1       = -((SYSTEMCLOCK/BAUDRATE)/16);         //设置定时器1 TH1初值
   TL1       = TH1;                                  //设置定时器1 TL1初值
   TR1       = 1;                                    //启动定时器1
   EIE2      = 0x40;                                 //允许 UART1 中断
   EIP2      = 0x40;                                 //外部中断 6 设置为高优先级
}

//初始化定时器3
void TIMER3_Init (int counts)
{
   TMR3CN    = 0x02;                                 //定时器3禁止;定时器3的时钟源由 T3M TMR3CN.1 位定义;计数器/定时器3使用系统时钟
   RCAP3     = -counts;                              //设置定时器重载初值
   TMR3      = RCAP3;                                //设置定时器初值
   EIE2     &= ~0x01;                                //禁止定时器3中断
   TMR3CN   |= 0x04;                                 //开始定时器3
}

//初始化12位数模转换器
void ADC0_Init (void)
{
   ADC0CN    = 0x04;                                 //ADC0禁止,当ADC被允许时除了转换期间之外一直处于跟踪方式
                                                     //定时器3溢出启动ADC0转换,数据右对齐
   REF0CN    = 0x07;                                 //内部电压基准缓冲器工作,内部电压基准提供从 VREF 引脚输出
                                                     //内部偏压发生器工作,内部温度传感器工作
   AMX0CF    = 0x00;                                 //ADC0独立的单端输入
     AMX0SL    = 0x01;                                 //选择AIN0.1引脚作为ADC0信号输入
   ADC0CF    = (SYSTEMCLOCK/SAR_CLK) << 3;           //ADC0转换时钟= 2.5MHz
   ADC0CF   |= 0x00;                                 //PGA增益= 1(默认)
   EIE2     |= 0x02;                                 //使ADC中断
//     EIP2      = 0x03;                               //ADC 转换结束中断为高优先级
                                                                                                         //定时器 3 中断为高优先级
}

//初始化定时器4
void TIMER4_Init ()
{
     CKCON &= ~0x40;                                   //定时器 4 使用系统时钟12分频
     RCAP4 = -(SYSTEMCLOCK/1000/12*5);                 //定时器4在1 kHz溢出1ms
   TMR4 = RCAP4;                                     //设置定时器初值
     T4CON &= ~0x80;                                   //清除初始化标志
     EIE2 |= 0x04;                                     //启动定时器4中断
     T4CON |= 0x04;                                    //启动定时器4
     //T4CON &= ~0x04;                                    //关闭定时器4    
}

//初始化定时器2
void TIMER2_Init()
{
   CKCON |= 0x20;                                    //定时器 2 使用系统时钟
   RCAP2 = OPERATING;                                //定时器2设置初值
   TMR2 = RCAP2;                                     //设置定时器初值
     T2CON = 0x04;                                     //使能定时器2自动填装
     TF2 = 0;                                          //清除初始化标志
   ET2 = 1;                                          //启动定时器2中断
     TR2 = 1;                                          //启动定时器2  
     //PT2 = 1;                                          //定时器2优先级最高
}

//外部中断1
void INT0_ISR (void) interrupt 0
{
   pollflag = 1;//打开轮询
}

//外部中断2
void INT1_ISR (void) interrupt 2
{
   pollflag = 0;//关闭轮询
}


//功率轮询
void Power_Poll (void) interrupt 5
{
    
    Power = ((float)SampArrAll * Kvaule + Bvalue * (float)SAMP_NUM ) / (float)SAMP_NUM;//计算光功率值dBm
    
    if(Power <= -65)                          //测试最小值
    {
         Power = -65; 
    }
    else if(Power >= 10)                      //测试最大值              
    {
         Power = 10;
    }
    
    if(pollflag == 1)     
    {  
        float temp = Power;                          //将功率值读入缓冲区
        char * temp1;                                //零时指针 
        TMR2 = RCAP2;                                //设置定时器初值
        UART_output_Size = 6;
        
        temp1=(char*)(&temp);
        outarr[0] = 0xEF; 
        outarr[1] = temp1[3];                        //将缓冲器数据写入待发区
        outarr[2] = temp1[2];        
        outarr[3] = temp1[1];                              
        outarr[4] = temp1[0];     
        AcceptReset1(UART_output_Size, &outarr);         //中断发送函数    
    }

  TF2 = 0;                                         //清除初始化标志
}

//12位数模转换器中断
void ADC0_ISR (void) interrupt 15
{

    if(SampNum == SAMP_NUM)                                  //判断采样次数
    {
        SampArrAll = SampArr;
        SampArr = 0;
        SampNum = 0;
    }
    
    Samp = ADC0;                                       //写入采样值
    SampNum++;                                         //累加
    SampArr += ADC0;                                   //读取采样放入数组

  AD0INT = 0;                                        //采样中断标志位清零
}

//串口接受间隔
void UART1_time (void) interrupt 16
{
   uchar i;
     TMR4 = RCAP4;                                     //设置定时器初值
    
     for(i = 0; i < UART_Input_Size; i++)
      UART_Input[i] = 0;                               //清除发送缓冲器
   InputCheck = 0;                                   //输入校验和清零
     UART_Input_Size = 0;                              //发送数据计数清零
      
     T4CON &= ~0x80;                                   //清除初始化标志
}

//串口1中断响应函数
void UART1_Interrupt (void) interrupt 20
{
   if ((SCON1 & 0x01) == 0x01)                       //判断RI1接收中断标志
   {
            TMR4 = RCAP4;                                  //设置定时器初值     
          T4CON &= ~0x80;                                //清除初始化标志
      if( UART_Input_Size == 0)                      //检查是否输入了新单词
            {
                    UART_Input_First = 0;                      //初始化数组序号
            } 
      Byte  = SBUF1;                                 //从超级终端读取字符    
      if (UART_Input_Size < UART_SIZE)               //判断读取数据是否超出
      {
         UART_Input[UART_Input_First] = Byte;        //将Byte写入数组
         UART_Input_Size++;                          //更新数组大小
         UART_Input_First++;                         //更新数组位数
                 Auto_LED_RED = ~Auto_LED_RED;               //Auto灯闪烁
      }
            
            if(UART_Input_Size > 3)
                 UART1_Deal();                               //串口接受处理函数
            SCON1 = (SCON1 & 0xFE);                        //清零RI1接收中断标志位
   }

   if ((SCON1 & 0x02) == 0x02)                       //判断TI1发送中断标志
   {
      if (UART_output_Size != 0)                     //如果缓冲区不为空
      {        
         Byte = UART_output[UART_output_First];      //在变量字节中存储一个字符
         SBUF1 = Byte;                               //将一位数据写入缓冲器
         UART_output_First++;                        //数组位累加
         UART_output_Size--;                         //数组总数减一
                 Manual_LED_GREEN = ~Manual_LED_GREEN;       //Manual灯闪烁
      }
      else
      {
                 UART_output_First = 0;                      //发送位清零
                 //UART_output_Size = 0;                       //发送数量清零
      }
            SCON1 = (SCON1 & 0xFD);                      //清零TI1接收中断标志位
   }
 }

//非易失128Bety Flash写入
void Flash_WRITE(void)
{
    uchar i;                                           //初始化累加值
    uchar xdata * pwrite;                              //非易失区指针
    uchar * pgen;                                      //常规指针
    EA = 0;                                            //关闭所有中断
  FLSCL = 0x01;                                      //允许对Flash进行写入
    PSCTL = 0x07;                                      //允许对Flash进行擦除
    pwrite = 0x1000;                                   //指向Flash的首地址
    *pwrite = 0;                                       //擦除该Flash扇区
    PSCTL = 0x05;                                      //禁止对Flash进行擦除
    pgen = &Permanent_data[0];                         //将数组128位    数据写入Flash
    for(i = 0; i < 128; i++)
        *pwrite++ = *pgen++;
    FLSCL = 0x00;                                      //禁止对Flash进行写入
    PSCTL = 0x00;                                      //禁止对Flash进行擦除
    EA = 1;                                            //打开所有中断
}
 
//读取非易失Flash数据
void Flash_READ(void)
{
    uchar i;                                           //初始化累加值
    uchar code *pread;                                 //程序存储空间指针
    PSCTL = 0x04;                                      //允许访问128K数据
  EA = 0;                                            //关闭所有中断
    pread = 0x1000;                                    //指向Flash的首地址
    for(i = 0; i < 128; i++)                           //读取非易失Flash数据start到stop数据
    {
        Permanent_data[i] = *pread++;    
    }  
    PSCTL = 0x00;                                      //禁止对Flash进行擦除
    EA = 1;                                            //打开所有中断
}
 
//串口数据处理
void UART1_Deal(void)
{
    uchar i;                                          //累加数
    if((UART_Input[0] == 0xEF))     //验证引导码确定发送数据完成
    {
        InputCheck = 0;                              //校验和清零
        for(i = 0; i < UART_Input_Size - 1; i++)       //计算校验和
            InputCheck += UART_Input[i];
        if(UART_Input[1] == 0x01)                        //客户写入
        {
            if((UART_Input[2] == 0x15) && (UART_Input_Size == 0x04) && (InputCheck == Byte))//停止功率轮询
            {    
                 pollflag = 0;                                      //关闭定时器2  
            }            
            else if((UART_Input[2] == 0x16) && (UART_Input_Size == 0x04) && (InputCheck == Byte))//开始功率轮询
            {    
                 pollflag = 1;                                      //开启定时器2  
            }                    
        }
        else if(UART_Input[1] == 0x02)                     //客户读取
        {
            if((UART_Input[2] == 0x07) && (UART_Input_Size == 0x04) && (InputCheck == Byte))//读取T1光功率
            {
                float temp = Power;                         //将功率值读入缓冲区
                char * temp1;                                  //零时指针 
                UART_output_Size = 6;
                temp1=(char*)(&temp);
                outarr[0] = 0xEF; 
                outarr[1] = temp1[3];                          //将缓冲器数据写入待发区
                outarr[2] = temp1[2];        
                outarr[3] = temp1[1];                              
                outarr[4] = temp1[0];    
                AcceptReset(UART_output_Size, &outarr);    
            }    
        }
        else if(UART_Input[1] == 0x11)                   //后台写入
        {
            if((UART_Input[2] == 0x00) && (UART_Input_Size == 0x0A) && (InputCheck == Byte))//写入SN号
            {  
                for(i = 0; i < UART_Input_Size; i++)         //将SN号写入到非易失FLASH
                {
                    if((i > 2) && (i < UART_Input_Size -1))
                        Permanent_data[i-3] = UART_Input[i];   
                }
                Flash_WRITE();                               //写入非易失Flash
                ReadData();                                  //读取非易失区数据
                AcceptReset(4, &outok);    
            }
            else if((UART_Input[2] == 0x01) && (UART_Input_Size == 0x08) && (InputCheck == Byte))//写入T1K值(1550)
            {
                for(i = 0; i < UART_Input_Size; i++)         //T1K值写入到非易失FLASH
                {
                    if((i > 2) && (i < 7))
                        Permanent_data[i-3+6] = UART_Input[i];   
                }
                Flash_WRITE();                               //写入非易失Flash
                ReadData();                                  //读取非易失区数据
                AcceptReset(4, &outok);    
            }
            else if((UART_Input[2] == 0x05) && (UART_Input_Size == 0x08) && (InputCheck == Byte))//写入T1B值(1550)
            {
                for(i = 0; i < UART_Input_Size; i++)         //T1B值写入到非易失FLASH
                {
                    if((i > 2) && (i < 7))
                        Permanent_data[i-3+6+4*4] = UART_Input[i];   
                }
                Flash_WRITE();                               //写入非易失Flash
                ReadData();                                  //读取非易失区数据
                AcceptReset(4, &outok);                            
            }
        }
        else if(UART_Input[1] == 0x12)//后台读取
        {
            if((UART_Input[2] == 0x00) && (UART_Input_Size == 0x04) && (InputCheck == Byte))//读取SN号
            { 
                UART_output_Size = 8;
                Flash_READ();                                  //重新读取非易失区数据
                for(i = 1; i < UART_output_Size-1; i++)        //将缓冲器数据写入待发区
                {
                    outarr[i] = Permanent_data[i-1];  
                }    
                AcceptReset(UART_output_Size, &outarr);
            }
            else if((UART_Input[2] == 0x01) && (UART_Input_Size == 0x04) && (InputCheck == Byte))//读取T1K值(1550)
            {
                UART_output_Size = 6;
                Flash_READ();                                  //重新读取非易失区数据
                for(i = 1; i < UART_output_Size-1; i++)        //将缓冲器数据写入待发区
                {
                    outarr[i] = Permanent_data[i-1+6];  
                }    
                AcceptReset(UART_output_Size, &outarr);        
            }
            else if((UART_Input[2] == 0x05) && (UART_Input_Size == 0x04) && (InputCheck == Byte))//读取T1B值(1550)
            {
                UART_output_Size = 6;
                Flash_READ();                                  //重新读取非易失区数据
                for(i = 1; i < UART_output_Size-1; i++)        //将缓冲器数据写入待发区
                {
                    outarr[i] = Permanent_data[i-1+6+4*4];  
                }    
                AcceptReset(UART_output_Size, &outarr);                            
            }
            else if((UART_Input[2] == 0x19) && (UART_Input_Size == 0x04) && (InputCheck == Byte))//读取T1采样值
            {
                uint temp = Samp;                           //将采样值读入缓冲区
                UART_output_Size = 4;
                outarr[0] = 0xEF;                     
                outarr[2] = temp;                              //将缓冲器数据写入待发区
                temp = temp >> 8;
                outarr[1] = temp;    
                AcceptReset(UART_output_Size, &outarr);    
            }
        }
    }
}
 
//发送接收缓冲器初始化
void AcceptReset(uchar output, uchar outarr[])  
{
  uchar i;
    InputCheck = 0;                                    //输入校验和清零
    OutputCheck = 0;                                   //输出校验和清零
    UART_output_First = 0;                             //发送位清零  
    
    UART_output_Size = output;                       //初始化输出数组数量    
    
    for(i = 0; i < UART_output_Size - 1; i++)
    {
        UART_output[i] = outarr[i];                    //写入返回数据
        OutputCheck += outarr[i];                      //计算输出校验和
    }
    UART_output[UART_output_Size-1] = OutputCheck;   //写入返回最后数据
    
    SCON1 = (SCON1 | 0x02);                          //激活串口RX标记位
}

//中断发送接收缓冲器初始化
void AcceptReset1(uchar output, uchar outarr[])  
{
    uchar i;
    InputCheck = 0;                                    //输入校验和清零
    OutputCheck = 0;                                   //输出校验和清零
    UART_output_First = 0;                             //发送位清零  
    
    UART_output_Size = output;                       //初始化输出数组数量    
    
    for(i = 0; i < UART_output_Size - 1; i++)
    {
        UART_output[i] = outarr[i];                    //写入返回数据
        OutputCheck += outarr[i];                      //计算输出校验和
    }
    UART_output[UART_output_Size-1] = OutputCheck;   //写入返回最后数据
    
    SCON1 = (SCON1 | 0x02);                          //激活串口RX标记位    
}

//读取非易失区数据
void ReadData(void)                                  
{
     Flash_READ();                                      //将非易失Flash数据全部读入Permanent_data数组

        tempchar[0] = Permanent_data[9];         //读取非易失数据中K值(1550)
        tempchar[1] = Permanent_data[8];
        tempchar[2] = Permanent_data[7];
        tempchar[3] = Permanent_data[6];
        tempfloat=(float*)(&tempchar);
        Kvaule = *tempfloat;
         
        tempchar[0] = Permanent_data[25];        //读取非易失数据中B值(1550)
        tempchar[1] = Permanent_data[24];
        tempchar[2] = Permanent_data[23];
        tempchar[3] = Permanent_data[22];
        tempfloat=(float*)(&tempchar);
        Bvalue = *tempfloat;
         
     
}

//非中断读取非易失区数据
void ReadData1(void)                                  
{
     Flash_READ();                                      //将非易失Flash数据全部读入Permanent_data数组
    
        tempchar[0] = Permanent_data[9];         //读取非易失数据中K值(1550)
        tempchar[1] = Permanent_data[8];
        tempchar[2] = Permanent_data[7];
        tempchar[3] = Permanent_data[6];
        tempfloat=(float*)(&tempchar);
        Kvaule = *tempfloat;
         
        tempchar[0] = Permanent_data[25];        //读取非易失数据中B值(1550)
        tempchar[1] = Permanent_data[24];
        tempchar[2] = Permanent_data[23];
        tempchar[3] = Permanent_data[22];
        tempfloat=(float*)(&tempchar);
        Bvalue = *tempfloat; 

     
}

运行结果及报错内容

img


前面数据间隔还在20ms,后面就出现300ms延迟。

我的解答思路和尝试过的方法

关闭其他所有中断,尝试只用串口中断连续发送数据,也会周期性出现300ms延迟。

我想要达到的结果

在不使用DMA情况下,实现C8051F020连续发送数据,要求数据间隔保存在20~30ms。

  • 写回答

3条回答 默认 最新

  • qllaoda 2022-06-16 16:41
    关注

    波特率115200,数据每秒11KB左右,4KB用300多毫秒,差不多啊。要是嫌慢,可以换c8051f340系列,用USB

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 6月25日
  • 已采纳回答 6月17日
  • 修改了问题 6月16日
  • 创建了问题 6月16日

悬赏问题

  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?