/* Calculate buffer index */
tmphead = (USART3_tx_head + 1) & USART3_TX_BUFFER_MASK;
/* Wait for free space in buffer */
while (USART3_tx_elements == USART3_TX_BUFFER_SIZE);
/* Store data in buffer */
USART3_txbuf[tmphead] = data;
/* Store new index */
USART3_tx_head = tmphead;
ENTER_CRITICAL(W);
USART3_tx_elements++;
EXIT_CRITICAL(W);
/* Enable Tx interrupt */
USART3.CTRLA |= (1 << USART_DREIE_bp);
}
/*
* Please disable standard startup files in Toolchain->AVR/GNU Linker->General.
* In this example startup.c replaces the standard startup files.
*/
#include <avr/io.h>
/* Letting the compiler know there will be something called main */
extern int main(void);
/* Being nice to the compiler by predeclaring the ISRs */
void __vector_cvt_nmi(void) __attribute__((weak, alias("dummy_handler")));
void __vector_cvt_lvl1(void) __attribute__((weak, alias("dummy_handler")));
void __vector_cvt_lvl0(void) __attribute__((weak, alias("dummy_handler")));
/* Setting up the vector section
* The rjump instruction can handle 8k code space, so this is used for
* vector tables on devices with 8k flash or smaller. Other devices
* use the jmp instruction.
*/
__attribute__((section(".vectors"), naked)) void vectors(void)
{
#if (PROGMEM_SIZE <= 0x2000)
asm("rjmp __ctors_end");
asm("rjmp __vector_cvt_nmi");
asm("rjmp __vector_cvt_lvl1");
asm("rjmp __vector_cvt_lvl0");
#else
asm("jmp __ctors_end");
asm("jmp __vector_cvt_nmi");
asm("jmp __vector_cvt_lvl1");
asm("jmp __vector_cvt_lvl0");
#endif
}
/* Initialize the AVR core */
__attribute__((section(".init2"), naked)) void init2(void)
{
asm("clr r1"); /* GCC expects this CPU register to be zero */
SREG = 0; /* Make sure the status register has a known state */
SPL = INTERNAL_SRAM_END & 0xff; /* Point the stack pointer to the end of stack (low byte) */
SPH = (INTERNAL_SRAM_END >> 8); /* Point the stack pointer to the end of stack (high byte) */
}
/* Handling main */
__attribute__((section(".init9"), naked)) void init9(void)
{
main();
/* Jump to avr libc defined exit handler
* (Disables interrupts and runs an empty loop forever)
*/
asm("jmp _exit");
}
/* Dummy handler alias for unused ISRs */
void dummy_handler(void)
{
while (1)
;
}
4. 设置工程属性,使工程不添加默认的启动文件。
说明:为什么我们没有看到系统自动生成的启动文件?这是因为自动生成的启动文件在编译完成后被删除了,如果想要保留需要使用keep --RUNTIME编译选项。 获取相关链接选项
查看MPLAB X IDE安装目录下的XC8 for AVR编译的使用说明文档(MPLAB_XC8_C_Compiler_User_Guide_for_AVR.pdf),在此文档中搜索"startup"关键字找到相关的编译选项。找到了链接选项"-nostartfiles"