找回密码
 立即注册

QQ登录

只需一步,快速开始

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

FMD60F010单片机URT外部中断问题?

[复制链接]
跳转到指定楼层
楼主
ID:468169 发表于 2021-10-18 22:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
300黑币

求教大师,我现在是用外部中断去控制灯的三段占空比,现在发现在if(scale==40)     { scale=20;}是它会延时3秒才能跳到scale=20这里,是什么原因,还有一个问题就是我要改小它的电流功耗,需要设置哪里,我试过改变晶振频率它电流没有减小。
单片机源程序如下:
  1. //*********************************************************
  2. #include "SYSCFG.h"

  3. //**********************************************************
  4. //***********************宏定义*****************************
  5. #define  unchar     unsigned char
  6. #define  unint      unsigned int
  7. #define  unlong     unsigned long

  8. #define  PortOut        RA4


  9.   unchar scale=40;
  10.   unchar n;
  11. /*-------------------------------------------------
  12. *  函数名:interrupt ISR1
  13. *        功能:  中断处理函数
  14. *  输入:  无
  15. *  输出:  无
  16. --------------------------------------------------*/
  17. void interrupt ISR(void)//PIC_HI-TECH使用
  18. {
  19.   //PA2外部中断处理**********************
  20.         if(INTE && INTF)      
  21.         {


  22.                 INTF = 0;                  //清PA2 INT 标志位
  23.                
  24.         }

  25.   //定时器2的中断处理**********************

  26.         if(TMR2IE && TMR2IF)                        //200us中断一次 = 2.5KHz
  27.         {
  28.                    TMR2IF = 0;
  29.             n++;
  30.                 if(n<scale)                 //n<设置比例时,打开灯
  31.         {         
  32.                         PortOut=1;
  33.                     
  34.         }
  35.       

  36.         else if(n>=scale)//n大于等于设置比例时 关闭灯
  37.         {         
  38.                 PortOut=0;  

  39.         }


  40.         if(n==40)                 
  41.         {
  42.                 n=0;                 //n=0
  43.         }


  44.         }
  45. }
  46. // --------------------------------------------------*/

  47. /*-------------------------------------------------
  48. *  函数名:POWER_INITIAL
  49. *        功能:  上电系统初始化
  50. *  输入:  无
  51. *  输出:  无
  52. --------------------------------------------------*/      
  53. void POWER_INITIAL (void)
  54. {
  55.          
  56.         OSCCON = 0B01100001;        //WDT 32KHZ IRCF=111=16MHZ/4=4MHZ,0.25US/T
  57.                                                          //Bit0=1,系统时钟为内部振荡器(60F01x保留位)
  58.                                                          //Bit0=0,时钟源由FOSC<2:0>决定即编译选项时选择
  59.         INTCON = 0;                          //暂禁止所有中断
  60.         PORTA = 0B00000000;               
  61.         TRISA = 0B00000100;                //PA输入输出 0-输出 1-输入
  62.                                                         //PA1->输出
  63.         WPUA = 0B00000100;             //PA端口上拉控制 1-开上拉 0-关上拉

  64.         OPTION = 0B00001000;        //Bit3=1 WDT MODE,PS=000=1:1 WDT RATE
  65.                                                         //Bit3 预分频器分配位 0-Timer0 1-WDT
  66.                                                         //Bit7(PAPU)=0 ENABLED PULL UP PA
  67.         MSCKCON = 0B00000000;   //Bit6->0,禁止PA4, PC5稳压输出(60F01x保留位)
  68.                                                           //Bit5->0,TIMER2时钟为Fosc(60F01x保留位)
  69.                                                           //Bit4->0,禁止LVR(60F01x O版之前)
  70.                             //Bit4->0, LVREN使能时,开启LVR(60F01x O版及O版后)  
  71.                                 //Bit4->1, LVREN使能时,工作时开启LVR, 睡眠时自动关闭LVR(60F01x O版及O版之后)      
  72. }

  73. /*-------------------------------------------------
  74. *  函数名: INT_INITIAL
  75. *        功能:  中断初始化函数
  76. *  输入:  无
  77. *  输出:  无
  78. --------------------------------------------------*/
  79. void INT_INITIAL(void)
  80. {
  81.         TRISA2 =1;                                                 //SET PA2 INPUT
  82.         INTEDG = 0;                                         //OPTION,INTEDG=0;PA2 INT 为下降沿触发
  83.         INTF =0;                                                   //清PA2 INT中断标志位
  84.         INTE =1;                                                   //使能PA2 INT中断?
  85. }

  86. /*-------------------------------------------------
  87. * 函数名称:  TIMER2_INITIAL
  88. * 功能:     初始化设置定时器1
  89. * 相关寄存器:T2CON TMR2 PR2 TMR2IE TMR2IF PEIE GIE  
  90. -------------------------------------------------*/
  91. void TIMER2_INITIAL (void)
  92. {
  93.         T2CON = 0B00000001;         //Bit[1,0]=01,T2时钟分频 1:4
  94.                                                         //Bit[6-3]=0000,T2输出时钟分频1:1
  95.         TMR2 = 0;                                  //TMR2赋初值
  96.         PR2 = 10;                                 //设置TMR2输出比较值定时200us=(1/16000000)*4*4*200(PR2)
  97.                                                         //16M-4T-4分频
  98.         TMR2IF = 0;                                //清TIMER2中断标志
  99.         TMR2IE = 1;                                //使能TIMER2的中断
  100.         TMR2ON = 1;                                //使能TIMER2启动
  101.         PEIE=1;                                    //使能外设中断
  102.         GIE = 1;                                   //使能全局中断

  103. }
  104. /*-------------------------------------------------
  105. *        函数名称:DelayUs
  106. *        功能:   短延时函数 --16M-2T--大概快1%左右.
  107. *        输入参数:Time 延时时间长度 延时时长Time Us
  108. *        返回参数:无
  109. -------------------------------------------------*/
  110. void DelayUs(unsigned char Time)
  111. {
  112.         unsigned char a;
  113.         for(a=0;a<Time;a++)
  114.         {
  115.                 CLRWDT();
  116.         }
  117. }                  
  118. /*----------------------------------------------------
  119. *        函数名称:DelayMs
  120. *        功能:   短延时函数
  121. *        输入参数:Time延时时间长度 延时时长Time ms
  122. *        返回参数:无
  123. ----------------------------------------------------*/
  124. void DelayMs(unsigned char Time)
  125. {
  126.         unsigned char a,b;
  127.         for(a=0;a<Time;a++)
  128.         {
  129.                 for(b=0;b<5;b++)
  130.                 {
  131.                          DelayUs(98);         //快1%
  132.                 }
  133.         }
  134. }
  135. /*----------------------------------------------------
  136. *        函数名称:DelayS
  137. *        功能:   短延时函数
  138. *        输入参数:Time延时时间长度 延时时长Time S
  139. *        返回参数:无
  140. ----------------------------------------------------*/
  141. void DelayS(unsigned char Time)
  142. {
  143.         unsigned char a,b;
  144.         for(a=0;a<Time;a++)
  145.         {
  146.                 for(b=0;b<10;b++)
  147.                 {
  148.                          DelayMs(100);        
  149.                 }
  150.         }
  151. }
  152. /*-------------------------------------------------
  153. *  函数名: main
  154. *        功能:  主函数
  155. *  输入:  无
  156. *  输出:  无
  157. --------------------------------------------------*/
  158. void main()
  159. {

  160.         POWER_INITIAL();                //系统初始化


  161.         TIMER2_INITIAL();                  //初始化T2
  162.       
  163.         while(1)
  164.         {


  165.                  
  166.            if(RA2==0)
  167.          {



  168.           DelayMs(2);

  169.              if(scale==40)                         //如果占空比为            
  170.                               
  171.                                     {
  172.                               
  173.                                          scale=20;                                        ////占空比赋值为,
  174.                                  
  175.                              
  176.                                         }

  177.                                  else if(scale==20)

  178.                                         {

  179.                                                    scale=5;  
  180.                                                           ;
  181.                                         }

  182.                                 else if(scale==5)
  183.                                          {
  184.                                           
  185.                                            scale=40;        
  186.                                                 
  187.                                          }

  188.             INT_INITIAL();
  189.             GIE =1;                                            //使能全局中?
  190.          }
  191.      while(!RA2);







  192.         }


  193. }
复制代码




分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:448556 发表于 2021-10-19 09:05 | 只看该作者
按键处理你确定这样写?
回复

使用道具 举报

板凳
ID:468169 发表于 2021-10-19 12:01 来自触屏版 | 只看该作者
liyezhao2019 发表于 2021-10-19 09:05
按键处理你确定这样写?

这不是按键,这是中断
回复

使用道具 举报

地板
ID:468169 发表于 2021-10-19 12:02 来自触屏版 | 只看该作者
liyezhao2019 发表于 2021-10-19 09:05
按键处理你确定这样写?

其它的单片机维晟和STC已经实现这个功能,只是现在要跟换单片机,所以才改的……。
回复

使用道具 举报

5#
ID:548551 发表于 2021-10-20 11:11 | 只看该作者
在工作了?
回复

使用道具 举报

6#
ID:468169 发表于 2021-10-24 02:32 来自触屏版 | 只看该作者
xqleft 发表于 2021-10-20 11:11
在工作了?

工作是工作了,现在优化了下,撤换正常,就是很耗电,现在还搞不到省电模式
回复

使用道具 举报

7#
ID:59341 发表于 2026-2-28 13:37 | 只看该作者
请问解决了吗?
回复

使用道具 举报

8#
ID:859047 发表于 2026-3-18 16:18 | 只看该作者
想要省电,就用PWM CPU只在外部中断进来时唤醒,然后更新占空比,再进入休眠
回复

使用道具 举报

9#
ID:859047 发表于 2026-3-18 16:35 | 只看该作者
/*****
Project:  zwt.prj
Device:   FT60F123-RB SOP16
Memory:   PROM=2Kx14, SRAM=128Byte, EEPROM=256Byte   
Description:
来一次外部中断,改变一次占空比,改变灯亮度
RELEASE HISTORY
VERSION DATE     DESCRIPTION
1.0  20260318   
*****/

#include "SYSCFG.h"  //头文件

//PA2 外部输入口

#define  led PA0   //LED接口,低电平点亮

volatile uint PA2in_cnt=0;  //外部中断计数
uint duty = 0;  //占空比值

//定时器0相关变量
uint t0_cnt=0; //

//上电系统初始化
void power_initial (void)
{
        OSCCON = 0B01110001;       
        INTCON = 0B00000000;         
        TRISA = 0B00000100;                //PA2 IN
        TRISC = 0B00000000;                //
           
    WPUA = 0B00000100;            //上拉
    WPUC = 0B00000000;                //
   
    WPDA = 0B00000000;        //下拉
    WPDC = 0B00000000;        //
   
           PORTA = 0B00000000;                //初值               
        PORTC = 0B00000000;         //初值
                                                                
        OPTION = 0B00000000;       
                           
    PSRCA = 0B11111111;                //源电流设置最大
    PSRCC = 0B11111111;         //
    PSINKA = 0B11111111;    //灌电流设置最大
    PSINKC = 0B11111111;        //
                     
    MSCON = 0B00110000;                          

}

//设置TMR0定时时长=(1/系统时钟频率)*指令周期*预分频值*256
//                                   =(1/16000000)*2*32*256=1.024ms(0.000032*32=0.001024)
void timer0_initial (void)  
{
        OPTION = 0B00000100;
        T0IF = 0;        //清空T0软件中断
    T0IE = 1;   //开定时器0中断
}

//中断处理
void interrupt ISR(void)
{  
        //定时器0的中断处理
        if(T0IE && T0IF)    //1.024ms翻转一次
        {
                T0IF = 0;    //清标志
        
        t0_cnt++;
        if(t0_cnt>=40)  //
        {
                        t0_cnt=0;
        }
        }
   
    //外部中断处理
    if(INTE && INTF)  //PA2中断处理
    {
                INTF = 0;  //清PA2 INF 标志位
                INTE = 0;  //暂先禁止PA2中断
        delay_us(10);   //短暂延时
        if(PA2==0)  //检查下降沿低电平
        {
                        PA2in_cnt++;  //累加次数
                        if(PA2in_cnt>=4)  //
                        {
                                PA2in_cnt=0;  //0123循环
                        }
        }
        INTE = 1;   //开中断
    }  
}

//
void int_initial(void)
{
        TRISA2 = 1;  //设定PA2 输入
    IOCA2 = 0; //禁止PA2电平变化中断
    INTEDG = 0 ;  //PA2 INT触发 0->下降沿 1->上升沿
    INTF = 0;  //清中断标志位
    INTE = 1;  //使能PA2 INT中断
}

void get_duty (void)
{
        switch(PA2in_cnt)
        {
                case 0:
                duty=0;
                break;
               
                case 1:
                duty=5;
                break;
               
                case 2:
                duty=20;
                break;
               
                case 3:
                duty=40;
                break;
               
                default:
                duty=0;
                break;
               
        }
}

void led_display (void)
{
       
        if(t0_cnt<=duty)        //小于占空比的时间是高电平,
        {
                led=1;                  //输出高电平
        }
        else
        {
                led=0;                  //输出低电平
        }
}

//主函数
void main()
{
        power_initial();  //上电初始化
   
    timer0_initial();  //定时器0初始化
   
    int_initial(); //外部中断
   
    GIE = 1;  //总中断
   
        while(1)
        {       
                get_duty();  //计算当前占空比
                led_display();  //点亮灯
        }
}
//end
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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