|
楼主 |
发表于 2005-11-5 10:41:03
|
显示全部楼层
#include <iom48.h>
#include <inavr.h>
#include "Defines.c"
void main(void)
{
uchar i,flag1,crc_data;
int count;
eeprom_struct eep_copy;
uint temp_addr;
system_ini();
system_state=0x40;
send_data_ok=1;
while(1)
{
//__watchdog_reset();
/*=============================================================================*/
if(receive_ok)
{
receive_ok=0;
crc_data=calcrc(rece_data.s_u.trasmit_data,9);
if(crc_data==0)
{
/*数据转移到数据缓冲*/
for(i=0;i<7;i++)
cal_data.s_u.trasmit_data=rece_data.s_u.trasmit_data;
temp_addr=cal_data.s_u.trasmit_data[0];
temp_addr<<=8;
temp_addr|=cal_data.s_u.trasmit_data[1];//获得本机地址2B
system_state=cal_data.s_u.ram.s_commd; //获得主机的控制命令1B
if(!(system_state&0x04)) //是读还是写操作 1:写,0:读
{
if(system_state&0x40) //是单播还是点播 1:单,0:点
{
system_unlock=0; //肯定是单播读操作
/*==============================*/
count=system_site-temp_addr;
//用地址差来确定当前模块需要等待的时间而且不能超过5
/*==============================*/
if ( (count<=5) && (count>0) )
{
switch(count)
{
case 1:
TCNT1=t1_70ms;
break;
case 2:
TCNT1=t1_170ms;
break;
case 3:
TCNT1=t1_270ms;
break;
case 4:
TCNT1=t1_370ms;
break;
case 5:
TCNT1=t1_470ms;
break;
default:break;
}
/*==============================*/
start_t1();//开始定时
}
else
end_t1();
}
else //点播---读操作
if( temp_addr==system_site )
//if((temp_addr==system_site) && system_unlock)
send_data_ok=1;
}
/*==============================*/
else //当前收到的数据帧是写操作 //本地参数修改
{ /*检查地址匹配和判断是什么操作模式*/
if((!(system_state&0x40)) && (temp_addr==system_site) )//写操作&&点播
{
switch(system_state&0x18)//取出bit 4 3判断数据的状态类型
{
case seri://序列号b 01
flag1=0;
/*为什么要去跟0x01020301比较???*/
for(i=0;i<4;i++)
if(cal_data.s_u.ram.s_data!=serial)
flag1=1;
if(!flag1)
{
system_unlock=1; //进入解锁模式
//TCNT1=t1_200ms;
TCNT1=t1_1000ms;
start_t1();
}
//既然是修改序列号 为什么没有做修改操作呢?
break;
case zoom://放大系数b 10
//__watchdog_reset();
if(system_unlock)
{
for(i=0;i<4;i++)
{ /*将放大系数写入EEPROM缓冲*/
system_zoom=cal_data.s_u.ram.s_data;
eep_copy.e_u.eeprom.a=system_zoom;
}
eep_copy.e_u.eeprom.e_addr=system_site;
eep_copy.e_u.eeprom.e_crc=calcrc(eep_copy.e_u.eep_data,6);
write_eeprom(eep_copy);//真正的修改到EEPROM中
//__watchdog_reset();
}
system_unlock=0;//退出解锁模式
end_t1();
break;
case site://通道地址b 11
//__watchdog_reset();
if(system_unlock)
{
system_site=cal_data.s_u.ram.s_data[2];
system_site<<=8;
system_site|=cal_data.s_u.ram.s_data[3];
for(i=0;i<4;i++)
eep_copy.e_u.eeprom.a=system_zoom;
eep_copy.e_u.eeprom.e_addr=system_site;
eep_copy.e_u.eeprom.e_crc=calcrc(eep_copy.e_u.eep_data,6);
write_eeprom(eep_copy);
//__watchdog_reset();
}
system_unlock=0;
end_t1();
break;
default:break;
}
}
}
}
}//?if(receive_ok)
/*=============================================================================*/
if(send_data_ok)//允许发送模式标志设置后进入
{
//__watchdog_reset();
send_data.s_u.trasmit_data[0]=(system_site>>8)&0xff;
send_data.s_u.trasmit_data[1]=system_site;
send_data.s_u.ram.s_commd=system_state;
switch(system_state&0x18)
{
case volt:
now_send_volt=1;
for(i=0;i<4;i++)
send_data.s_u.ram.s_data=data1;
now_send_volt=0;
break;
case seri:
for(i=0;i<4;i++)
send_data.s_u.ram.s_data=serial;
break;
case zoom:
for(i=0;i<4;i++)
send_data.s_u.ram.s_data=system_zoom;
break;
default:break;
}
send_data.s_u.ram.s_crc=calcrc(send_data.s_u.trasmit_data,7);
send();
system_state=0;
send_data_ok=0;
}//?if(send_data_ok)
/*=============================================================================*/
}
}
//****************************************
//函数功能:外部中断函数,采7135数据
//入口函数:无
//出口参数:无
//备注:PC[3..0]=B[1..4]原来是:PB[3..0]=B[4..1]
//现在是PB[5..1]=D[5..1](D5是最高位)
//原来是PB[7..4]=D[1..4] PD6=D5
//1 9 9 9 9 [8 4 2 1 ]
//D5 D4 D3 D2 D1 [B4 B3 B2 B1]
//data[4]保存原始数据;data1[4]读取原始数据
//#pragma vector = INT0_vect
#if _VOLT_GET >0
#pragma vector = INT0_vect
__interrupt void Int0Service (void)
{
uchar a_d_temp;
uchar j;
EIMSK&=0xfe; //关闭外部中断0
//===================================//
j=0;
a_d_temp=PINC&0x0f; //取出BCD数据
a_d_temp&=0x0f; //去掉最高四位
while(a_d_temp) //高低位翻转由于硬件设计原因
{
j<<=1; //保存高位
j|=a_d_temp&0x01; //存入低位
a_d_temp>>=1; //移动一位到末端
}
a_d_temp=j&0x0f; //到此时已经获得了真正的BCD数据
switch(PINB&0x3e) //0011 1110[PB5-PB1]PB5:对应最高位
{
case 0x02: //D5
data[1]=a_d_temp&0x01;
//bcdbuf[0]=a_d_temp;
break;
case 0x04: //D4
data[2]=a_d_temp;
//bcdbuf[1]=a_d_temp;
break;
case 0x08: //D3
data[2]<<=4;
data[2]|=a_d_temp;
//bcdbuf[2]=a_d_temp;
break;
case 0x10: //D2
data[3]=a_d_temp;
//bcdbuf[3]=a_d_temp;
break;
case 0x20: //D1
data[3]<<=4;
data[3]|=a_d_temp;
data[0]=0; //设置数据符号位为+
/*如果当前没有发送电压则转存数据*/
if(!now_send_volt)
{
for(j=0;j<4;j++)
data1[j]=data[j];
}
//bcdbuf[4]=a_d_temp;
break;
default:
break;
}
/*这里是原来的at90s2313使用的代码
a_d_temp=PINB&0x0f;//获取当前的数据
if(PIND&0x40)//判断是否为第五位最高位
data[1]=a_d_temp&0x01;//四位半中的半位要么为0要么为1
else
{
switch(PINB&0xf0)//读高四位选择读取第几个数字
{
case 0x80://D1
data[3]<<=4;
data[3]|=a_d_temp;
data[0]=0;
if(!now_send_volt)
for(j=0;j<4;j++)
data1[j]=data[j];
break;
case 0x40:
data[3]=a_d_temp;
break;
case 0x20:
data[2]<<=4;
data[2]|=a_d_temp;
break;
case 0x10://D4
data[2]=a_d_temp;
break;
default:break;
}
}
*/
//===================================//
EIMSK|=0x01; //恢复外部中断0
}
#endif
//****************************************
//函数功能:中断接收函数
//入口函数:无
//出口参数:无
//****************************************
//#pragma vector = UART_RX_vect //2313使用
#pragma vector =USART_RX_vect
__interrupt void UartService (void)
{
uchar temp1,u_temp;
/*==========================*/
__disable_interrupt();
temp1=UDR0; //mega48使用
/*==========================*/
if(!header_length)//头ff 55 00
{
if(temp1==0xff)
header_length=1;
}
else
{
if(temp1==0x55)
header_length++;
else
{
if(!temp1)//0x00
if(header_length==2)
{
head_ok=1;
header_length=0;
data_length=0;
data_time=0;
goto exit;
}
header_length=0;
}
}
/*==========================*/
if(head_ok)
{ //因为在8515发出来时进行了数据重复3次
if(data_time==3)//每三个字节数据中选择一个
{
data_time=0;
/*===================*/
if(temp[0]==temp[1])
u_temp=temp[0];
else if(temp[0]==temp[2])
u_temp=temp[0];
else
u_temp=temp[1];
/*===================*/
rece_data.s_u.trasmit_data[data_length++]=u_temp;
}
temp[data_time++]=temp1;
}
/*==========================*/
if(data_length==9)
{
head_ok=0;
receive_ok=1;
data_length=0;
/*if(rece_data.s_u.ram.s_commd&0x80)//判断是否为复位命令
{
WDTCSR=0x08; //watch dag is 16ms
while(1);//让模块复位
}
*/
}
/*==========================*/
exit:
__enable_interrupt();
}
//*************************************************
//功能:定时器1,进行与无线发谢模块在时钟上同步,
//入口参数:
//出口参数:
//备注:计时函数,有INT0中断产生,注:晶振用3.6864M
//*************************************************
//#pragma vector = TIMER1_OVF1_vect //2313使用
#pragma vector = TIMER1_OVF_vect
__interrupt void Timer1Service (void)
{
end_t1();
if(system_unlock)
system_unlock=0;
else
send_data_ok=1;
}
//*************************************************
//功能:定时器0, 用做5ms延时和25ms关trasmit_mode
//入口参数:
//出口参数:
//备注:计时函数,有INT0中断产生,注:晶振用3.6864M
//*************************************************
//#pragma vector = TIMER0_OVF0_vect //2313使用
#pragma vector = TIMER0_OVF_vect
__interrupt void Timer0Service (void)
{
TIFR0|=0x01;
end_t0();
receive_mode();
TIMSK0&=0xfe; //关闭t0中断mega48
}
-----此内容被Houseivan于2005-11-05,10:42:30编辑过
//==================define.c=============================//
//****************************************
//函数功能:进行定时器,串口等初始化操作
//入口函数:无
//出口参数:无
//***************************************
#ifndef _DEFINE_C
#define _DEFINE_C
#define uchar unsigned char
#define uint unsigned int
#define _MCU_TYPE 1 //1:表示Mega48,0:表示90S2313
#define _DEBUG 0 //调试开关
#define _BAUD_9600 0 //1:Baud=9600;0:14400/19200
#define _VOLT_GET 1
#define _IO_CHANGE 0
#define _BAUD_RATE 14.4 //规定的串口波特率14.4K
#define _FOSC_VALUE 3686.4 //3.6864MHZ=3686.4KHZ
#define wirless_Address 0x12 //无线站址
#define t1_70ms 0xff03
#define t1_170ms 0xfd9b
#define t1_270ms 0xfc33
#define t1_370ms 0xfacb
#define t1_470ms 0xf963
#define t1_200ms 0xfd2f
#define t0_5ms 0xed
#define t0_25ms 0xa5
#define t0_40ms 0x6f
#define t1_1000ms 0xf1ef
#define volt 0x00
#define seri 0x08
#define zoom 0x10
#define site 0x18
/*===============函数宏表达式定义====================*/
#define display_on() PORTD&=0xdf
#define display_off() PORTD|=0x20
#define SET_TXD_H() PORTD|=0x02
#define SET_RXD_H() PORTD|=0x01
#define SET_TXD_IN() DDRD&=0xfd;
#define SET_TXD_OUT() DDRD|=0x02;
#define SET_RXD_IN() DDRD&=0xfe;
#define SET_RXD_OUT() DDRD|=0x01;
#if _IO_CHANGE>0
//TXEN:PD7/CS:PD6
#define SET_TXEN_H() PORTD|=0x80
#define SET_TXEN_L() PORTD&=0x7f
#define SET_CS_H() PORTD|=0x40
#define SET_CS_L() PORTD&=0xBF
#else
//TXEN:PD4/CS:PD3
#define SET_TXEN_H() PORTD|=0x10
#define SET_TXEN_L() PORTD&=0xef
#define SET_CS_H() PORTD|=0x08
#define SET_CS_L() PORTD&=0xF7
#endif
/*2313
#define Receive_Enable() UCR|=0x10 //串口允许接收
#define Receive_Disable() UCR&=0xef //串口禁止接收
#define trasmit_enable() UCR|=0x08 //串口允许发送
#define trasmit_disable() UCR&=0xf7 //串口允许发送
*/
//mega48使用
#define Receive_Enable() UCSR0B|=0x10 //允许接收
#define Receive_Disable() UCSR0B&=0xef //禁止接收
#define trasmit_enable() UCSR0B|=0x08 //允许发送
#define trasmit_disable() UCSR0BR&=0xf7 //允许发送
/*预定义宏:发送方式*/
#define trasmit_mode() \
{ \
SET_TXEN_H(); \
display_off(); \
}
/*预定义宏:接收方式*/
#define receive_mode() \
{ \
SET_TXEN_L(); \
display_on(); \
}
/*2313
#define start_t1() TCCR1B=0x05 //clk/1024,启动定时T1
#define end_t1() TCCR1B=0x00 //停止定时T1
#define start_t0() TCCR0=0x05 //clk/1024,启动定时T0
#define end_t0() TCCR0=0x00 //停止定时T0
*/
//mega48使用
#define start_t1() TCCR1B=0x05 //clk/1024,启动定时T1
#define end_t1() TCCR1B=0x00 //停止定时T1
#define start_t0() TCCR0B=0x05 //clk/1024,启动定时T0
#define end_t0() TCCR0B=0x00 //停止定时T0
/*输入输出定义*/
/*0b00000000*/
#define PB_direct_define DDRB=0x00
/*0b00000000*/
#define PB_data_define PORTB=0x00
/*0b11111010*/
#define PD_direct_define DDRD=0xfe
/*0b00000010*/
#define PD_data_define PORTD=0x02
/*0b00000000*/
#define PC_direct_define DDRC&=0x80
/*0b00000000*/
#define PC_data_define PORTC=0x00
void system_ini(void)
{
uchar m;
#if _DEBUG<1
uchar n,crc_data1,err;
eeprom_struct struct_back,good_eep;
#endif
float2char f_zoom;
/*============================*/
//TIMSK|=0x80; //开启T1 2313使用
TIMSK1|=0x01; //开启T1 mega48使用
//UCR|=0x80; //接收结束中断使能 2313使用
UCSR0B|=0x80; //接收结束中断使能 mega48使用 启用UART
#if _BAUD_9600>0 //这样做的好处是节约代码空间
//UBRR=23;
UBRR0=23
#else
//UBRR=15; //95--2400 23--9600 15--14400 11--19200
UBRR0=11;
#endif
TCCR1A=0x00; //这里2313和mega48一致 T1采用定时方式
TCCR0A=0x00; //mega48专用
//MCUCR=0x02; //中断0下降沿触发? 2313使用
//GIMSK=0x40; //外中断0使能 2313
#if _VOLT_GET <1
data1[0]=0x00;
data1[1]=0x00;
data1[2]=0x88;
data1[3]=0x43;
#else
EICRA|=0x02; //中断0下降沿触发?mega48使用
EIMSK|=0x01; //外部中断0 请求使能
#endif
/*============================*/
PB_direct_define;
PB_data_define;
PC_direct_define;
PC_data_define;
PD_direct_define;
PD_data_define;
SET_CS_L();
receive_mode();
/*============================*/
end_t0();
end_t1();
/*============================*/
f_zoom.f_data=default_zoom;
#if _DEBUG<1
err=0;
for(m=0;m<=120;m+=40)
{
struct_back=copy_eeprom(m);
crc_data1=calcrc(struct_back.e_u.eep_data,8);
if(crc_data1)
err++;
else
{
good_eep=copy_eeprom(m);
system_site=good_eep.e_u.eeprom.e_addr;
for(n=0;n<4;n++)
system_zoom[n]=good_eep.e_u.eeprom.a[n];
}
}
if(err)
{
if(err==4)
{
system_site=wirless_Address;
for(m=0; m<4; m++)
system_zoom[m]=f_zoom.c_data[m];
}
else
write_eeprom(good_eep);
}
#else
system_site=wirless_Address;
for(m=0; m<4; m++)
system_zoom[m]=f_zoom.c_data[m];
#endif
/*============================*/
//WDTCR=0x0b; //watch dog is 120ms 2313
//WDTCSR=0x0b; //125ms mega48
/*============================*/
/*============================*/
header_length=0;
head_ok=0;
now_send_volt=0;
data_length=0;
system_unlock=0;
send_data_ok=0;
receive_ok=0;
/*============================*/
Receive_Enable();
trasmit_enable();
/*============================*/
__enable_interrupt();
/*============================*/
}
-----此内容被Houseivan于2005-11-05,10:45:58编辑过 |
|