找回密码
 立即注册
查看: 1094|回复: 9

STC8G1KO8A取代STC15W104中遇到的问题

[复制链接]

该用户从未签到

1

主题

3

回帖

15

积分

新手上路

积分
15
发表于 2023-2-22 09:14:22 | 显示全部楼层 |阅读模式
本帖最后由 ecoo 于 2023-2-22 11:34 编辑

最近在移植一段开源的电调程序到stc8G1K08A,根据手册指引;
改了include,增加了STC8G.h和intrins.h

改了IO配置;
增加了eeprom的iap_tps指令;
复位脚用作IO输出,未改动;
初始化中配置了引脚准双向;
根据例程的eeprom基础操作改了程序的eeprom操作。

编译过程未报错,实际下载程序后,能看到初始化的输出波形,但是主程序没反应,请大佬指正下程序哪里没改到位。
  1. #include<STC8G.h>
  2. #include<intrins.h>
  3. #define u8 unsigned char
  4. #define u16 unsigned int
  5. sbit IN=P5^4;                              //修改引脚定义
  6. //sbit Mode_IN=P5^5;                       //模式引脚
  7. sbit A1=P3^3;
  8. sbit A2=P3^2;
  9. sbit B1=P3^1;
  10. sbit B2=P3^0;
  11. bit turn;
  12. bit stop,go;
  13. bit ok,lose,error;
  14. bit mode;
  15. u8 MARK1,MARK2,low,top,calabration,over,n;
  16. u8 step;
  17. u16 time,tt ;
  18. u16 MAX,MINE,MIDDLE,k;                          //修改冲突的min>>mine
  19. u16 Timer2_value;
  20. u16 phase_time;
  21. int speed;
  22. void Delay100us()                                            //@12.000MHz,修改为Y6指令集
  23. {
  24.         unsigned char i, j;
  25.         _nop_();
  26.         i = 2;
  27.         j = 140;
  28.         do
  29.         {
  30.                 while (--j);
  31.         } while (--i);
  32. }
  33. void delay(u16 t)
  34. {
  35.         while(t--)
  36.         Delay100us();
  37. }
  38. u8 EEPROM_read(u8 address)
  39. {
  40.     char byte;
  41.     IAP_CONTR = 0x80;                           //使能IAP
  42.     IAP_TPS = 12;                               //设置等待参数12MHz
  43.     IAP_CMD = 1;                                //设置IAP读命令
  44.     IAP_ADDRL = address;                        //设置IAP低地址
  45.     IAP_ADDRH = address >> 8;                   //设置IAP高地址
  46.     IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
  47.     IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
  48.     _nop_();
  49.     byte = IAP_DATA;                            //读IAP数据
  50.     IAP_CONTR = 0;                              //关闭IAP功能
  51.     return byte;
  52. }
  53. void EEPROM_write(u8 address,u8 byte)
  54. {
  55.     IAP_CONTR = 0x80;                           //使能IAP
  56.     IAP_TPS = 12;                               //设置等待参数12MHz
  57.     IAP_CMD = 2;                                //设置IAP写命令
  58.     IAP_ADDRL = address;                        //设置IAP低地址
  59.     IAP_ADDRH = address >> 8;                   //设置IAP高地址
  60.     IAP_DATA = byte;                            //写IAP数据
  61.     IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
  62.     IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
  63.     _nop_();
  64.     IAP_CONTR = 0;
  65.         //         IAP_CONTR=0x80;                           //以下为源程序eeprom操作
  66. //  IAP_ADDRL=address;
  67. //  IAP_DATA=byte;
  68. //  IAP_CMD=0x02;
  69. //  IAP_TRIG=0x46;
  70. //  IAP_TRIG=0xb9;
  71.        
  72. }
  73. void EEPROM_clean(u8 address)
  74. {
  75.           IAP_CONTR = 0x80;                           //使能IAP
  76.     IAP_TPS = 12;                               //设置等待参数12MHz
  77.     IAP_CMD = 3;                                //设置IAP擦除命令
  78.     IAP_ADDRL = address;                        //设置IAP低地址
  79.     IAP_ADDRH = address >> 8;                   //设置IAP高地址
  80.     IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
  81.     IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
  82.     _nop_();                                    //
  83.     IAP_CONTR = 0;                              //关闭IAP功能
  84. // IAP_CONTR=0x80;                              //源程序eeprom操作
  85. //  IAP_ADDRL=address;
  86. //  IAP_CMD=0x03;
  87. //  IAP_TRIG=0x46;
  88. //  IAP_TRIG=0xb9;
  89. }
  90. void DATA_read()
  91. {
  92. IAP_CONTR=0x83;                                //修改
  93. IAP_TPS = 12;                                  //设置等待参数12MHz
  94. MARK1=EEPROM_read(0);
  95. MARK2=EEPROM_read(1);
  96. MAX=EEPROM_read(2);
  97. MAX<<=8;
  98. MAX+=EEPROM_read(3);
  99. MIDDLE=EEPROM_read(4);
  100. MIDDLE<<=8;
  101. MIDDLE+=EEPROM_read(5);
  102. IAP_CONTR=0;
  103. }
  104. void DATA_save()
  105. {
  106. IAP_CONTR=0x83;                                //修改
  107. IAP_TPS = 12;                                  //设置等待参数12MHz
  108. EEPROM_clean(0);
  109. EEPROM_write(0,0x0f);
  110. EEPROM_write(1,0xa5);
  111. EEPROM_write(2,MAX>>8);
  112. EEPROM_write(3,MAX);
  113. EEPROM_write(4,MIDDLE>>8);
  114. EEPROM_write(5,MIDDLE);
  115. IAP_CONTR=0;
  116. }
  117. void measure()
  118. {
  119.         time=0;
  120.         TL0=0,TH0=0;
  121.         while(!IN);
  122.         TR0=1;
  123.         while(IN);
  124.         TR0=0;
  125.         time=TH0;
  126.         time<<=8;
  127.         time+=TL0;               
  128. }
  129. void shock(u8 n)                                //beep
  130. {
  131.         u8 i;
  132.         for(i=0;i<250;i++)
  133.         {
  134.                 A1=1;A2=0;
  135.                 delay(n);
  136.                 A1=0;A2=1;
  137.                 delay(n);       
  138.         }
  139.         A1=0;A2=0;
  140. }
  141. void initial()
  142. {
  143.         u8 i;       
  144.        
  145.         P3M1=0x00;                                          //修改准双向
  146.         P3M0=0x00;
  147.         P5M1=0x00;       
  148.         P5M0=0x00;
  149.         TMOD=0x01;
  150.         A1=0;
  151.         A2=0;
  152.         B1=0;
  153.         B2=0;
  154.        
  155.         delay(2000);
  156.         shock(2);                                            //上电能观察到输出
  157.         shock(3);
  158.         shock(4);
  159.         delay(5000);
  160.        
  161. //        mode=Mode_IN;
  162.         mode=1;                                       //1为2相,0取四相
  163.         measure();
  164.         measure();
  165.         measure();
  166.         measure();
  167.         measure();
  168.        
  169.        
  170.         DATA_read();
  171.         if(MARK1!=0x0f||MARK2!=0xa5)                  //16bit,if((MARK1==0x0f)&&(MARK2==0xa5))
  172.         {
  173.                
  174.                 MAX=1950;MIDDLE=1500;                       //默认标准行程
  175.                
  176.         }
  177.        
  178.         over=1;
  179.         while(over)
  180.         {
  181.                 measure();
  182.                
  183.                 if(time>1700)                               //上电油门高位校准行程
  184.                 {
  185.                         i++;
  186.                         if(i>100)over=0,calabration=1;            //校准
  187.                 }
  188.                 else                 
  189.                 {
  190.                         if(time<MIDDLE+50&&time>MIDDLE-50)        //校准完成
  191.                         {
  192.                                 over=0;
  193.                                 shock(4);
  194.                                 shock(3);
  195.                                 shock(2);
  196.                         }
  197.                 }
  198.         }       
  199.         if(MAX>2200||MIDDLE<1300)
  200.         {
  201.                 calabration=1;
  202.                 if(MAX<1700||MIDDLE>1700)calabration=1;
  203.         }
  204.        
  205.         if(calabration)
  206.         {
  207.                 over=1;
  208.                 while(over)
  209.                 {
  210.                         measure();
  211.                         if(time>1700)over=0;
  212.                 }
  213.                 delay(5000);delay(5000);
  214.                 shock(4);
  215.                 delay(2000);
  216.                 shock(4);
  217.                 measure();
  218.                 measure();
  219.                 if(time>1700&&time<2200)MAX=time;
  220.                 else error=1;         
  221.                
  222.                 over=1;
  223.                 while(over)
  224.                 {
  225.                         measure();
  226.                         if(time<1700&&time>1300)over=0;
  227.                 }         
  228.                 delay(5000);delay(5000);
  229.                 shock(4);
  230.                 delay(2000);
  231.                 shock(4);
  232.                 measure();
  233.                 measure();
  234.                 if(time>1300&&time<1700)MIDDLE=time;
  235.                 else error=1;
  236.                
  237.                 if(error==0)DATA_save();
  238.                 delay(2000);
  239.                 shock(4);
  240.                 shock(3);
  241.                 shock(2);
  242.         }
  243.        
  244. }
  245. main()
  246. {
  247.         initial();
  248.         stop=1;
  249.         IE=0x80;                                      //中断
  250.         IE2=0x04;
  251.         MINE=MIDDLE+MIDDLE-MAX;
  252.         k=MAX-MIDDLE;
  253.         AUXR=0x10;                                    //开定时器2
  254.         while(1)                                      //正常工作
  255.         {
  256.                  measure();
  257. //                shock(2);                                 //测试主程序循环用方波
  258.                 if(lose)                                    //失控待机
  259.                 {
  260.                         delay(1000);
  261.                         measure();
  262.                         measure();
  263.                 }
  264.                 if(time>800&&time<2200)                     //主程序
  265.                 {
  266.                        
  267.                         ok=1;lose=0;
  268.                        
  269.                         if(time>MIDDLE+50)
  270.                         {
  271.                                 stop=0,go=1;
  272.        
  273.                                 if(time>MAX)time=MAX;
  274.                
  275.                                 speed=(long)(time-MIDDLE )*100/k;
  276.                                
  277.                                 phase_time=11000-speed*100;             //11ms~1ms换向时间调节,最大0.4ms,取值范围10400~11000(根据电机)
  278.                                 Timer2_value=65535-phase_time;
  279.                         }
  280.                         else if(time<MIDDLE-50)
  281.                         {
  282.                                 stop=0,go=0;
  283.        
  284.                                 if(time<MINE)time=MINE;
  285.                
  286.                                 speed=(long)(MIDDLE- time)*100/k;
  287.                                 phase_time=11000-speed*100;
  288.                                 Timer2_value=65535-phase_time;
  289.                         }
  290.                         else
  291.                         {
  292.                                 stop=1;
  293.                         }
  294.                                                
  295.                 }
  296.                        
  297.         }
  298. }
  299. void et2()interrupt 12                          //定时驱动
  300. {
  301.         if(stop)                                      //停止
  302.         {
  303.                 T2L=0x18,T2H=0xfc;                          //1ms
  304.                 A1=0,A2=0,B1=0,B2=0;
  305.         }
  306.         else                                          //转动
  307.         {
  308.                 T2L=Timer2_value,T2H=Timer2_value>>8;       //11ms~1ms换向时间调节
  309.                
  310.                 if(mode)                                    //两相 8拍,MODE=1
  311.                 {
  312.                         if(step==0)A1=1,A2=0,B1=0,B2=0;
  313.                         else if(step==1)A1=1,A2=0,B1=1,B2=0;
  314.                         else if(step==2)A1=0,A2=0,B1=1,B2=0;
  315.                         else if(step==3)A1=0,A2=1,B1=1,B2=0;
  316.                         else if(step==4)A1=0,A2=1,B1=0,B2=0;
  317.                         else if(step==5)A1=0,A2=1,B1=0,B2=1;
  318.                         else if(step==6)A1=0,A2=0,B1=0,B2=1;
  319.                         else if(step==7)A1=1,A2=0,B1=0,B2=1;
  320.                 }
  321.                 else                                        //四相 8拍,MODE=0
  322.                 {
  323.                         if(step==0)A1=1,A2=0,B1=0,B2=0;
  324.                         else if(step==1)A1=1,A2=1,B1=0,B2=0;
  325.                         else if(step==2)A1=0,A2=1,B1=0,B2=0;
  326.                         else if(step==3)A1=0,A2=1,B1=1,B2=0;
  327.                         else if(step==4)A1=0,A2=0,B1=1,B2=0;
  328.                         else if(step==5)A1=0,A2=0,B1=1,B2=1;
  329.                         else if(step==6)A1=0,A2=0,B1=0,B2=1;
  330.                         else if(step==7)A1=1,A2=0,B1=0,B2=1;
  331.                 }       
  332.                
  333.                 if(go)                                      //正转
  334.                 {
  335.                         step++;
  336.                         if(step>7)step=0;
  337.                 }
  338.                 else                                        //反转
  339.                 {
  340.                         if(step)step--;
  341.                         else step=7;
  342.                 }
  343.         }
  344.         tt++;
  345.         if(ok)tt=0;
  346.         else {if(tt>200)tt=200,stop=1,lose=1;}        //信号断开检测
  347.         ok=0;
  348. }
复制代码



回复 送花

使用道具 举报

该用户从未签到

46

主题

3032

回帖

6835

积分

超级版主

积分
6835
发表于 2023-2-22 09:42:52 | 显示全部楼层
临时借用一个IO放在主程序中取反,示波器看是否输出方波,看看主程序是否在循环。
回复 支持 1 反对 0 送花

使用道具 举报

  • TA的每日心情
    开心
    2024-1-24 13:08
  • 签到天数: 1 天

    [LV.1]初来乍到

    8

    主题

    651

    回帖

    1102

    积分

    超级版主

    积分
    1102
    发表于 2023-2-22 13:22:43 | 显示全部楼层
       楼主可以参考STC8G资料附录X部分:STC8G单片机取代STC15系列的注意事项:下载链接如下:

         https://www.stcai.com/cp_stc8gxl
       1.png
    STC官网:https://www.stcai.com/
    QQ:2593903262
    微信号:18106296598

    该用户从未签到

    1

    主题

    3

    回帖

    15

    积分

    新手上路

    积分
    15
     楼主| 发表于 2023-2-22 21:16:33 | 显示全部楼层
    梁工 发表于 2023-2-22 09:42
    临时借用一个IO放在主程序中取反,示波器看是否输出方波,看看主程序是否在循环。 ...

    方波有输出,主程序循环中

    点评

    那你说“主程序没反应”就不是了,主程序在循环中,可能是某个外设没初始化对。问题描述再细化一点,是哪个外设功能没输出?  详情 回复 发表于 2023-2-23 10:06

    该用户从未签到

    1

    主题

    3

    回帖

    15

    积分

    新手上路

    积分
    15
     楼主| 发表于 2023-2-22 21:17:29 | 显示全部楼层
    STCAI-32位8051 发表于 2023-2-22 13:22
    楼主可以参考STC8G资料附录X部分:STC8G单片机取代STC15系列的注意事项:下载链接如下:

         https:// ...

    帖子开头已经对照着手册这一段一条条改过去了

    该用户从未签到

    46

    主题

    3032

    回帖

    6835

    积分

    超级版主

    积分
    6835
    发表于 2023-2-23 10:06:06 | 显示全部楼层
    ecoo 发表于 2023-2-22 21:16
    方波有输出,主程序循环中

    那你说“主程序没反应”就不是了,主程序在循环中,可能是某个外设没初始化对。问题描述再细化一点,是哪个外设功能没输出?

    该用户从未签到

    1

    主题

    3

    回帖

    15

    积分

    新手上路

    积分
    15
     楼主| 发表于 2023-2-23 10:56:20 | 显示全部楼层
    梁工 发表于 2023-2-23 10:06
    那你说“主程序没反应”就不是了,主程序在循环中,可能是某个外设没初始化对。问题描述再细化一点,是哪 ...

    程序上电后输出方波,然后测量输入得pmw,在范围内正常工作,根据输入pmw宽度输出4路pmw,输入不在范围内就重新测量范围,然后写入eeprom,源程序在15w上工作正常,移植过程中未改动main、measure里面的代码。实际是只能看到上电的波形,后面输出引脚无反应了。在循环中加入直接输出,输出引脚正常输出.

    点评

    你分两步,先测试PWM输出,给定一个占空比,看PWM是否能连续输出,能则这部分没有问题,不能则PWM部分有问题,先改好。 然后调测量的程序。  详情 回复 发表于 2023-2-23 11:06

    该用户从未签到

    46

    主题

    3032

    回帖

    6835

    积分

    超级版主

    积分
    6835
    发表于 2023-2-23 11:06:00 | 显示全部楼层
    ecoo 发表于 2023-2-23 10:56
    程序上电后输出方波,然后测量输入得pmw,在范围内正常工作,根据输入pmw宽度输出4路pmw,输入不在范围内 ...

    你分两步,先测试PWM输出,给定一个占空比,看PWM是否能连续输出,能则这部分没有问题,不能则PWM部分有问题,先改好。
    然后调测量的程序。
  • TA的每日心情
    开心
    2024-3-10 16:27
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    0

    主题

    1

    回帖

    24

    积分

    新手上路

    积分
    24
    发表于 2024-3-7 14:44:59 | 显示全部楼层
    问题解决没?
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 21:50
  • 签到天数: 152 天

    [LV.7]常住居民III

    34

    主题

    325

    回帖

    653

    积分

    高级会员

    积分
    653
    发表于 2024-3-7 15:46:19 | 显示全部楼层
    void EEPROM_clean(u8 address)
    {
              IAP_CONTR = 0x80;                           //使能IAP
        IAP_TPS = 12;                               //设置等待参数12MHz
        IAP_CMD = 3;                                //设置IAP擦除命令
        IAP_ADDRL = address;                        //设置IAP低地址
        IAP_ADDRH = address >> 8;                   //设置IAP高地址
        IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
        IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
        _nop_();                                    //
        IAP_CONTR = 0;                              //关闭IAP功能
    // IAP_CONTR=0x80;                              //源程序eeprom操作
    //  IAP_ADDRL=address;
    //  IAP_CMD=0x03;
    //  IAP_TRIG=0x46;
    //  IAP_TRIG=0xb9;
    }

    把每个IAP_TPS = 12;      取消掉,初始化配置一次就好,这个不知有没有影响,我是放初始化执行一次

    然后,STC8速度比较快,所以  遇到_nop_();    你就多复制几个    _nop_();     _nop_();     _nop_();     _nop_();   
    纸上得到终觉浅,绝知此事要躬行。
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-5-17 11:01 , Processed in 0.094271 second(s), 68 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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