启用ATTINY1626 UART RX中断不触发ISR,如何解决?

huangapple go评论65阅读模式
英文:

Enabling ATTINY1626 UART RX interrupt doesn't trigger ISR, how to resolve?

问题

I have a receive interrupt issue with ATTINY1626. In pooling mode I can able to receive UART data. But it is not happening by enabling UART RX interrupt. I don't know where I missed some configuration related to interrupts.

Please suggest me if anybody faced and resolved this type of issue.

Below is the code.

#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)

// ... (The code continues)

I tried enabling the UART RXIE configurations. Enabled Global interrupts. Even the ISR also not calling upon the receive data available on receive buffers.

Hardware path seems ok as the receive functionality working with POOLing mode.

英文:

I have a receive interrupt issue with ATTINY1626. In pooling mode I can able to receive UART data. But it is not happening by enabling UART RX interrupt. I don't know where I missed some configuration related to interrupts.

Please suggest me if anybody faced and resolved this type of issue.

Below is the code.

#include &lt;avr/io.h&gt;
#include &lt;avr/interrupt.h&gt;
#include &lt;util/delay.h&gt;
#include &lt;avr/fuse.h&gt;

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

//#define cli()				__asm__ __volatile__ (&quot;cli&quot; ::)			///&lt; Disables global interrupts
//#define sei()				__asm__ __volatile__ (&quot;sei&quot; ::)			///&lt; 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 &amp;=~(1 &lt;&lt; 7);
//	PORTMUX.EVSYSROUTEA |= (1 &lt;&lt; 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 &gt;&gt; 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 &amp;= ~PIN3_bm;			// Configure the RXD pin as an input.
	
	USART0.CTRLA |=(1&lt;&lt;USART_RXCIE_bp) | (1&lt;&lt;USART_ABEIE_bp);//0x84;
	USART0.CTRLB |=(1&lt;&lt;USART_RXEN_bp)|(1&lt;&lt;USART_TXEN_bp) ;			// Enable the transmitter and the receiver (USARTn.CTRLB).
	
	 sei();
}

void usart0WriteByte(unsigned char dataByte)
{
	while(!(USART0.STATUS &amp; 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 &amp; 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&lt;&lt;CLKCTRL_CLKOUT_bp ));	///&lt; To out the clock on clock out pin
    _PROTECTED_WRITE(CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm );					///&lt; To set the clock pre-scaler as DIVIDED BY 2
    
	usart0_init(115200);				///&lt; Initializing UART0 as debug interface.
	//_PROTECTED_WRITE(CPU_SREG, (1 &lt;&lt; CPU_I_bp));	
	//send_string(0, &quot;System Initialized\r\n&quot;);
	_delay_ms(1000);
	gvc_Rxbyte = &#39;B&#39;;	
	
    while (1)
    {
		 //sei();
		////gvc_Rxbyte = usart0ReadByte();
		//usart0WriteByte(gvc_Rxbyte);
		//_delay_ms(1000);
    }
}

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

I tried enabling the UART RXIE configurations. Enabled Global interrupts. Even the ISR also not calling upon the receive data available on receive buffers.

Hardware path seems ok as the receive functionality working with POOLing mode.

答案1

得分: 2

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

英文:

It seems that you read the USART0.RXDATAL byte twice in your ISR. If your gvc_Rxbyte is 0, it might be because you overwrite it by reading USART0.RXDATAL the second time.

huangapple
  • 本文由 发表于 2023年5月29日 16:42:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76355848.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定