//************************************************************//
//**************开关量的采集修改******************************//
//*************2013.3.12**********路************************//
//************宏定义文件 ************************************//
//***********************************************************//
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#define F_CPU 11059200 /* 单片机主频为11.0592MHz,用于延时子程序 */
#include <util/delay.h>
#include <avr/iom16.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long int
#define CON1(x) if(x==0){PORTD&=~_BV(PD2);}else{PORTD|=_BV(PD2);} //485通信1接受发送使能
#define baud 9600 //设置波特率的大小
#define baud_setting (uint)((ulong)F_CPU/(16*(ulong)baud)-1) //波特率计算公式
#define baud_h (uchar)(baud_setting>>8) //提取高位
#define baud_l (uchar)(baud_setting) //低位
#define delay_us(x) _delay_us(x) //AVR GCC延时函数 x(us)
#define delay_ms(x) _delay_ms(x) //AVR GCC延时函数 x(ms)
//*************************************************************
//*** 全局变量定义 ***0
//*************************************************************
uchar RX1_data[125];
uchar RX1_arm_data[125];
uchar RX1_Len;
uchar ddada[50]= { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //接收的数据
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uchar addr_arm; //报警地址
uchar temper[50]={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, //处理的数据
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uchar RX1_state; //数据处理完标志位
uchar RX1_len; //串口1计数据长度
uchar RX1_Cmd_ok; //串口1接收完成标志位
uchar dz,H_dz,L_dz,ml; //从站发送地址,地址高位,地址低位,功能码
uint H_nu,L_nu,nu; //接收数量高位,接收数量低位,接收数量
uchar ml; //功能码
uchar ms2; //定时中断2的时间变量
//#define uchar unsigned char
//#define uint unsigned int
//#define ulong unsigned long int
/* CRC 高位字节值表 */
const prog_char auchCRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40
};
/* CRC低位字节值表*/
const prog_char auchCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
0x40
};
/***********************************/
//函数名称:CRC16(uchar *pushMsg,uchar usDataLen)
//函数功能:CRC校验函数
//输入参数:*pushMsg 校验数据起始地址指针
//输出参数:usDataLen 校验数据长度
//返 回 值:16位CRC校验码
/***********************************/
uint CRC16(uchar *pushMsg,uchar usDataLen)
{
uchar uchCRCHi=0xFF; /*高CRC字节初始化*/
uchar uchCRCLo=0xFF; /*低CRC 字节初始化*/
uint uIndex; /*CRC循环中的索引*/
while (usDataLen--) /*传输消息缓冲区*/
{
uIndex = uchCRCHi ^ *pushMsg++; /* 计算CRC */
uchCRCHi = uchCRCLo ^ pgm_read_byte(&auchCRCHi[uIndex]);
uchCRCLo = pgm_read_byte(&auchCRCLo[uIndex]);
}
return (uchCRCHi<< 8 | uchCRCLo);
}
//*********************************************/
//函数名称:port_init
//函数功能:IO端口初始化
//输入参数:无
//输出参数:无
//返 回 值:无
/*********************************************/
void port_init(void)
{
PORTA = 0xFF; //全为0,全输出低电平输入:
DDRA = 0x00;
PORTB = 0xFF;
DDRB = 0x00; //全为0,全输出低电平输入:
}
/*********************************************/
//函数名称:usart1_init
//函数功能:串口通信初始化程序
//输入参数:无
//输出参数:无
//返 回 值:无
/*********************************************/
void usart1_init(void)
{
UCSRA = 0x00; //工作在异步正常模式下 U2X=0
UCSRB = 0xF8; //接收中断和发送中断允许
UCSRC=(1<<UCSZ1)|(1<<UCSZ0); //写UCSRC寄存器,异步通信无校验,8位数据1位停止位
UBRRH=baud_h; //写波特率的值
UBRRL=baud_l;
}
/***********************************/
//函数名称:ADC_read
//函数功能:模数转换
//输入参数:无
//输出参数:
//返 回 值:
/***********************************/
uchar bomakaiguan(void)
{
uchar j,i;
j=~PINB;
i=j&0xff;
return i;
}
/***********************************/
//函数名称:ADC_read
//函数功能:模数转换
//输入参数:无
//输出参数:
//返 回 值:
/***********************************/
uchar press_key(void)
{
uchar j,i;
j=~PINA;
i=j&0xff;
return i;
}
/*********************************************/
//函数名称:timer2_init(void)
//函数功能:定时T2初始化配置函数 1ms
//输入参数:无
//输出参数:无
//返 回 值:无
/*********************************************/
void timer2_init(void)
{
TCCR2 = 0x00; //stop
ASSR = 0x00; //set async mode
TCNT2 = 0xF6; //定时为1ms 定时器初值,定时器加一计数
TCCR2 = 0x07; //普通模式,OC0不输出,1024分频
TIFR = 0x40; //清中断标志位
TIMSK = 0x40; //溢出中断使能
}
/*********************************************/
//函数名称:SIGNAL(SIG_OVERFLOW2) 3.5T要做的事。
//函数功能:T2溢出中断服务程序
//输入参数:无
//输出参数:无
//返 回 值:无
/*********************************************/
SIGNAL(SIG_OVERFLOW2)
{
TCNT2=0xF6; //定时器赋初值,非自动重装模式
if(ms2<15)
{
ms2++; //微秒
}
else
{
TCCR2 = 0x00; //停止定时器
// RX1_arm_len=RX1_Len; //命令长度
RX1_Len=0;
RX1_Cmd_ok=1; //一个消息接收完成!等待处理
}
}
/***********************************/
//函数名称:SIGNAL(SIG_USART1_RECV)
//函数功能:串口接受中断处理函数,接收串口数据。
//输入参数:无
//输出参数:接收的串口数据
//返 回 值:无
/***********************************/
SIGNAL(SIG_USART_RECV)
{
TCCR2=0x00; //停止计数
if(ms2>15)
{
RX1_len=0;
ms2=0;
}
RX1_data[RX1_Len]=UDR; //接收数据1
RX1_Len++;
// RX1_len&=0xFF; //最大接收的字节32个
ms2=0;
TCCR2=0x00; //停止定时器
TCNT2=0xF6; //定时为1ms 定时器初值,定时器加一计数
TIMSK=0x40; //溢出中断使能
TCCR2=0x07; //普通模式,OC0不输出,1024分频
}
/***********************************/
//函数名称:usart1_TX
//函数功能:串数据发送查询方式发送*
//输入参数:tx_data
//输出参数:串口数据
//返 回 值:无
/***********************************/
void usart1_TX(uchar tx_data)
{
while(!(UCSRA &(1<<UDRE)));
UDR = tx_data;
}
//*********************************************/
//函数名称:串口ViewTem_cmd 发送数据 取采集的开关变量
//函数功能:
//返 回 值:无
/*********************************************/
void ViewTem_cmd(void)
{
uint crc,i,j;
uchar fs[100];
ddada[0]=press_key();
CON1(0);
fs[0]=temper[0]; //从机地址
fs[1]=temper[1]; //命令号
fs[2]=temper[2]; //数据字节数
for(i=0;i<temper[2];i++)
{
fs[3+i] =ddada[i];
}
crc=CRC16(&fs[0],3+temper[2]);
fs[3+temper[2]]=crc>>8;
fs[4+temper[2]]=crc&0xff;
wdt_reset();//喂狗
for(j=0;j<5+temper[2];j++)
usart1_TX(fs[j]);
while(!(UCSRA & (1<<UDRE)));
_delay_ms(2);
CON1(1);
}
/***********************************/
//函数名称:deal_RX1data
//函数功能:串口1数据中断处理函数,处理接收的串口1数据。
//输入参数:无
//输出参数:接收的串口数据
//返 回 值:正确与否的标志
/***********************************/
void deal_RX1data(void)
{
uchar j;
uint crc; //本地计算CRC
uint js_crc; //接收到的CRC
uint n;
if(RX1_Cmd_ok==1)
{
for(j=0;j<8;j++)
{
RX1_arm_data[j]=RX1_data[j]; //转存串口接收的数据,等待处理!
}
dz= RX1_arm_data[0]; //取数据来源地址
ml= RX1_arm_data[1]; //取命令码
H_dz= RX1_arm_data[2]; //地址高位
L_dz= RX1_arm_data[3]; //地址低位
H_nu= RX1_arm_data[4]; //数据高位
L_nu= RX1_arm_data[5]; //数据低位
nu=((H_nu<<8)|L_nu); //总数据
if(dz==bomakaiguan())
{
if(ml==0x02) //命令
{
wdt_reset();//喂狗
crc=CRC16(&RX1_arm_data[0],6); //计算接收命令CRC
js_crc= RX1_arm_data[6]; //接收到的CRC
js_crc=((js_crc<<8)| RX1_arm_data[7]);
wdt_reset();//喂狗
if(crc==js_crc)
{
_delay_ms(100);
temper[0]=RX1_arm_data[0];
temper[1]=RX1_arm_data[1];
n=nu/8;
if(n*8<nu)
n=n+1;
temper[2]=n;
ddada[0]=press_key();
_delay_ms(100);
ViewTem_cmd();
}
}
}
RX1_Cmd_ok=0;
}
}
/*********************************************/
//函数名称:初始化子程序
//函数功能:包含所有的初始化程序
//输入参数:无
//输出参数:无
//返 回 值:无
/*********************************************/
void init_devices(void)
{
cli(); //禁止所有中断
port_init();
usart1_init();
timer2_init();
sei();//开全局中断
}
/*********************************************/
//函数名称:主函数
//函数功能:包含所有的初始化程序
//输入参数:无
//输出参数:无
//返 回 值:无
/*********************************************/
int main(void)
{
init_devices();
_delay_ms(300);
while(1)
{
wdt_reset();//喂狗
_delay_ms(300);
deal_RX1data() ;//接收命令
}
}
|