搞全栈小苏 2024-03-27 11:54 采纳率: 0%
浏览 14

HC89S003A做可控硅调光

早上好各位!我在使用HC89S003A做可控硅调光时,外中断服务程序中开启一个定时器(T1)可以正常调光,同时开启2个定时器(T1和T4)实现2路调光就不能,先前的1路调光也不能正常工作了。请教,谢谢! (程序中还开启了T0做简单定时标记)
这是我的定时器代码

#include "HC89S003AF4.h"
#include "globl.h"


extern bit    f_pwr1, f_pwr2;
extern bit f_adj_bright1, f_adj_bright2;

extern unsigned short bright1_curr, bright2_curr;

//extern sbit TRIAC;

static unsigned int count1=0, count2=0;

// 0.5ms
//初始化定时器1
void triac2_init(void)
{
    TCON1 = 0x00;                          //T1定时器时钟为Fosc
    TMOD = 0x00;                          //16位重装载定时器/计数器

    //Tim1计算时间     = (65536 - 0xFACB) * (1 / (Fosc /Timer分频系数))
    //                = 1333 / (16000000 / 12)
    //                = 1 ms

    //定时1ms
    //反推初值     = 65536 - ((1/1000) / (1/(Fosc / Timer分频系数)))
    //               = 65536 - ((1/1000) / (1/(16000000 / 12)))
    //            = 65536 - 1333
    //            = 0xFACB
    
    TH1 = 0x80;//0xFD;//A;
    TL1 = 0x00;//0x76;//CB;
    IE |= 0x08;                    //打开T1中断
    //TCON |= 0x40;                //使能T1
    
    EA = 1;                        //打开总中断
}

///// TCON  [7:0]---[7].TF1; [6].TR1; [5].TF0; [4].TR0; [3:0].RSV
///   TCON1 [7:0]---[7].RSV; [6].RSV; [5].T1O; [4].T1CLKS; [3,2].RSV; [1].T0O; [0].T0CLKS
///   IE    [7:0]---[7].EA;  [6].EUART2; [5].EWDT; [4].EUART1; [3].ET1; [2].EX1; [1].ET0;[0].EX0
///   IE1   [7:0]---[7].EX8_15;[6].EX2_7;[5].EADC; [4].ET5; [3].EIIC; [2].ET4; [1].ET3; [0].ESPI
///   T3CON [7:0]-- [7].TF3;    [6].PDEN; [5,4].PS:00-1; [3].RSV; [2].TR3:0-DS; [1,0].CLKS:00-Fosc
//                                                  01-8                   1-EN             01-exck
//                                                  10-64                                   10-32768
//                                                  11-256                                  11-RC44K
//    T4CON [7:0]=--[7].TF4;     [6].TC4   [5,4].PRES; [3,2].MODE; [1].TR4; [0].T4CLKS
//    T5CON [7:0]---[7].TF5(SC); [6].EXF5; [5,4].PRES; [3,2].MODE; [1].TR5; [0].EXEN5
//    T5CON1[7:0]---[7:2].RSV;                  [1,0].CAPM-00.T5 pin edge;
//                                                         01.inner RC
//                                                         10.RX1
//                                                         11.RX2
//    T5CON2[7:0]---[7:3].RSV;      [2].T5_MODE-0.UP TO T5M;   [1].RSV;  [0].T5CAPCR
//                                              1.rise or fall edge
//初始化定时器4
void triac_init(void)
{
    TH4 = 0x80;//0xFD;
    TL4 = 0x00;//0x76;
    
    T4CON = 0x0;//NO prescal
    
    ET4 = 1;//IE1 |= 0x02;
    EA = 1;                                 
    
}
//unsigned char up = 1;

/***************************************************************************************
  * @说明      T1中断服务函数
  *    @参数      无
  * @返回值 无
  * @注          无
  *     0.5MS
***************************************************************************************/
void TIMER1_Rpt(void) interrupt TIMER1_VECTOR
{
    //EA = 1;
    count1++;
    /*
    if (up)
    {
        bright1_curr++;
        if (bright1_curr >= 1000)
        {
            up = 0;
        }
    }else
    {
        if (bright1_curr > 120)
        {
            bright1_curr--;
        }
        else
            up = 1;
    }
    */
    //if ((f_adj_bright1) || (f_pwr1) )
    //{
        if(count1 >= (CTRL_NUM  -  (bright1_curr/50)))
        {
            TRIAC1 = 1;//triac_on;
            if (count1 >= 16)//CTRL_NUM)//(control_value + 30))
            {
                TRIAC1 = 0;//triac_off;
                TCON &= ~0x40;//停止T1
                count1 = 0;
            }
        }
    //}
}
// 0.5ms
//void TIMER3_Rpt(void) interrupt T3_VECTOR
void TIMER4_Rpt(void) interrupt T4_VECTOR
{
    //EA = 1;
    //T4CON &= ~0x80;//clear int flag
    T4CON &=~ 0x80;        
    count2++;
    //TRIAC2 = ~TRIAC2;
    //if ((f_adj_bright2) || (f_pwr2))
    //{
        if(count2 >= (CTRL_NUM  -  (bright2_curr/50)))
        {
            TRIAC2 = 1;//triac_on;
            if (count2 >= 16)//
            {
                TRIAC2 = 0;//triac_off;
                T4CON &= ~0x02;//TR3 = 0;//TCON &= ~0x40;//停止T4
                count2 = 0;
            }
        }
    //}
}
//INT4 initial
void Int4_init(void)
{
    P0M2 = P0M2 & 0xF0 | 0x06;//P04 pullup with SMT input
    PITS1 |= 0x03;// INT4 双沿中断
    PINTE0 |= 0x10;//EINT4 = 1;//PINTE
    EX2_7 = 1;// IE1 [7:0] : [7-EX8_15]; [6-EX2_7]; [5-EADC]; [4-ET5]; [3-EIIC]; 
}

// INT4 interrupt
void INT2_7_Rpt() interrupt INT2_7_VECTOR
{
    if (PINTF0 & 0x10)
    {
        PINTF0 &= ~0x10;
        
        count1 = 0;
        count2 = 0;
        //if ((f_pwr1) || (f_adj_bright1))
        //{
            TCON |= 0x40;//使能T1
       /* }
        else
        {
            TCON &= ~0x40;//停止T1
        }*/
        /*if ((f_pwr2) || (f_adj_bright2))
        {*/
            T4CON |= 0x02;//TR3 = 1;//使能T3
        /*}
        else
        {
            T4CON &= ~0x02;//TR3 = 0;//停止T3
        }*/
    }
}


  • 写回答

2条回答 默认 最新

  • 专家-皆知 2024-03-27 11:54
    关注

    引自免费微信小程序:皆我百晓生

    从您提供的代码中,我看到您已经初始化了定时器1和定时器4,并在定时器1的IRQ处理函数中处理了调光功能。同时,您已经定义了相关的变量和控制寄存器。

    根据您的描述,当同时开启定时器1和定时器4时,2路调光可以正常工作。但是,当只开启定时器1时,1路调光却不能正常工作。您提到,当定时器1的计数值大于等于某个值时,TRIAC1会被设置为1(开),此时1路调光会工作。而当定时器1的计数值小于某个值时,1路调光不会工作。

    我注意到,在您的代码中,当定时器1的计数值大于等于16时,TRIAC1会被设置为1(开),此时1路调光会工作。但是,当定时器1的计数值小于16时,1路调光不会工作。这可能是因为在定时器1的计数值大于等于16时,定时器1已经过了1个周期,因此TRIAC1会被设置为1(开)。而在定时器1的计数值小于16时,定时器1还没有过1个周期,因此TRIAC1不会被设置为1(开)。

    为了解决这个问题,您可以尝试修改定时器1的计数值的比较条件。例如,您可以将定时器1的计数值大于等于16的条件修改为定时器1的计数值大于等于某个值(比如32)。这样,当定时器1的计数值大于等于32时,TRIAC1会被设置为1(开),此时1路调光会工作。而当定时器1的计数值小于32时,1路调光不会工作。

    希望我的建议对您有所帮助。如果您还有其他问题,请随时提问。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 3月27日

悬赏问题

  • ¥15 非科班怎么跑代码?如何导数据和调参
  • ¥15 打开powerpont询问是否安装officeplus不小心点了不安装以后再也不提示是否安装了
  • ¥15 Altair EDEM中生成一个颗粒,并且各个方向没有初始速度
  • ¥15 系统2008r2 装机配置推荐一下
  • ¥500 服务器搭建cisco AnyConnect vpn
  • ¥15 用大厂网站防红自己网站
  • ¥15 悬赏Python-playwright部署在centos7上
  • ¥15 psoc creator软件有没有人能远程安装啊
  • ¥15 快速扫描算法求解Eikonal方程咨询
  • ¥20 我的是道格手机,重置后屏幕右上角出现红色字的未写入tee key 和未写入google key请问怎么去掉啊