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

求指教,冲哥stc32g12课计数器本人实验失败求解

[复制链接]

该用户从未签到

13

主题

25

回帖

141

积分

注册会员

积分
141
发表于 2023-7-18 20:32:38 | 显示全部楼层 |阅读模式
本帖最后由 工控单片机 于 2023-7-18 22:33 编辑

问题描述:1.TH1和TL1的值在定时器1ms中断服务函数里计时2000ms时,Tim_Count被成功清零,TH1和TL1没有被清零。T1按键也就是P35我不按他的情况下,TH1和TL1无规律的几分钟加1.以下是我的代码,求计数大佬指教。有人说TR1=0以后才能给TH1和TL1清零,有人说不用,我试过了,TR1=0后确实能清零,但是马达计数效果不理想。冲哥视频中也没先给TR1=0后再清零。然后再在定时器0中给TR1=1.希望有大佬答疑。
#include "stc.h"
#include "usb.h"
#include "math.h"

#define KEY1 P32
#define KEY2 P33
#define BEEP P54
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";                      //设置自动复位到ISP区的用户接口命令
u8 Num_Geg[21]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10,0xff};//0-9数码管显示, 段码,0.-9.带小数点。
u8 Com_tab[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//从左到右1-8位数码管的位码
u8 Show_tab[8]={20,20,20,20,0,0,0,0};//右边到左边倒数第三个数组填10,数码管显示“0.”这里显示的内容可以用来灵活替换Num_Geg内容
u8 num =0;
u32 Tim_Count = 0;//计时1ms
u16 Count_t1 = 0;//计数寄存器,赋初值。
void Seg_Fre()//数码管刷新函数
{
        P7=Com_tab[num];
        P6=Num_Geg[Show_tab[num]];
//        delay_ms(1);============使用定时器刷新,delay函数不需要直接屏蔽掉
        num++;
        if(num>7)
        num=0;
}
void sys_init()
{
    WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;   //设置为准双向口
    P2M1 = 0x00;   P2M0 = 0x00;   //设置为准双向口
    P3M1 = 0x00;   P3M0 = 0x00;   //设置为准双向口
    P4M1 = 0x00;   P4M0 = 0x00;   //设置为准双向口
    P5M1 = 0x00;   P5M0 = 0x00;   //设置为准双向口
    P6M1 = 0x00;   P6M0 = 0x00;   //设置为准双向口
    P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口

    //====== USB 初始化 ======
    P3M0 &= ~0x03;
    P3M1 |= 0x03;

    IRC48MCR = 0x80;
    while (!(IRC48MCR & 0x01));

    USBCLK = 0x00;
    USBCON = 0x90;
    //========================
}
void Timer0_Init(void)                //1毫秒@24.000MHz  1ms定时器初始化
{
        AUXR &= 0x7F;                        //定时器时钟12T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0x30;                                //设置定时初始值
        TH0 = 0xF8;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}


//主函数入口
void main()
{   
        Timer0_Init();
    TMOD = 0x40;                        //设置计数器模式
        TL1 = 0x00;                                //设置计数器初始值========计数两次脉冲进入中断
        TH1 = 0x00;                                //设置计数器初始值
        TF1 = 0;                                //清除TF0标志
        TR1 = 1;                //计数器1开始计时                                
    ET1 = 1;                                //使能计数器1中断
        P3PU = 0x20; //打开计数器P35的4.1K上拉电阻,P34,P35用作脉冲计数推荐打开内部上拉
        EA = 1;                 //打开总中断

    sys_init();  //系统初始化
    usb_init();  //USB CDC 接口配置  
//死循环   
        while (1)
        {               
                if(DeviceState != DEVSTATE_CONFIGURED)  //等待USB完成配置
            continue;
               
        if (bUsbOutReady)
        {
            usb_OUT_done();    //接收应答(固定格式)

                        printf("计算结果:%d\r\n",TL1);
                        printf("计算结果:%d\r\n",Count_t1);
//            memcpy(UsbInBuffer, UsbOutBuffer, OutNumber);  //将接收数据(UsbOutBuffer),复制到发送缓冲区(UsbInBuffer)
//            usb_IN(OutNumber);      //原路返回, 用于测试
        }  
    }
}
//void Tim1_Isr() interrupt 3//计数器1中断函数,中断号3,固定格式计数器0中断号必须是1,计数器1中断号是3,
//{
//        P60 = !P60;
//}
void Timer0_Isr(void) interrupt 1//定时器1ms中断服务函数
{
        
        Tim_Count++;
        if(Tim_Count>=2000)//计时到达2000MS,也就是2S,
        {
                Tim_Count = 0;//计时值清零,
                Count_t1 = (TH1*256)+TL1;//读计数寄存器高八位TH1和低八位TL1的值转换成10进制

                Show_tab[4]=Count_t1/1000%10;
                Show_tab[5]=Count_t1/100%10;
                Show_tab[6]=Count_t1/10%10;
                Show_tab[7]=Count_t1/1%10;            //取1位               
                TH1 = 0;//计数值清零,
                TL1 = 0;//计数值清零,
        }
        Seg_Fre();
}

回复 送花

使用道具 举报

  • TA的每日心情
    奋斗
    2023-12-13 11:59
  • 签到天数: 1 天

    [LV.1]初来乍到

    3

    主题

    337

    回帖

    1651

    积分

    版主

    积分
    1651
    发表于 2023-7-19 09:25:16 | 显示全部楼层
    您的STC32G12K128实验箱是哪个版本呢?先跑例程试下吧
    QQ:2269694595     微信:18106296594
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    13

    主题

    25

    回帖

    141

    积分

    注册会员

    积分
    141
     楼主| 发表于 2023-7-19 20:34:18 | 显示全部楼层
    9.6版本的。单独跑计数没发现问题,计数没试过溢出之前重新赋值。只测试了溢出后重新赋值。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    13 小时前
  • 签到天数: 139 天

    [LV.7]常住居民III

    26

    主题

    1332

    回帖

    4145

    积分

    论坛元老

    积分
    4145
    发表于 2023-7-21 11:45:35 | 显示全部楼层
    本帖最后由 乘风飞扬 于 2023-7-21 11:46 编辑


    定时器0,1这部分功能是一样的
    1.png
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    13

    主题

    25

    回帖

    141

    积分

    注册会员

    积分
    141
     楼主| 发表于 2023-7-21 19:13:06 | 显示全部楼层
    感谢,我理解了,谢谢
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    3

    主题

    7

    回帖

    39

    积分

    新手上路

    积分
    39
    发表于 2023-8-5 17:35:43 | 显示全部楼层
    乘风飞扬 发表于 2023-7-21 11:45
    定时器0,1这部分功能是一样的

    不太理解
    它的意思是不是TR0=1时,TH0和TL0有值,再给它俩赋值的时候,是把值存在了隐藏的寄存器中,不会改变TH0和TL0的值?只会读到TH0,TL0的值
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    奋斗
    13 小时前
  • 签到天数: 139 天

    [LV.7]常住居民III

    26

    主题

    1332

    回帖

    4145

    积分

    论坛元老

    积分
    4145
    发表于 2023-8-6 12:13:59 | 显示全部楼层
    cc.cn 发表于 2023-8-5 17:35
    不太理解
    它的意思是不是TR0=1时,TH0和TL0有值,再给它俩赋值的时候,是把值存在了隐藏的寄存器中,不会 ...

    TR0=1时往TH0,TL0写的值是放到隐藏寄存器,而不是直接写到TH0,TL0。当计数器产生溢出时才会将隐藏寄存器里的值载入TH0,TL0。读取时是直接读取TH0,TL0的值。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2023-12-14 08:57
  • 签到天数: 1 天

    [LV.1]初来乍到

    4

    主题

    93

    回帖

    495

    积分

    中级会员

    积分
    495
    发表于 2023-8-6 18:28:30 | 显示全部楼层
    我刚解决了:
    TMOD = 0x40;                        //设置计数器模式,自动装入
            TL1 = 0x00;                                //设置计数器初始值========计数两次脉冲进入中断
            TH1 = 0x00;                                //设置计数器初始值
            TF1 = 0;                                //清除TF0标志
            TR1 = 1;                //计数器1开始计时                                
        ET1 = 1;                                //使能计数器1中断
            P3PU = 0x20; //打开计数器P35的4.1K上拉电阻,P34,P35用作脉冲计数推荐打开内部上拉
            EA = 1;                 //打开总中断

    要设置为TMOD = 0x50;                        //设置计数器模式,不自动装入。
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2023-12-14 08:57
  • 签到天数: 1 天

    [LV.1]初来乍到

    4

    主题

    93

    回帖

    495

    积分

    中级会员

    积分
    495
    发表于 2023-8-6 18:32:02 | 显示全部楼层
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    3

    主题

    7

    回帖

    39

    积分

    新手上路

    积分
    39
    发表于 2023-8-8 11:32:10 | 显示全部楼层
    乘风飞扬 发表于 2023-8-6 12:13
    TR0=1时往TH0,TL0写的值是放到隐藏寄存器,而不是直接写到TH0,TL0。当计数器产生溢出时才会将隐藏寄存器 ...

    懂了
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

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

    GMT+8, 2024-5-13 22:10 , Processed in 0.072293 second(s), 67 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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