找回密码
 立即注册
查看: 474|回复: 10

Timer0停止计数

[复制链接]

该用户从未签到

1

主题

3

回帖

23

积分

新手上路

积分
23
发表于 2023-6-1 12:02:45 | 显示全部楼层 |阅读模式
芯片是STC8H3K64S4,30M时钟,定时器0是2mS,运行几分钟以后定时器0就停止计数了,程序和定时器0无关的部分正常运行。

定时器0是用在按键和OLED刷新,所以出现故障很明显。

但是都是,如果在循环里任意一个地方读TR0,定时器就能继续计数。
那位知道这是神马原因?
回复 送花

使用道具 举报

  • TA的每日心情
    开心
    4 小时前
  • 签到天数: 176 天

    [LV.7]常住居民III

    9

    主题

    856

    回帖

    3365

    积分

    论坛元老

    积分
    3365
    发表于 2023-6-1 12:13:39 | 显示全部楼层
    你的程序有缺陷,你把你的代码完整地贴上来看看
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    1

    主题

    3

    回帖

    23

    积分

    新手上路

    积分
    23
     楼主| 发表于 2023-6-1 13:21:07 | 显示全部楼层
    angmall 发表于 2023-6-1 12:13
    你的程序有缺陷,你把你的代码完整地贴上来看看
    1. /***********************************************
    2. File Name: S500.main
    3. Author:
    4. Date:230525
    5. Note:
    6. ************************************************/
    7. #include <STC8H.H>
    8. #include <intrins.h>
    9. #include <stdio.h>
    10. #include "common.h"
    11. #include "I2C.h"
    12. #include "OLED.h"
    13. #include "Display.h"
    14. #include "ScanKey.h"
    15. #include "Config.h"
    16. #include "NTC.c"
    17. #include "SPWM.h"
    18. #include "ADCaverage.h"
    19. //回读修正
    20. xdata float K_V = 8.338;                //AD/显示       
    21. xdata float K_I = 108.05;                //AD/显示               
    22. //基准输出比例
    23. xdata float K_V_REF = 13.087;                //峰值电压基准/输出设定
    24. xdata float K_I_REF = 169.6;                //峰值电流基准/输出设定
    25. //全局变量
    26. bit EN;                //开关;0:关,1:开
    27. bit Start;                //开关机状态
    28. bit Save;                //保存
    29. xdata unsigned char StatusWord = 1;                //0x00:待机;0x01:正常;0x11:故障;0x12输入欠压;0x13输入过压;0x14:过热;0x15:输出欠压;0x16:输出过压;0x17:过流
    30. xdata float Set_V = 0;        //电压设置值
    31. xdata float Set_I = 0;        //电流设置值
    32. xdata unsigned int Set_F = 0;        //频率设置值
    33. unsigned int REF_V;                //电压峰值基准
    34. unsigned int REF_I;                //电流峰值基准
    35. xdata float Test_V = 0;        //电压测量值
    36. xdata float Test_I = 0;        //电流测量值
    37. xdata unsigned char Test_T = 0;        //温度测量值
    38. unsigned int Sense_V, Sense_I, Sense_T, Sense_B, Sense_BUS;                //AD采样值
    39. unsigned long SamplingV;                //电压长采样值
    40. unsigned long SamplingI;                //电流长采样值
    41. unsigned int SamplingCountV;                //电压长采样计数
    42. unsigned int SamplingCountI;                //电流长采样计数
    43. //bit SamplingNewV;                //电压长采样更新
    44. //bit SamplingNewI;                //电流长采样更新
    45. //bit ADC_Busy;
    46. xdata unsigned char inquireCount = 0;                //查询定时
    47. bit IS_OK;                //浪涌抑制完成
    48. //PWM部分
    49. bit PWM_EN;                //PWM启动
    50. bit SoftStart = 1;                //软启动标识,1:需要软启动;0:软启动完成
    51. unsigned char M;                //调制
    52. //保护
    53. bit IN_O;                //输入过压
    54. bit IN_U;                //输入欠压
    55. bit OverV;                //输出过压
    56. bit OverU;                //输出欠压
    57. bit OverI;                //输出过流
    58. bit OverC;                //输出短路
    59. bit OverT;                //过热
    60. xdata unsigned int OverTime;                //过流事件|过流计时
    61. xdata unsigned int OverTimeMemory;                //过流事件|过流计时
    62. xdata unsigned int OverRecover;
    63. bit ErrNew;
    64. bit busy;
    65. //显示部分
    66. xdata char Str_Set_V[6] = {'0', '0', '0', '0', '0', '\0'};
    67. xdata char Str_Set_I[6] = {'0', '0', '0', '0', '0', '\0'};
    68. xdata char Str_Set_F[6] = {'0', '0', '0', '0', '0', '\0'};
    69. xdata char Str_V[6] = {'0', '0', '0', '0', '0', '\0'};
    70. xdata char Str_I[6] = {'0', '0', '0', '0', '0', '\0'};
    71. xdata char Str_F[6] = {'0', '0', '0', '0', '0', '\0'};
    72. xdata unsigned char Display_cls1 = 0, Display_cls2 = 0, Display_cls3 = 0;
    73. xdata unsigned char Display_clsrst = 0;
    74. void CLK_Init(void)
    75. {       
    76.         XOSCCR = 0xc8;                //启动外部晶振       
    77.         while (!(XOSCCR & 1));                //等待时钟稳定
    78.         CLKDIV = 0x00;                //时钟不分频
    79.         CLKSEL = 0x01;                //选择外部高速晶振
    80. }
    81. void GPIO_Init(void)
    82. {
    83.         P0M1 = 0xFD; P0M0 = 0x02; //P0(高高高高高高推高)
    84.         P1M1 = 0xBF; P1M0 = 0x40; //P1(高推高高高高高高)
    85.         P2M1 = 0x00; P2M0 = 0xF3; //P2(推推推推双双推推)
    86.         P3M1 = 0xFD; P3M0 = 0x0E; //P3(高高高高开开推高)
    87.         P4M1 = 0xEB; P4M0 = 0x14; //P4(高高高推高推高高)
    88.         P5M1 = 0xFF; P5M0 = 0x00; //P5(高高高高高高高高)
    89.        
    90.         P01 = 1;
    91.         P20 = 0;
    92.         P21 = 0;
    93.         P24 = 0;
    94.         P25 = 0;
    95.         P26 = 0;
    96.         P27 = 0;
    97.         P42 = 0;
    98. }
    99. void WDTInit(void)
    100. {
    101.         WDT_CONTR |= 0x05;                //配置看门狗定时器 1.26S@20M
    102.         WDT_CONTR |= 0x10;
    103.         WDT_CONTR |= 0x20;       
    104. }
    105. void Timer1Init(void)                //5毫秒@30.000MHz
    106. {
    107.         AUXR &= 0xBF;                //定时器时钟12T模式
    108.         TMOD &= 0x0F;                //设置定时器模式
    109.         TL1 = 0x2C;                //设置定时初始值
    110.         TH1 = 0xCF;                //设置定时初始值
    111.         TF1 = 0;                //清除TF1标志
    112.         ET1 = 1;                //允许中断
    113.         TR1 = 0;                //定时器1开始计时
    114. }
    115. void Config()
    116. {
    117.         REF_V = (unsigned int)(Set_V * K_V_REF);
    118.         REF_I = (unsigned int)(Set_I * K_I_REF);
    119.         PWMA_ARR = MainClock/Element/Set_F+0.5;
    120.         MiddleValue = (PWMA_ARR/2)+0.5;
    121. }
    122. void Change()
    123. {
    124.         xdata unsigned char str[7];
    125.         if(Direction != 0)
    126.         {
    127.                 if(CursorPosition == 0)
    128.                 {
    129.                         if(Direction == 1)
    130.                         {
    131.                                 if(Set_V <= S_O_V_H - 0.1) Set_V +=0.1;
    132.                         }
    133.                         if(Direction == 2)
    134.                         {
    135.                                 if(Set_V >= S_O_V_L + 0.1) Set_V -=0.1;
    136.                         }
    137.                         if(Direction == 10)
    138.                         {
    139.                                 if(Set_V <= S_O_V_H - 1) Set_V +=1;
    140.                         }
    141.                         if(Direction == 20)
    142.                         {
    143.                                 if(Set_V >= S_O_V_L + 1) Set_V -=1;
    144.                         }
    145.                         REF_V = (unsigned int)(Set_V * K_V_REF);
    146.                         sprintf(str, "%5.1f", Set_V);
    147.                         //str[5] = '\0';
    148.                         Display_cls1 = 1;
    149.                         Display_cls2 = 0;
    150.                         Display_cls3 = 0;
    151.                         OLED_P6x8Str_R(68,5,str);
    152.                 }
    153.                 if(CursorPosition == 1)
    154.                 {
    155.                         if(Direction == 1)
    156.                         {
    157.                                 if(Set_I <= S_O_I_H - 0.1) Set_I +=0.1;
    158.                         }
    159.                         if(Direction == 2)
    160.                         {
    161.                                 if(Set_I >= S_O_I_L + 0.1) Set_I -=0.1;
    162.                         }
    163.                         if(Direction == 10)
    164.                         {
    165.                                 if(Set_I <= S_O_I_H - 1) Set_I +=1;
    166.                         }
    167.                         if(Direction == 20)
    168.                         {
    169.                                 if(Set_I >= S_O_I_L + 1) Set_I -=1;
    170.                         }
    171.                         sprintf(str, "%5.2f", Set_I);
    172.                         REF_I = (unsigned int)(Set_I * K_I_REF);
    173.                         //str[5] = '\0';
    174.                         Display_cls1 = 0;
    175.                         Display_cls2 = 1;
    176.                         Display_cls3 = 0;
    177.                         OLED_P6x8Str_R(68,6,str);
    178.                 }
    179.                 if(CursorPosition == 2)
    180.                 {
    181.                         if(Direction == 1)
    182.                         {
    183.                                 if(Set_F <= S_O_F_H - 1) Set_F +=1;
    184.                         }
    185.                         if(Direction == 2)
    186.                         {
    187.                                 if(Set_F >= S_O_F_L + 1) Set_F -=1;
    188.                         }
    189.                         if(Direction == 10)
    190.                         {
    191.                                 if(Set_F <= S_O_F_H - 10) Set_F +=10;
    192.                         }
    193.                         if(Direction == 20)
    194.                         {
    195.                                 if(Set_F >= S_O_F_L + 10) Set_F -=10;
    196.                         }
    197.                         PWMA_ARR = MainClock/Element/Set_F+0.5;
    198.                         MiddleValue = (PWMA_ARR/2)+0.5;
    199.                         str[0] = Set_F/100+48;
    200.                         str[1] = Set_F/10%10+48;
    201.                         str[2] = Set_F%10+48;
    202.                         str[3] = '\0';
    203.                         Display_cls1 = 0;
    204.                         Display_cls2 = 0;
    205.                         Display_cls3 = 1;
    206.                         OLED_P6x8Str_R(80,7,str);
    207.                 }
    208.                 Direction = 0;
    209.         }
    210. }
    211. //刷新
    212. void Display_Refresh()
    213. {
    214.         xdata unsigned char i;
    215.         xdata unsigned char str[7];
    216.        
    217.         ET0 = 0;
    218.        
    219.         //Change();
    220.         if(Refresh_Count > 250)
    221.         {               
    222.                 Refresh_Count = 0;
    223.                 if((Display_cls1 == 1) || (Display_cls2 == 1) || (Display_cls3 == 1))
    224.                 {
    225.                         if(Direction == 0) Display_clsrst++;
    226.                         if(Display_clsrst > 10)
    227.                         {
    228.                                 Display_cls1 = 0;
    229.                                 Display_cls2 = 0;
    230.                                 Display_cls3 = 0;
    231.                                 Display_clsrst = 0;
    232.                                 //save
    233.                         }
    234.                 }
    235.                
    236.                 sprintf(str, "%5.1f", Test_V);
    237.                 for(i=0; i<6; i++)
    238.                 {
    239.                         Str_V[i] = str[i];
    240.                 }
    241.                
    242.                 sprintf(str, "%5.2f", Test_I);
    243.                 for(i=0; i<6; i++)
    244.                 {
    245.                         Str_I[i] = str[i];
    246.                 }               
    247.                 if(StatusWord == 0x01)
    248.                 {
    249.                         Str_F[0] = Set_F/100+48;
    250.                         Str_F[1] = Set_F/10%10+48;
    251.                         Str_F[2] = Set_F%10+48;
    252.                         Str_F[3] = '\0';
    253.                 }
    254.                 else
    255.                 {
    256.                         Str_F[0] = '0';
    257.                         Str_F[1] = '0';
    258.                         Str_F[2] = '0';
    259.                         Str_F[3] = '\0';
    260.                 }
    261.                
    262.                 Display_Cursor(CursorPosition);                //更新光标位置
    263.                 Display_Fill1(StatusWord);
    264.                 if(Display_cls1 == 0) Display_Fill(4, Str_V);
    265.                 if(Display_cls2 == 0) Display_Fill(5, Str_I);
    266.                 if(Display_cls3 == 0) Display_Fill(6, Str_F);               
    267.                        
    268.                        
    269.                 //OLED_Display_16bit_number(68,3,Test_T-40);                //test
    270.                 OLED_Display_16bit_number(68,3,PWMA_ARR);                //test
    271.         }       
    272.         ET0 = 1;
    273. }
    274. void ONOFF()
    275. {
    276.         //开机过程               
    277.         if((EN) && (IS_OK))                //开机
    278.         {
    279.                 Start = 1;
    280.         }
    281.         else
    282.         {
    283.                 Start = 0;
    284.         }
    285.        
    286.         if(Start)
    287.         {
    288.                 PWM_EN = 1;       
    289.         }
    290.         else
    291.         {
    292.                 M = 0;
    293.                 PWM_EN = 0;
    294.                 SoftStart = 1;
    295.         }
    296.        
    297.         if((PWM_EN == 1) && (SoftStart == 1))                //软启动
    298.         {
    299.                 TR1 = 1;                //定时器1计时控制
    300.         }
    301. }
    302. //定时器1中断
    303. void timer1_isr() interrupt 3                //软起动&保护
    304. {
    305.        
    306.         //软启动
    307.         if((PWM_EN == 1) && (SoftStart == 1))               
    308.         {
    309.                 M++;
    310.                 if(M >= Level-20)
    311.                 {
    312.                         SoftStart = 0;
    313.                 }
    314.                
    315.                 //Sense_V = Absolute(Get_ADC(0x01), Get_ADC(0x00));
    316.                 if(Sense_V >= REF_V - 50)
    317.                 {                               
    318.                         SoftStart = 0;
    319.                 }
    320.         }
    321.        
    322.         //温度查询
    323.         inquireCount++;
    324.         if(inquireCount > 100)
    325.         {
    326.                 xdata unsigned char i;
    327.                 inquireCount = 0;
    328.                 Sense_T = ADCaverage(0x02);
    329.                 if(Sense_T < 6)
    330.                 {
    331.                         Test_T = 254;
    332.                 }
    333.                 if(Sense_T > 3104)
    334.                 {
    335.                         Test_T = 255;
    336.                 }
    337.                 for(i=0;i<160;i++)
    338.                 {
    339.                         if(NTCV[i] >= Sense_T)
    340.                         {
    341.                                 Test_T = i;
    342.                                 break;
    343.                         }
    344.                 }
    345.         }
    346. }
    347. unsigned int Absolute(unsigned int a, unsigned int b)
    348. {
    349.         unsigned int c;
    350.         if(a >= b)
    351.         {
    352.                 c = a - b;
    353.         }
    354.         else
    355.         {
    356.                 c = b - a;
    357.         }
    358.         return (c);
    359. }
    360. void inquire()
    361. {
    362.         Sense_B = ADCaverage(0x0c);
    363.         Sense_BUS = ADCaverage(0x0b);
    364. }
    365. void Sampling()                //20uS
    366. {
    367.        
    368. }
    369. void status()
    370. {
    371. //bit IN_O;                //输入过压
    372. //bit IN_U;                //输入欠压
    373. //bit OverV;                //输出过压
    374. //bit OverU;                //输出欠压
    375. //bit OverI;                //输出过流
    376. //bit OverC;                //输出短路
    377. //bit OverT;                //过热
    378. }
    379. void PID()                //12bit:23uS/45uS
    380. {
    381.         unsigned char Factor = 15;                //比例系数
    382.         unsigned int Diffe;                //差值
    383.         bit Direction;                //差值方向
    384.         unsigned int P;                //增量
    385.        
    386.         if(SinPeak)
    387.         {
    388.                 SinPeak = 0;
    389.                 Sense_V = Absolute(Get_ADC1(0x01), Get_ADC1(0x00));
    390.                 if(Sense_V >= REF_V)
    391.                 {
    392.                         Diffe = Sense_V - REF_V;
    393.                         Direction = 1;
    394.                         SoftStart = 0;
    395.                 }
    396.                 else
    397.                 {
    398.                         Diffe = REF_V - Sense_V;
    399.                         Direction = 0;
    400.                 }
    401.                
    402.                 P = Diffe / Factor;                //P
    403.                
    404.                 if(!SoftStart)
    405.                 {
    406.                         if(Direction)
    407.                         {
    408.                                 M = M - P;
    409.                         }
    410.                         else
    411.                         {
    412.                                 M = M + P;
    413.                         }
    414.                 }
    415.                
    416.                 //
    417.                 if(M <= 0)
    418.                 {
    419.                         M = 0;
    420.                 }
    421.                 if(M >= Level)
    422.                 {
    423.                         M = Level - 1;
    424.                 }
    425.                
    426.                 //电压长采样
    427.                 SamplingV += Sense_V;
    428.                 SamplingCountV++;
    429.                 if(SamplingCountV >= (Element - 1))
    430.                 {
    431.                         Test_V = (float)(SamplingV / SamplingCountV) / K_V;
    432.                         SamplingV = 0;
    433.                         SamplingCountV = 0;
    434.                                                
    435.                         //SamplingNewV = 1;
    436.                 }
    437.                 //电流长采样
    438.                 Sense_I = Absolute(Get_ADC1(0x0e), Get_ADC1(0x0d));
    439.                 SamplingI += Sense_I;
    440.                 SamplingCountI++;
    441.                 if(SamplingCountI >= (Element - 1))
    442.                 {
    443.                         Test_I = (SamplingI / SamplingCountI) / K_I;
    444.                         SamplingI = 0;
    445.                         SamplingCountI = 0;
    446.                                                
    447.                         //SamplingNewV = 1;
    448.                 }
    449.                
    450.         }       
    451.        
    452. }
    453. void ADC_Isr() interrupt 5
    454. {
    455.        
    456.         ADC_CONTR &= ~0x20;         //清中断标志       
    457.         EA = 1;       
    458.         TR0 = 1;                //定时器0开始计时
    459.         EADC = 0;                //使能ADC中断               
    460.         PID();       
    461. }
    462. void main()
    463. {
    464.         P_SW2 |= 0x80;         //使能访问 XFR       
    465.         CLK_Init();
    466.         GPIO_Init();
    467.         ADCInit();
    468.         ConfigRead();
    469.         PWM_Init();
    470.         Config();
    471.         I2C_Init();
    472.         OLED_Init();
    473.         //Display_Start();
    474.         Display_Frame();
    475.         Timer0Init();
    476.         Timer1Init();
    477.        
    478.         //OLED_Display_16bit_number(68,3,REF_I);
    479.         EN = 1;       
    480.         IS_OK = 1;
    481.         M = 98;
    482. ///////////////////////
    483.        
    484.        
    485.         IP = 0x10;
    486.         IPH = 0x20;
    487.         IP2 = 0x04;
    488.         IP2H = 0x04;
    489.         EA = 1;
    490.         Change();
    491.         while(1)
    492.         {
    493.                 Change();
    494.                 ONOFF();
    495.                 Display_Refresh();
    496.                
    497.                
    498.                
    499.                 if(Save == 1)
    500.                 {
    501.                         Save = 0;
    502.                         OLED_P8x16Str(68,3,"Save...");
    503.                         ConfigWrite();
    504.                         OLED_P8x16Str(68,3,"       ");
    505.                 }
    506.                
    507.                 //P26 = TR0;
    508.                
    509.         ///////////////////////////////////////////////////////
    510.         WDT_CONTR |= 0x10;
    511.         }
    512. }
    复制代码
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    1

    主题

    3

    回帖

    23

    积分

    新手上路

    积分
    23
     楼主| 发表于 2023-6-1 13:25:42 | 显示全部楼层
    angmall 发表于 2023-6-1 12:13
    你的程序有缺陷,你把你的代码完整地贴上来看看

    目前已知:ADC中断如果不开启中断嵌套(494行)就不会导致这个问题

    点评

    那估计你的中断程序有问题,仔细检查。  详情 回复 发表于 2023-6-1 13:54
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    46

    主题

    3038

    回帖

    6847

    积分

    超级版主

    积分
    6847
    发表于 2023-6-1 13:54:03 | 显示全部楼层
    jeff.c 发表于 2023-6-1 13:25
    目前已知:ADC中断如果不开启中断嵌套(494行)就不会导致这个问题

    那估计你的中断程序有问题,仔细检查。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    2023-12-5 13:56
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    12

    主题

    259

    回帖

    1590

    积分

    超级版主

    积分
    1590
    发表于 2023-6-1 16:02:14 | 显示全部楼层

    用这个范例试下:
    1.png
    电话:0513-55012946 QQ:2195591714  微信:  19952583740
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    4 小时前
  • 签到天数: 176 天

    [LV.7]常住居民III

    9

    主题

    856

    回帖

    3365

    积分

    论坛元老

    积分
    3365
    发表于 2023-6-1 16:10:37 | 显示全部楼层
    没有看见这个程序 Timer0Init();
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    1

    主题

    3

    回帖

    23

    积分

    新手上路

    积分
    23
     楼主| 发表于 2023-6-1 16:23:47 | 显示全部楼层
    STC32G12K128 发表于 2023-6-1 16:02
    用这个范例试下:

    是的,平时都是用STCISP工具配置的定时器
    1. void Timer0Init(void)                //2毫秒@30.000MHz
    2. {
    3.         AUXR &= 0x7F;                //定时器时钟12T模式
    4.         TMOD &= 0xF0;                //设置定时器模式
    5. //        TL0 = 0x3C;                //设置定时初始值                //1mS
    6. //        TH0 = 0xF6;                //设置定时初始值
    7.         TL0 = 0x78;                //设置定时初始值                //2mS
    8.         TH0 = 0xEC;                //设置定时初始值
    9.         TF0 = 0;                //清除TF0标志
    10.         TR0 = 1;                //定时器0开始计时
    11.         ET0 = 1;
    12.         //IP &= 0xfd;
    13.         //IPH &= 0xfd;
    14. }
    复制代码
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    4 小时前
  • 签到天数: 176 天

    [LV.7]常住居民III

    9

    主题

    856

    回帖

    3365

    积分

    论坛元老

    积分
    3365
    发表于 2023-6-1 16:34:47 | 显示全部楼层
    那估计你的ADC中断程序运行超过两毫秒。你需要调整一下。
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    4

    主题

    12

    回帖

    63

    积分

    注册会员

    积分
    63
    发表于 2023-6-2 11:40:13 | 显示全部楼层
    本帖最后由 pingfr 于 2023-6-2 11:41 编辑

    我的STC32G12K也遇到类似问题,开timer0中断后进入一次就再也不进了,配置也没啥特殊的
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-5-18 04:58 , Processed in 0.155326 second(s), 68 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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