求助】用WinAVR编写AVR128串行接受中断程序
/******ATMEGA128单片机串口中断程序******/
#include "avr/io.h"
#include "avr/interrupt.h"
void UART_Init(void);
void UART_Send_Byte(unsigned char mydata);
void UART_Send_Str(char *s);
unsigned char rec=0;
#define fosc 16000000 //晶振16MHZ
#define baud 9600 //波特率
void main(void)
{
UART_Init();
UART_Send_Str("串口设置完毕\r\n");
while(1)
{
PORTA=0x10;
PORTB=0x10;
PORTC=0x10;
}
}
void UART_Init(void)
{
UCSR0B = 0x00;
UCSR0A = 0x00;
UCSR0C =(1<<UCSZ01)|(1<<UCSZ00);
UBRR0L=(fosc/16/(baud+1))%256;
UBRR0H=(fosc/16/(baud+1))/256;
UCSR0B =(1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);//RXCEN TXCEN
}
void UART_Send_Byte(unsigned char mydata)
{
while (!(UCSR0A&(1<<UDRE0)));
UDR0=mydata;
}
/*******发送字符串*******/
void UART_Send_Str(char *s)
{
while(*s)
{
UART_Send_Byte(*s);
s++;
}
}
/****************************
******串口0接收中断程序*******
*******************************/
ISR(USART0_RX_vect)
{
rec=UDR0;
UART_Send_Byte(rec);
}
#include <iom128v.h>
#include <macros.h>
#define TRUE 0xFF
#define FALSE 0x00
unsigned char Scounter = 0,Lcounter = 0,FMcounter = 0;
unsigned char ALARMFlg = FALSE;
//数码管字形编码定义
unsigned char SEGtable[]=
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x00
};
void delay(void) //延时函数
{
unsigned int i;
for(i=1;i<100;i++);
}
void delay_1ms(void)//1ms延时函数
{
unsigned int i;
for(i=1;i<(unsigned int)(8*143-2);i++) ;
}
void DelayMs(unsigned int time)//ms延时函数
{
unsigned int i=0;
while(i<time)
{
delay_1ms();
i++;
}
}
//串口发送函数
void putchar(unsigned char x)
{
while(!(UCSR0A&(1<<UDRE0)));
UDR0= x;
}
//端口初始化
void port_init(void)
{
PORTA = 0x00;
DDRA = 0x00;
PORTB = 0x00;
DDRB = 0x00;
PORTC = 0x00; //PC为输入端口
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x01; //PD0驱动FMQ
PORTE = 0x00;
DDRE = 0x00;
PORTF = 0x00;
DDRF = 0xFF; //PF为输出端口
PORTG = 0x00;
DDRG = 0x00;
}
//uart0初始化函数,9600bps
void uart0_init(void)
{
UCSR0B = 0x00;
UCSR0A = 0x00; //倍速
UCSR0C = 0x06;
UBRR0L = 0x33; //设置波特率9600bps
UBRR0H = 0x00;
UCSR0B = 0x98;
}
//串口接收中断服务子函数
#pragma interrupt_handler uart0_rx_isr:19
void uart0_rx_isr(void)
{
unsigned char temp;
temp = UDR0;
PORTF = temp; //显示对方的负载数据
//读取串口接收到的数据
switch(temp)
{
case 0x00: Lcounter = 0;break;
case 0xf9: Lcounter = 1;break;
case 0xa4: Lcounter = 2;break;
case 0xb0: Lcounter = 3;break;
case 0x99: Lcounter = 4;break;
case 0x92: Lcounter = 5;break;
case 0x82: Lcounter = 6;break;
case 0xF8: Lcounter = 7;break;
case 0x80: Lcounter = 8;break;
default:{};
}
if(Scounter > Lcounter)
{
if((Scounter - Lcounter) > 2) //如果超过2%
{
FMcounter = Scounter - Lcounter;
ALARMFlg = TRUE; //报警标志位
}
else
{
ALARMFlg = FALSE;
}
}
else
{
ALARMFlg = FALSE; //清除
}
}
//系统初始化函数
void init_devices(void)
{
CLI();
Xdiv = 0x00;
XMCRA = 0x00;
port_init();
uart0_init();
MCUCR = 0x00;
EICRA = 0x00;
EICRB = 0x00;
EIMSK = 0x00;
TIMSK = 0x00;
ETIMSK = 0x00;
SEI();
}
//统计单字节中1的个数
unsigned char SaticOne(unsigned char n)
{
unsigned char sum=0;
while(n)
{
if(n%2==1)
sum++;
n/=2;
}
return sum;
}
void FM(unsigned char t) //蜂鸣器发声函数
{
unsigned char i;
for(i=0;i<50;i++)
{
PORTD^=BIT(0); //PC1取反
DelayMs(t);
}
PORTD&=BIT(0); //PC1翻转
}
void main(void)
{
unsigned char ucKey = 0x00; //按键值
unsigned char ucKeyCounter = 0x00;//按键返回值中1的个数
init_devices(); //初始化系统
for(;;) //进入主循环等待中断事件
{
DelayMs(100); //软件延时
PORTC = 0xFF; //设置PC端口为高电平
ucKey = PINC; //读取拨码开关的值
ucKeyCounter = SaticOne(ucKey);//获得开关被闭合的个数
Scounter = ucKeyCounter;
putchar(SEGtable[ucKeyCounter]); //发送对应的
if(ALARMFlg == TRUE) //如果超重
{
FM(FMcounter); //报警
}
}
}
自己看吧,我在一本书上看到的
不错的代码,谢谢共享!