找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2764|回复: 8
打印 上一主题 下一主题
收起左侧

STC单片机更改定时器优先级,定时器不正常

[复制链接]
跳转到指定楼层
楼主
ID:734017 发表于 2021-11-22 16:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
优先级那里IP和IPH 如果不加程序就到不了上电握手那里,卡在某一个函数,如果加了,定时器0初值就不对,但定时器1和串口1是对的,都是1T,我试过在while里面把定时0的初值改变重新加载,又是对的。因为调用定时器1的时候要最高优先,不然中断跳变严重,需要定时器0的时候再改回来。上电默认定时0开启。初值不对。

void Timer0()      
{     
        AUXR &= 0x0f;                        //1T
        AUXR |= 0xc0;
        TMOD &= 0xF0;           //清零T0的控制位
        TL0 = 0xA0;               
        TH0 = 0xF6;        
        TF0 = 0;
        ET0 = 1;        //使能T0中断
        TR0 = 1;        //启动T0
}
void TM0_Isr() interrupt 1                                        //定时器0中断
{
               
                if(SK_lock)                                                                                 
                {
                        
                        //P0^=0x03;
                                SK_L =~SK_L;
                                _nop_();
                                SK_H =~SK_H;
                        //return;
                }
                        if (clok_lock)                                                               
                        {
                                clok_satar=~clok_satar;
                        }
                        if(clok_HOT)
                        {        
                                clok_HOT_tmie=~clok_HOT_tmie;
                        }        
                                                if(ul_1_lock|ul_2_lock)                                                
                                                {
                                                        ul_satar=~ul_satar;
                                                        //return;
                                                }
                                                        if(ion_1_lock)                                                               
                                                        {
                                                                ion1_satar=~ion1_satar;
                                                                //return;
                                                        }
                                                                if(ion_2_lock)                                                        
                                                                {        
                                                                        ion2_satar=~ion2_satar;
                                                                        //return;
                                                                }
}

void Timer1()
        {
                TMOD |= 0x10;                                                   
        TL1 = (65535-RF_Duty)%256;               
        TH1 = (65535-RF_Duty)/256;                       
        TF1 = 0;                                                               
        ET1 = 0;
                TR1 = 0;                                                        
        }

void TM1_Isr() interrupt 3                                                              
{    if(RF_lock)
                        {
                         if(RF_PWM_H)
                                         {
                                                        RF_PWM_H=0;
                                                        RF_PWM_OUT=1;      
                                                        TL1 = RF_PWM_TIME_H_L;                //???????
                                                        TH1 = RF_PWM_TIME_H_H;                //???????
                                         }
                                else
                                         {
                                                        RF_PWM_H=1;
                                                        RF_PWM_OUT=0;      
                                                        TL1 = RF_PWM_TIME_L_L;                //???????
                                                        TH1 = RF_PWM_TIME_L_H;                //???????
                                         }               
                        }  
                else if(SK_lock)
                                {
                                        if(RF_PWM_H)
                                                         {
                                                                RF_PWM_H=0;
                                                                SS_int_ADJ=1;      
                                                                TL1 = RF_PWM_TIME_H_L;                //???????
                                                                TH1 = RF_PWM_TIME_H_H;                //???????
                                                         }
                                        else
                                                         {
                                                                RF_PWM_H=1;
                                                                SS_int_ADJ=0;      
                                                                TL1 = RF_PWM_TIME_L_L;                //???????
                                                                TH1 = RF_PWM_TIME_L_H;                //???????
                                                         }
                                }
                        
}



//*************************UART设置*****************************

uchar buf[18];
uchar rp = 0;
uchar TI_Busy = 0;
uchar TI_Busy1 = 0;
void UartInit()
        {
                SCON = 0x50;                         //可变波特率8位数据方式
                S2CON = 0x50;                        //8位数据,可变波特?
                AUXR |= 0x15;                        //不分频.启动定时器2
                //T2L = BRT;
                //T2H = BRT >> 8;        
                T2L = 0xCC;                //24M1T
                T2H = 0xFF;        
                ES = 1;                                 //使能串口1中断
                //IE2 |=0x01;                        //使能串口2中断
        }

void IapIdle()
{
        IAP_CONTR        =0;                        //关闭IAP功能
        IAP_CMD                =0;                        //清除命令寄存器
        IAP_TRIG         =0;                        //清除触发寄存器
        IAP_ADDRH        =0x80;                //将地址设置到非IAP区域
        IAP_ADDRL        =0;                        //
}
/*----------------------------
从ISP/IAP/EEPROM读一字节
----------------------------*/
unsigned char IapRead(unsigned int addr)                                //读
{
    unsigned char dat;                       //数据缓冲区

    IAP_CONTR = WT_24M;                 //使能IAP
    IAP_CMD = 1;                             //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    dat = IAP_DATA;                 //读ISP/IAP/EEPROM数据
   // IapIdle();                      //关闭IAP功能

    return dat;                     //返回
}
unsigned int IapRead_two(unsigned int addr)                                //读int
{
    unsigned int dat;                       //数据缓冲区

    IAP_CONTR = WT_24M;                 //使能IAP
    IAP_CMD = 1;                             //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
    dat = IAP_DATA;                 //读ISP/IAP/EEPROM数据
        dat=dat<<8;
        if(++IAP_ADDRL == 0)  
                IAP_ADDRH++;
    IAP_TRIG = 0x5a;               
    IAP_TRIG = 0xa5;   
        _nop_();        
        dat |= IAP_DATA;  
   // IapIdle();                      //关闭IAP功能

    return dat;                     //返回
}

/*----------------------------
写一字节数据到ISP/IAP/EEPROM区域
----------------------------*/
void IapProgram(unsigned int addr, unsigned char dat)        //写
{
    IAP_CONTR = WT_24M;                 //使能IAP
    IAP_CMD = 2;                                 //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_DATA = dat;                 //写ISP/IAP/EEPROM数据
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
   // IapIdle();
}

void IapProgram_two(unsigned int addr, unsigned int dat)        //写int
{
    IAP_CONTR = WT_24M;                 //使能IAP
    IAP_CMD = 2;                                 //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_DATA = dat>>8;                 //写ISP/IAP/EEPROM数据
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
        if(++IAP_ADDRL == 0)  
                IAP_ADDRH++;
    IAP_DATA = dat;               
    IAP_TRIG = 0x5a;               
    IAP_TRIG = 0xa5;   
        _nop_();                        //等待ISP/IAP/EEPROM操作完成   
   // IapIdle();
}
/*----------------------------
扇区擦除
----------------------------*/
void IapErase(unsigned int addr)                                //擦除
{
    IAP_CONTR = WT_24M;                 //使能IAP
    IAP_CMD = 3;                            //设置IAP命令
    IAP_ADDRL = addr;               //设置IAP低地址
    IAP_ADDRH = addr >> 8;          //设置IAP高地址
    IAP_TRIG = 0x5a;                //写触发命令(0x5a)
    IAP_TRIG = 0xa5;                //写触发命令(0xa5)
    _nop_();                        //等待ISP/IAP/EEPROM操作完成
   // IapIdle();
}
//--------------------------------------------------------------------
/*比较器*/
        void CMPCR_data()
        {
                CMPCR2                =0x80;
                CMPCR2                &=~0x80;                //正向输出
                //CMPCR2        |=0x80;                        //反向输出
                CMPCR2                &=~0x40;                //禁止0.1US滤波
                //CMPCR2        |=0x40;                        //0.1US滤波
                //CMPCR2        &-~0x3f;                //比较器直接输出
                CMPCR2                |=0x10;                        //16个去抖输出
                CMPCR1                =0x00;
                CMPCR1                |=0x30;                        //边沿中断
                //CMPCR1                &=0x~20;        //禁止上升中断
                //CMPCR1                |=0x20;                //上升中断
                //CMPCR1                &=~0x10;        //禁止下降中断
                //CMPCR1                |=0x10;                //下降中断
                CMPCR1                &=~0x08;                //P3.7+
                //CMPCR1                |=0x08;                //ADC输入
                CMPCR1                &=~0x04;        //内部CMP-        
                //CMPCR1                |=0x04;                        //P3.6CMP-
                CMPCR1                &=~0x02;        //禁止输出
                //CMPCR1                |=0x02;                        //输出        
                CMPCR1                |=0x80;                        //开比输器
               
        }
        
void IOsatar()
{
//IP    = 0x12;
//IPH   = 0x0a;    // 定时器0最高级            
P0M1 = 0x00;
P0M0 = 0xFF;
P1M1 = 0x00;
P1M0 = 0xff;
P2M1 = 0x00;
P2M0 = 0xFF;
P3M1 = 0x80;
P3M0 = 0x7e;
//P4M1 = 0xb3;
//P4M0 = 0xb4;
P5M1 = 0x00;
P5M0 = 0x30;     

//00准双向口(传统8051端口模式,弱上拉)
//01推挽输出
//10高阻输入
//11开漏输出
        
P0 = 0x06;                                //上电输出
P1 = 0x40;
P2 = 0x2b;
P3 = 0x7b;
sk_OUT=0;                                    
RF_Duty = 180;          //高电平初值
SK_Duty = 180;

}


void main()
{
                        
                        P_SW2 |= 0x80;                        //扩展 RAM 区特殊功能寄存器(XFR)访问控制寄存器
                        //CKSEL = 0x00;         //8H默认内部IRC
                        CKSEL = 0x00;                 //8F 默认内部IRC  不输出 ,默认管脚
                        //CLKDIV =0x04;           //SYSCLK时钟,默认4分频
                        CLKDIV =0x00;           //不分频SYSCLK时钟
                        IOsatar();                                //IO口模式
                        Timer0();                                 //定时器0 100US
                        Timer1();                                 //定时器1
                        //Timer3();                                //定时器3
                        UartInit();                          //串口中断
                        //ADC_Init();                        //ADC 中断
                        EA=1;
                        CMPCR_data();                        //比较器
                        Power_on_reset();                //上电握手
while(1)
        {          .....................
}
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:57657 发表于 2021-11-22 18:41 | 只看该作者
请在 while (1) 里面加一句 WDT_CONTR |=0x10;
回复

使用道具 举报

板凳
ID:624769 发表于 2021-11-22 18:59 | 只看该作者
//                        EA=1;
                        CMPCR_data();                        //比较器
                        Power_on_reset();                //上电握手
                        TF0 = 0;
                        EA=1;
回复

使用道具 举报

地板
ID:734017 发表于 2021-11-23 00:23 | 只看该作者
npn 发表于 2021-11-22 18:41
请在 while (1) 里面加一句 WDT_CONTR |=0x10;

请问有什么作用,我没用看门狗呢
回复

使用道具 举报

5#
ID:734017 发表于 2021-11-23 00:27 | 只看该作者
188610329 发表于 2021-11-22 18:59
//                        EA=1;
                        CMPCR_data();                        //比较 ...

不行,发现串口中断接收不了,一直发送就是接收不了。加上IP    = 0x12;IPH   = 0x0a;又可以了,奇怪,刚开始我没启用优先级寄存器一切正常,启用过后,发现定时器不对。取消就影响串口接收
回复

使用道具 举报

6#
ID:734017 发表于 2021-11-23 01:34 | 只看该作者
188610329 发表于 2021-11-22 18:59
//                        EA=1;
                        CMPCR_data();                        //比较 ...

CMPCR1                |=0x30;                        //边沿中断
可能是这个,没有对应的中断号
回复

使用道具 举报

7#
ID:624769 发表于 2021-11-23 12:57 | 只看该作者
happy2058 发表于 2021-11-23 01:34
CMPCR1                |=0x30;                        //边沿中断
可能是这个,没有对应的中断号

interrupt  21
回复

使用道具 举报

8#
ID:57657 发表于 2021-11-23 13:12 | 只看该作者
happy2058 发表于 2021-11-23 00:23
请问有什么作用,我没用看门狗呢

看门狗是每个程序都必须开的,否则受到干扰都找不到北。
回复

使用道具 举报

9#
ID:624769 发表于 2021-11-23 13:22 | 只看该作者
在实际使用时, 看门狗能在一定程度上有效防止意外跑飞后的各种问题。
同时,在调试阶段,看门狗也会极大限度的掩盖程序设计中的大量逻辑错误。如果要赶工期应付老板,看门狗是一大利器,要是自己凭借爱好做东西,至少在所有功能调试完毕满意之前,不要用看门狗。
回复

使用道具 举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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