C语言 使能ATTINY1626 UART RX中断不触发ISR,如何解决?

6l7fqoea  于 2023-06-05  发布在  其他
关注(0)|答案(1)|浏览(145)

ATTINY1626出现接收中断问题。在池模式下,我可以接收UART数据。但通过使能UART RX中断不会发生这种情况。我不知道我在哪里错过了一些与中断相关的配置。
请告诉我是否有人遇到并解决了这类问题。
下面是代码。

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/fuse.h>

#define F_CPU 16000000UL / 2
#define FUSE_OSCCFG_16MHZ  (0x7D)

//#define cli()             __asm__ __volatile__ ("cli" ::)         ///< Disables global interrupts
//#define sei()             __asm__ __volatile__ ("sei" ::)         ///< Enables global interrupts

volatile unsigned char gvc_Rxbyte = 0;

FUSES = {
    .WDTCFG     = FUSE_WDTCFG_DEFAULT,
    .BODCFG     = FUSE_BODCFG_DEFAULT,
    .OSCCFG     = FUSE_OSCCFG_16MHZ,    // Run at 16 MHz and Calibration registers of the 20 MHz oscillator are accessible
    .SYSCFG0    = FUSE_SYSCFG0_DEFAULT, // Reset Pin Configured as UPDI
    .SYSCFG1    = FUSE_SYSCFG1_DEFAULT, // start-up time between power-on and code execution
    .APPEND     = 0x14, // FUSE_APPEND_DEFAULT - 4K APP CODE
    .BOOTEND    = 0x04, // FUSE_BOOTEND_DEFAULT - 1K BOOT CODE
};

void send_string(unsigned char uartNo, char *s);

void usart0_init(unsigned long int baudRate)
{
    unsigned int baud = 0;
    cli();
    SREG &=~(1 << 7);
//  PORTMUX.EVSYSROUTEA |= (1 << 1);
    //uint8_t sregBackup = CPU_SREG;
//  cli();
    baud = (F_CPU / baudRate) * 4;  // BAUD = (64 * fCLK_PER) / (S * fBAUD)
    // S is the number of samples per bit
    // Asynchronous Normal mode: S = 16
    // Asynchronous Double-Speed mode: S = 8
    // Synchronous mode: S = 2
    
    USART0.BAUDL = (unsigned char) baud;            // Set the baud rate (USARTn.BAUD).
    USART0.BAUDH = (unsigned char) (baud >> 8);
    
    USART0.CTRLC = 0x03;            // Set the frame format and mode of operation (USARTn.CTRLC).
    //set character size to 8. parity = none. stop bits = 1. async usart.
    PORTB.DIR |= PIN2_bm;           // Configure the TXD pin as an output.
    PORTB.DIR &= ~PIN3_bm;          // Configure the RXD pin as an input.
    
    USART0.CTRLA |=(1<<USART_RXCIE_bp) | (1<<USART_ABEIE_bp);//0x84;
    USART0.CTRLB |=(1<<USART_RXEN_bp)|(1<<USART_TXEN_bp) ;          // Enable the transmitter and the receiver (USARTn.CTRLB).
    
     sei();
}

void usart0WriteByte(unsigned char dataByte)
{
    while(!(USART0.STATUS & USART_DREIF_bm)); // wait till tx register is free
    USART0.TXDATAL = dataByte;              // load data in the tx register
}

unsigned char usart0ReadByte(void)
{
    unsigned char rxByte = 0;
    while(!(USART0.STATUS & USART_RXCIF_bm)); // wait for rx register data
    rxByte = USART0.RXDATAL;                // read data from the rx register
    
    return rxByte;
}

void send_string(unsigned char uartNo, char *s)
{
    while(*s)
    {
        usart0WriteByte(*s);        
        s++;
    }
}

int main(void)
{
    //unsigned char i=0;
    cli();
    
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLA, CLKCTRL_CLKSEL_OSC20M_gc | (0<<CLKCTRL_CLKOUT_bp ));    ///< To out the clock on clock out pin
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm );                  ///< To set the clock pre-scaler as DIVIDED BY 2
    
    usart0_init(115200);                ///< Initializing UART0 as debug interface.
    //_PROTECTED_WRITE(CPU_SREG, (1 << CPU_I_bp));  
    //send_string(0, "System Initialized\r\n");
    _delay_ms(1000);
    gvc_Rxbyte = 'B';   
    
    while (1)
    {
         //sei();
        ////gvc_Rxbyte = usart0ReadByte();
        //usart0WriteByte(gvc_Rxbyte);
        //_delay_ms(1000);
    }
}

ISR (USART0_RXC_vect)
{
    if(USART0.STATUS & USART_RXCIF_bm)
    {
        gvc_Rxbyte = USART0.RXDATAL;
    }
    gvc_Rxbyte = USART0.RXDATAL;                // read data from the rx register
    usart0WriteByte(gvc_Rxbyte);    
}
**

我尝试启用UART RXIE配置。启用全局中断。甚至ISR也不调用接收缓冲器上可用的接收数据。
硬件路径似乎正常,因为接收功能在POOLing模式下工作。

nxagd54h

nxagd54h1#

您似乎在ISR中读取了USART0.RXDATAL字节两次。如果gvc_Rxbyte为0,可能是因为第二次阅读USART0.RXDATAL时覆盖了它。

相关问题