简单记录一下如何使用ATMEGA64-UART1串口中断方式。
一、main.c
#include <iom64v.h>
#include <macros.h>
#include <string.h>
#include "uart.h"
void main(void)
{
CLI(); //总中断禁止
uart1_init(); //uart1初始化
SEI(); //总中断允许
puts1("Atmega64 staring.......");
while(1){
}
}
一定要记得开总中断允许:SEI();
CLI(); //总中断禁止
uart1_init(); //uart1初始化
SEI(); //总中断允许
二、uart.h
#define true 1
#define false 0
#define cMaxRxLength 16
#define cMaxTxLength 100
struct SCI_Buffer
{
unsigned char bRxLength; //已经接收的字符长度
unsigned char bTxLength; //已经发送的字符长度
unsigned char bTxBufferLength; //缓冲区中的字符长度
unsigned char bRxBuffer[cMaxRxLength];
unsigned char bTxBuffer[cMaxTxLength];
};
extern struct SCI_Buffer stSciBuffer;
void uart1_init(void);
char putchar1(char c);
unsigned char getchar1(void);
void puts1(char *s);
三、uart.c
/* Code adapted from Atmel AVR Application Note AVR306
* Interrupt mode driver for UART.
*/
#include <iom64v.h>
#include <macros.h>
#include "uart.h"
/***********************************宏定义**********************************/
#define fosc 16000000 //晶振16MHZ,晶振是多少就设多少
#define baud 115200 //波特率 115200
struct SCI_Buffer stSciBuffer;
//********************************************************************
// Function : SciBuffer_Init
// Input : ptr-pointer to SCI Buffer
// Output : none
// Description : Initialization of SCI Buffer
//********************************************************************
void SciBuffer_Init(struct SCI_Buffer *ptr)
{
ptr->bRxLength = 0;
ptr->bTxLength = 0;
ptr->bTxBufferLength = 0;
//memset(ptr->bRxBuffer,0,16);
sprintf(ptr->bRxBuffer,"万里悲秋常作客,");
}
//********************************************************************
// Function : sbGetRxBufferEmptyStatus
// Input : ptr-pointer to SCI Buffer
// Output : Status of SCI TX Buffer
// Description : Check whether the SCI TX Buffer is empty or not
//********************************************************************
unsigned char sbGetRxBufferEmptyStatus(struct SCI_Buffer *ptr)
{
if(ptr->bRxLength == 0)
{
return(true);
}
return(false);
}
//********************************************************************
// Function : SciBuffer_Rx_Reset
// Input : ptr-pointer to SCI Buffer
// Output : none
// Description : Reset RX Buffer Length to zero
//********************************************************************
void SciBuffer_Rx_Reset(struct SCI_Buffer *ptr)
{
ptr->bRxLength = 0;
}
//********************************************************************
// Function : SciBuffer_Rx_In
// Input : ptr-pointer to SCI Buffer
// Output : none
// Description : Add data into the SCI RX Buffer
//********************************************************************
void SciBuffer_Rx_In(struct SCI_Buffer *ptr,unsigned char bData)
{
if(ptr->bRxLength < cMaxRxLength)
{
ptr->bRxBuffer[ptr->bRxLength] = bData;
ptr->bRxLength++;
}
else
{
ptr->bRxBuffer[0] = bData;
ptr->bRxLength = 1;
}
}
//38400
/****************************************************************************
函数功能:uart1初始化程序
入口参数:
出口参数:
注:只开了接收中断
****************************************************************************/
void uart1_init(void)
{
UCSR1A = 0x00;
UCSR1B = 0x00;//设置波特率前,要关闭USART0的所有使用,包括使能和中断.
UCSR1C = (1<<UCSZ11)|(1<<UCSZ10); //异步 8-bit ,停止位1位
UBRR1L=(fosc/16/(baud+1))%256;
UBRR1H=(fosc/16/(baud+1))/256;
//RXCIE1-RX完成中断,
UCSR1B =(1<<RXCIE1)|(1<<RXEN1)|(1<<TXEN1); //位4—RXEN接收使能,置为后将启动USART接收器 位3—TXEN:发送使能,置为后将启动USART发送器
UCSR1B |= 0x80;//上一条语句已经包括了
SciBuffer_Init(&stSciBuffer);
}
//********************************************************************
// Function : UART_RX_DATA
// Input : none
// Output : data received
// Description : Get Received Data from Register
//********************************************************************
unsigned char UART_RX_DATA(void)
{
//while(!(UCSR1A& (1<<RXC1)));
return UDR1;
}
//********************************************************************
// Function : sUART_RX_ISR
// Input : none
// Output : none
// Description : UART RX Interrupt Service Routine
//********************************************************************
//iv_USART1_RX 是UART1的接收中断号 ,ATMEGA64 的UART1接收中断号应该是31
#pragma interrupt_handler sUART_RX_ISR:iv_USART1_RX //31
void sUART_RX_ISR(void)
{
unsigned char data;
//step1:read receive register to clear interrupt flag
data = UART_RX_DATA();
//step2:report event or store received char to buffer
if((data == 0x0A) || (data == 0x0D))
{
if(sbGetRxBufferEmptyStatus(&stSciBuffer) == false)
{
SciBuffer_Rx_Reset(&stSciBuffer);
//sSet_SCI_Event(1);
}
}
else
{
SciBuffer_Rx_In(&stSciBuffer,data);
putchar1(data);
}
}
/****************************************************************************
函数功能:uart1发送单字节数据
入口参数:c
出口参数:
****************************************************************************/
char putchar1(char c)
{
while (!(UCSR1A&(1<<UDRE1)));
UDR1=c;
return c;
}
/****************************************************************************
函数功能:uart1接收单字节数据
入口参数:
出口参数:
****************************************************************************/
unsigned char getchar1(void)
{
while(!(UCSR1A& (1<<RXC1)));
return UDR1;
}
/****************************************************************************
函数功能:uart1发送字符串数据
入口参数:*s
出口参数:
****************************************************************************/
void puts1(char *s)
{
while (*s)
{
putchar1(*s);
s++;
}
putchar1(0x0a);
putchar1(0x0d);
}