菠萝催雪
2022-06-16 16:32
采纳率: 100%
浏览 46

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条回答 默认 最新

相关推荐 更多相似问题