首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Attiny816外部中断问题

Attiny816外部中断问题
EN

Stack Overflow用户
提问于 2022-11-02 10:52:58
回答 1查看 18关注 0票数 0

最近使用attiny816开发了测速仪。基本上使用5个输入来感知来自霍尔传感器的脉冲(使用中断感知上升的边缘)。在测试中,当我使用简单的晶体管键来模拟霍尔传感器(给出不同频率的矩形波)时,我注意到,经过一段时间后,微控制器慢下来了(是的,像慢动作一样工作)。有时只需要几分钟,有时需要几个小时。

为了找出问题,我创建了一个简单的程序,在触发中断时切换并改变速度值。值得一提的是,在使用内部32k时钟的示例代码上,当更改为20 than时,它正确工作了几个小时(比32k长得多)。在Attiny816和Attiny826上尝试了程序,两者的问题相同。有什么能导致问题的原因吗?下面是测试代码。在每个输入端,不同的中断时间(不同的信号频率) PB5 -每120 is PB4中断一次-每60 is PB3中断一次-每40 is PB2中断一次30 is PB1中断每24 is中断一次。

代码语言:javascript
复制
/*
 * Attiny816 VQFN TeST.c
 *
 * Created: 01/11/2022 10:11:41
 * Author : 
 */ 

#define F_CPU 32768UL


#include <avr/io.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>


#define USART0_BAUD_RATE(BAUD_RATE) ((float)(F_CPU * 64 / (16 * (float)BAUD_RATE)) + 0.5)


void USART0_init(void);
void USART0_sendChar(char c);
void USART0_sendString(char *str);
int USART0_printChar(char c, FILE *stream);
void reset_screen(void);
FILE USART_stream = FDEV_SETUP_STREAM(USART0_printChar, NULL, _FDEV_SETUP_WRIT);


uint16_t speed_read(uint8_t wejscie_TACHO);


int main(void)
{
    
    CPU_CCP = CCP_IOREG_gc;                         
    CLKCTRL_MCLKCTRLA = CLKCTRL_CLKSEL_OSCULP32K_gc;    /*32.768 kHz */
    CPU_CCP = CCP_IOREG_gc;
    CLKCTRL_MCLKCTRLB = 0 << CLKCTRL_PEN_bp;        /* prescaler DISABLED */
    
    /* --- ALARM LED'S --- */
    PORTC.DIRSET = PIN3_bm;     // F1 ALARM LED
    PORTC.DIRSET = PIN2_bm;     // F2 ALARM LED
    PORTC.DIRSET = PIN1_bm;     // F3 ALARM LED
    PORTC.DIRSET = PIN0_bm;     // F4 ALARM LED
    PORTB.DIRSET = PIN0_bm;     // F5 ALARM LED
    
    
    /* --- USART --- */
    USART0_init();
    printf( "%cc", 27 );
    
    
    
    /* --- TACHO --- */
    PORTB.PIN5CTRL = PORT_ISC_INTDISABLE_gc;    //TACHO_1_DIS
    PORTB.PIN4CTRL = PORT_ISC_INTDISABLE_gc;    //TACHO_2_DIS
    PORTB.PIN3CTRL = PORT_ISC_INTDISABLE_gc;    //TACHO_3_DIS
    PORTB.PIN2CTRL = PORT_ISC_INTDISABLE_gc;    //TACHO_4_DIS
    PORTB.PIN1CTRL = PORT_ISC_INTDISABLE_gc;    //TACHO_5_DIS
    sei();
    
    
    
    
    /* Replace with your application code */
    while (1) 
    {
        
        printf("\n\r Speed 1 - %u[rpm]", speed_read(1));
        printf("\n\r Speed 2 - %u[rpm]", speed_read(2));
        printf("\n\r Speed 3 - %u[rpm]", speed_read(3));
        printf("\n\r Speed 4 - %u[rpm]", speed_read(4));
        printf("\n\r Speed 5 - %u[rpm]", speed_read(5));
        USART0_sendString("\n\r");
    }
}

ISR( PORTB_PORT_vect )
{
    switch ( PORTB_INTFLAGS )
    {
        case (32):  // TACHO_1 - PB5    (2^(5-1) = 32)
        ////tacho_now[1] = TCA0.SINGLE.CNT;
            PORTB.INTFLAGS |= PORT_INT5_bm;     /* clear interrupt flag */
            break;
        case (16):  // TACHO_2 - PB4
        ////tacho_now[2] = TCA0.SINGLE.CNT;     // tacho_cnt;
            PORTB.INTFLAGS |= PORT_INT4_bm;     /* clear interrupt flag */
            break;
        case (8):   // TACHO_3 - PB3
        ////tacho_now[3] = TCA0.SINGLE.CNT;
            PORTB.INTFLAGS |= PORT_INT3_bm;     /* clear interrupt flag */
            break;
        case (4):   // TACHO_4 - PB2
        //tacho_now[4] = TCA0.SINGLE.CNT;
            PORTB.INTFLAGS |= PORT_INT2_bm;     /* clear interrupt flag */
            break;
        case (2):   // TACHO_5 - PB1
        ////tacho_now[5] = TCA0.SINGLE.CNT;
            PORTB.INTFLAGS |= PORT_INT1_bm;     /* clear interrupt flag */
            break;
        default:
            break;
    }
    
}

void USART0_init(void)
{
    PORTMUX.CTRLB = PORTMUX_USART0_ALTERNATE_gc;
    
    
    PORTA.DIRSET = PIN1_bm;  // PA1 - TXD jako wyjscie
    
    
    USART0.BAUD = (uint16_t)USART0_BAUD_RATE( 1200 );   // set the Baud Rate
    USART0.CTRLB |= USART_TXEN_bm;                      // enable the Transmitter
    
    // Set frame format
    USART0.CTRLC = USART_CMODE_ASYNCHRONOUS_gc          // Asynchronous Mode
    | USART_CHSIZE_8BIT_gc                  // Character size: 8 bit
    | USART_PMODE_DISABLED_gc               // No Parity
    | USART_SBMODE_1BIT_gc;                 // 1 stop bit
    
    stdout = &USART_stream;
    
    _delay_ms(250);
    
}

void USART0_sendChar(char c)
{
    while ( !(USART0.STATUS & USART_DREIF_bm) )
    {
        ; // do nothing
    }
    USART0.TXDATAL = c;
}

void USART0_sendString(char *str)
{
    for(size_t i = 0; i < strlen(str); i++)
    {
        USART0_sendChar(str[i]);
    }
}

int USART0_printChar(char c, FILE *stream)
{
    USART0_sendChar(c);
    return 0;
}



uint16_t speed_read(uint8_t wejscie_TACHO)
{
    uint32_t    speed = 0;
    
    /* --- disable all TACHO input --- */
    PORTB.PIN5CTRL = PORT_ISC_INTDISABLE_gc;    //TACHO_1_DIS
    PORTB.PIN4CTRL = PORT_ISC_INTDISABLE_gc;    //TACHO_2_DIS
    PORTB.PIN3CTRL = PORT_ISC_INTDISABLE_gc;    //TACHO_3_DIS
    PORTB.PIN2CTRL = PORT_ISC_INTDISABLE_gc;    //TACHO_4_DIS
    PORTB.PIN1CTRL = PORT_ISC_INTDISABLE_gc;    //TACHO_5_DIS
    //_delay_ms(100);
    
    /* --- enable [wejscie_TACHO] only --- */
    switch ( wejscie_TACHO )
    {
        case (1):
            speed = 500;
            PORTC.OUTTGL = PIN3_bm;// _delay_ms(200);
            PORTB.PIN5CTRL = PORT_ISC_RISING_gc;
            break;
        case (2):
            speed = 1000;
            PORTC.OUTTGL = PIN2_bm; //_delay_ms(200);
            PORTB.PIN4CTRL = PORT_ISC_RISING_gc;
            break;
        case (3):
            speed = 1500;
            PORTC.OUTTGL = PIN1_bm; //_delay_ms(200);
            PORTB.PIN3CTRL = PORT_ISC_RISING_gc;
            break;
        case (4):
            speed = 2000;
            PORTC.OUTTGL = PIN0_bm; //_delay_ms(200);
            PORTB.PIN2CTRL = PORT_ISC_RISING_gc;
            break;
        case (5):
            speed = 2500;
            PORTB.OUTTGL = PIN0_bm; //_delay_ms(200);
            PORTB.PIN1CTRL = PORT_ISC_RISING_gc;
            break;
        default:
            break;
    }
    _delay_ms(250);
    
    return speed;
}

我试过不同的芯片,测试过电源和输入信号波,看起来都应该是。它看起来就像在中断程序中迷路之后的微控制器。

EN

回答 1

Stack Overflow用户

发布于 2022-11-02 12:49:53

发现问题时,如果两个或多个引脚同时触发中断,则中断处理程序不考虑此问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74288032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档