/**说明************************************************************
MCU:mega16
FREQ:11059200MHz
TIME:2013-12-15
FUNCTION:与上位机通讯实现对主板的控制
**头文件***********************************************************/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
/**宏定义************************************************************/
const unsigned char author[]={'w','h','p'};
#define set_bit(val,bitn) (val|=(1<<(bitn))) //置1
#define clr_bit(val,bitn) (val&=~(1<<(bitn))) //置0
//#define get_bit(val,bitn) (val&(1<<(bitn)) ) //取值(容易理解错误)
#define BAUD 19200 //波特率
#define BAUD_SETTING (unsigned int)((unsigned long)F_CPU/(16*(unsigned long)BAUD)-1)
#define BAUD_H (unsigned char)(BAUD_SETTING>>8)
#define BAUD_L (unsigned char)(BAUD_SETTING)
#define FRAMING_ERROR _BV(FE) //接收帧错误
#define PARITY_ERROR _BV(PE) //校验错误
#define DATA_OVERRUN _BV(DOR) //接收数据溢出
#define DATA_REGISTER_EMPTY _BV(UDRE) //数据寄存器空
#define DATA_BEGIN 0xaa //起始命令
#define T_SIZE 13 //发送长度
#define R_SIZE 4 //接收长度
volatile unsigned char RECE_FLAG,T_count,R_count; //计数标志
volatile unsigned char R_buffer[R_SIZE];
volatile unsigned char T_buffer[T_SIZE]; //缓存区
volatile unsigned char T_index,index; //位序指针
//volatile unsigned char getok=0,rise=1;
volatile unsigned char getok=0;
/**USART初始化*******************************************************/
void USART_init()
{
UCSRA=0x00;
UCSRB=(1<<RXCIE)|(1<<TXCIE)|(1<<RXEN)|(1<<TXEN); //接收完成中断、允许接受、允许发送
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//8位长度\1位停止位\无校验
UBRRH=BAUD_H;
UBRRL=BAUD_L;
}
/****IO口初始化*****************************************************/
void IO_init()
{
DDRA=0xff;
PORTA=0x00;
DDRC=0xff;
PORTC=0x00;
DDRD=0xff;
PORTD=0x03;
}
/*****模拟比较器初始化***********************************************
void COM_init()
{
ACSR=0xc2; //1100 0010 内部参考,中断允许?,下降沿触发
}
**接收中断*********************************************************/
ISR(USART_RXC_vect)
{
unsigned char status,data;
status=UCSRA;
data=UDR;
if(RECE_FLAG) //判断是否接收,1为能接收
{
if((status&(FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)//硬件检验无错误
{
R_buffer[R_count]=data;
R_count++;
switch(R_count)
{
case 1: // 检验起始字符
if(data!=DATA_BEGIN)
R_count=0;
break;
case 3: // 检验校验字
if(data!=0x04)
R_count=0;
break;
case 4: // 检验结束字符
R_count=0;
if (data==((170+R_buffer[1]+4)%255))
RECE_FLAG=0; //表示接收到数据,等待处理
break;
}
}
}
}
/**发送中断*********************************************************/
ISR(USART_TXC_vect)
{
if (T_count)
{
--T_count; //没法送一个这个值会累减
UDR=T_buffer[T_index];
if(++T_index==T_SIZE) //数位循环
T_index=0;
}
}
/*****比较中断******************************************************
ISR(ANA_COMP_vect)
{
rise=0;
}
**发送子函数********************************************************/
void putdat(unsigned char c)
{
// unsigned char index;
while(T_count==T_SIZE); //如果发送队列满,则等待
cli(); //防止T_count在中断中改变
if (T_count||((UCSRA & DATA_REGISTER_EMPTY)==0)) //寄存器不为空(未发或未发完的数据)
{
T_buffer[index]=c;
if(++index==T_SIZE)
index=0;
++T_count; //如果未来得及发送,这个值会累加
}
else
UDR=c; //如果寄存器为空,不需要排队,直接赋值
sei();
}
/**主函数************************************************************/
int main()
{
//定义2位输出变量
unsigned char T_data1;
//控制PORT口初始化
IO_init();
// COM_init(); //比较器初始化
//USART初始化
USART_init();
sei(); //开全局中断
while(1)
{
if(!RECE_FLAG)
{
switch(R_buffer[1])
{
case 0xF0: //读版本号
getok=2;
break;
case 0x01: //A1,+24V
set_bit(PORTA,1);
_delay_ms(100);
getok=1;
break;
.....
.....
case 0x26: //D7,FOOT2
set_bit(PORTD,7);
//clr_bit(ACSR,7);
//set_bit(ACSR,3);
//while(rise);
//clr_bit(ACSR,3);
//set_bit(ACSR,7);
_delay_ms(100);
getok=1;
//rise=1;
break;
case 0x30: //所有继电器初始化
clr_bit(PORTA,1); //用&=为什么不可以
clr_bit(PORTA,2);
clr_bit(PORTA,3);
clr_bit(PORTA,4);
clr_bit(PORTA,5);
clr_bit(PORTA,6);
clr_bit(PORTC,1); //用&=为什么不可以
clr_bit(PORTC,2);
clr_bit(PORTC,3);
clr_bit(PORTC,4);
clr_bit(PORTC,5);
clr_bit(PORTC,6);
clr_bit(PORTC,7);
PORTD=0x03;
_delay_ms(100);
getok=1;
break;
default:
_delay_ms(100);
getok=0;
break;
}
T_data1=R_buffer[1];
switch (getok)
{
case 2:
putdat(DATA_BEGIN);
putdat(0xF0);
putdat(0x0D);
putdat(0xA9);
putdat(0x30);
putdat(0x43);
putdat(0x53);
putdat(0xE1);
putdat(0x01);
putdat(0);
putdat(0);
putdat(0);
putdat(0xFE);
break;
case 1:
putdat(DATA_BEGIN);
putdat(T_data1);
putdat(0x05);
putdat(0x01);
putdat((170+T_data1+5+1)%255);
break;
case 0:
putdat(DATA_BEGIN);
putdat(T_data1);
putdat(0x05);
putdat(0x00);
putdat((170+T_data1+5)%255);
break;
default:
putdat(DATA_BEGIN);
putdat(T_data1);
putdat(0x05);
putdat(0x00);
putdat((170+T_data1+5)%255);
break;
}
RECE_FLAG=1; //处理完一个数据包,开启能接收标志
getok=0;
}
}
}