英文:
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 <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);
}
**
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论