test_tmp 发表于 2024-3-26 20:08:00

提交一个USB和timer3共存的bug | 数据手册中有注意事项

在将程序从stc8h8k64u迁移到stc32g12k128时,发现一个bug,描述如下:

板子:屠龙刀
状况:板子通过CDC与电脑通讯,不初始化定时器3时,工作正常,初始化定时器3后,CDC就出不来了。


代码如下:


#include "..\api\core_api.h"
#include "..\api\usb_uart.h"
#include "..\api\usb\stc32_stc8_usb.h"
#include "stdio.h"


sbit LED_24 = P2^4;
sbit LED_25 = P2^5;

uint debugTimer = 0;
bit B_chkTimeFreq = 0;

void procUartCmd();

void initTimer0ByTest(){
      AUXR &= 0x7F;
      TMOD &= 0xF0;
      TL0 = 0x0;
      TH0 = 0x0;
      TF0 = 0;      
      ET0 = 1;
}

void initTimer2(void){      
      TM2PS = 0;
      AUXR &= 0xFB;
      T2L = 0x30;      
      T2H = 0xF8;               
T2R = 1;
ET2 = 1;      
}

void initTimer3(){//初始化定时器3
TM3PS = 0;      
      T4T3M &= 0xf0;               
      T3H = 0;
      T3L = 0;
      ET3 = 1;    //加入该行后,CDC出问题
}


void reset(){
      WTST = 0;
      EAXFR = 1;
      CKCON = 0;
      initTimer2();
      P3n_pure_input(0x03);//P3.0/P3.1 ºÍ USB µÄ D-/D+¹²Óà PIN ½Å£¬ÐèÒª½« P3.0/P3.1 ÉèÖÃΪ¸ß×èÊäÈëģʽ
      usb_init();//USB CDC ½Ó¿ÚÅäÖÃ
      EA = 1;
}

void showDebuger(){
      if(B_chkTimeFreq){
                sendTowDats2Pc(0xb5, 3, 10);
      }
}

void main(void){
      LED_24 = 0;
      reset();
      initTimer3();
      LED_25 = 0;
      
      while(1){
                if (bUsbOutReady) {
                        procUartCmd();         
                        usb_OUT_done();   
                }
               
                if(debugTimer==0){
                        debugTimer = 500;
                        showDebuger();
                }
               
      }
}

uint timer0_Overs = 0;

void timer2_isr() interrupt 12{
      if(debugTimer>0) debugTimer--;
}

void timer0_Isr(void) interrupt 1{
      timer0_Overs++;
}

ulong mathCalcAdd(int nums, int dat1, int dat2){
      int i;
      long res = 0;
      for(i=0;i<nums;i++){
                res = dat1 + dat2;
      }
      return res;
}

ulong mathCalcDec(int nums, int dat1, int dat2){
      int i;
      long res = 0;
      for(i=0;i<nums;i++){
                res = dat1 - dat2;
      }
      return res;
}

ulong mathCalcMul(int nums, int dat1, int dat2){
      int i;
      long res = 0;
      for(i=0;i<nums;i++){
                res = dat1 * dat2;
      }
      return res;
}

ulong mathCalcDiv(int nums, int dat1, int dat2){
      int i;
      long res = 0;
      for(i=0;i<nums;i++){
                res = dat1 / dat2;
      }
      return res;
}

ulong mathCalcMulFloat(int nums, int dat1, int dat2){
      int i;
      long res = 0;
      float f0 = ((float)dat1) / 10.0;
      float f1 = ((float)dat2) / 10.0;
      float f2 = 0;
      for(i=0;i<nums;i++){
                f2 = f0 * f1;
      }
      res = (long)(f2*10.0);
      return res;      
}

ulong mathCalcDivFloat(int nums, int dat1, int dat2){
      int i;
      long res = 0;
      float f0 = ((float)dat1) / 10.0;
      float f1 = ((float)dat2) / 10.0;
      float f2 = 0;
      for(i=0;i<nums;i++){
                f2 = f0 / f1;
      }
      res = (long)(f2*10.0);
      return res;      
}


void checkMathPrefs(){
      long res = 0;
      uint timer = 0;
      uchar idx = 5;
      uchar type = UsbOutBuffer;
      int nums = (((int)UsbOutBuffer) << 8) + UsbOutBuffer;
      int dat1 = (((int)UsbOutBuffer) << 8) + UsbOutBuffer;
      int dat2 = (((int)UsbOutBuffer) << 8) + UsbOutBuffer;
      initTimer0ByTest();
      timer0_Overs = 0;
      TR0 = 1;
      switch(type){
                case 1:
                        res = mathCalcAdd(nums, dat1, dat2);
                        break;
                case 2:
                        res = mathCalcDec(nums, dat1, dat2);
                        break;
                case 3:
                        res = mathCalcMul(nums, dat1, dat2);
                        break;
                case 4:
                        res = mathCalcDiv(nums, dat1, dat2);
                        break;
                case 5:
                        res = mathCalcMulFloat(nums, dat1, dat2);
                        break;
                case 6:
                        res = mathCalcDivFloat(nums, dat1, dat2);
                        break;
      }
      TR0 = 0;
      timer = (((uint)TH0) << 8) + TL0;
      
      createStartRs232(0xb5, 3, 12);
      addUChar2RS232Buf(type);
      addInt2RS232Buf(nums);
      addInt2RS232Buf(dat1);
      addInt2RS232Buf(dat2);
      flushRS232Buffer();
      
      createStartRs232(0xb5, 3, 11);
      addUInt2RS232Buf(timer0_Overs);
      addUInt2RS232Buf(timer);
      addLong2RS232Buf(res);
      flushRS232Buffer();
}


void procUartCmd(){
      if((UsbOutBuffer==0x8A)&&(UsbOutBuffer==0x8B)){//´Ó×Ô¼º¿ª·¢µÄÉÏλ»úÈí¼þ·¢À´µÄ
                if(UsbOutBuffer==0x1C){//³¤¶È¶Ô
                        if(checkRXDatSum()){//УÑéºÍÕýÈ·
                              switch(UsbOutBuffer){//¹¦ÄÜ
                                        case 0xa1://pwmµ÷ÊÔ
                                                switch(UsbOutBuffer){
                                                      case 0x00:   //ÉÏλ»ú¶ÁÈ¡ÅäÖà                                                        
                                                                break;
                                                      case 0x01://±£´æÅäÖÃ
                                                                break;
                                                      case 0x02://debug1
                                                                break;
                                                      case 0x03://debug2
                                                                break;
                                                      case 0x04://debug3
                                                                break;
                                                      case 0x05://debug4
                                                                break;
                                                      case 0x06://debug5
                                                                break;
                                                      case 0x07:   //ʱÖÓ°´Å¥
                                                                B_chkTimeFreq = ~B_chkTimeFreq;
                                                          break;
                                                      case 0x08://»»Ïà¼Ç¼
                                                                break;
                                                      case 0x09://¿ª¹ØADC
                                                          break;                                                      
                                                      case 0x20:   //µ÷ÊÔ2 ²»´ø²ÎÊý
                                                                break;
                                                      case 0x21://µ¥²½
                                                                break;
                                                      case 0x22:   //Í£Ö¹
                                                                break;
                                                }
                                                break;
                                        case 0xa2://ÉÏλ»úдÅäÖÃÀ´                              
                                                break;
          case 0xa3:    //µ÷ÊÔ1 ´ø²ÎÊý(int)
                                                checkMathPrefs();
            break;                                                
                              }
                        }
                }
      }
}

test_tmp 发表于 2024-3-26 20:12:18

程序涉及的代码见下面的附件,希望官方确认一下,或者哪位大神帮忙看看。

21cnsound 发表于 2024-3-26 21:08:19

看T3的初始化代码,确实是不应该影响其他功能。等官方答复吧

test_tmp 发表于 2024-3-26 21:15:40

21cnsound 发表于 2024-3-26 21:08
看T3的初始化代码,确实是不应该影响其他功能。等官方答复吧

嗯,我反复测试了,只要打开timer3的中断,CDC就出不来了

test_tmp 发表于 2024-3-26 21:18:55

再次测试了,timer4也一样,换句话说,可以操作IE2的5\6位后,usb的CDC就有问题,但同样的代码,在stc8h下是正常的

test_tmp 发表于 2024-3-26 21:27:26

请官方尽快看看吧

jwd 发表于 2024-3-26 21:45:04

是不是和EUSB有关?

jwd 发表于 2024-3-26 21:48:13

看看手册这里,估计是与它有关。stc32的这些寄存器可以位寻址,直接用位变量操作

test_tmp 发表于 2024-3-26 21:57:00

研究了一下,确实是EUSB的问题,新版手册里面,提到这个问题了,只要操作了IE2,就需要重新置EUSB=1

DebugLab 发表于 2024-3-26 22:12:34

test_tmp 发表于 2024-3-26 21:57
研究了一下,确实是EUSB的问题,新版手册里面,提到这个问题了,只要操作了IE2,就需要重新置EUSB=1 ...

操作IE2后再EUSB=1,EUSB也会被清零一下,可能会导致未知的错误,应该
unsigned char a;
a=IE2;//先读出
a|=0x20;//打开定时器3中断
a|=0x80;//打开USB中断
IE2=a;//再写回
页: [1] 2
查看完整版本: 提交一个USB和timer3共存的bug | 数据手册中有注意事项