📄 init.c
字号:
/********************************************************/
/* ABOL */
/* 868MHZ数码管显示接收器 */
/* 作者:于朝晖 2008-5-24 9:30:00 */
/* 目标MCU:MEGA16 晶振:INT RC 8MHZ */
/* 文件名称:init.c 负责初始化MCU各内部资源及外部端口 */
/* 编译:ICC-AVR application builder */
/* 当前版本: 1.0 */
/* 修改日期: 2008.5.24 */
/********************************************************/
#include <iom88v.h>
#include <macros.h>
#include "eeprom.h"
#include "delay.h"
#include "init.h"
#define bitset(var, bitno) ((var) |= (1 << (bitno)))
#define bitclr(var, bitno) ((var) &= ~(1 << (bitno)))
unsigned char ptr[3]={0,0,0};
void port_init(void)
{
PORTB = 0xff; //00010000 ff
DDRB = 0xff; //11111111 ff
PORTC = 0x0c; //00001100 0c
DDRC = 0xf7; //11111011 f7
PORTD = 0xee; //11101111 e7
DDRD = 0x11; //00010001 19
}
void timer0_init(void)
{
TCNT0 =196; // T/C0开始值
TCCR0B=0x02; // 预分频 ck/8 ,计数允许
TIFR0=0;
TIMSK0=1;
TIFR0=1;
}
void timer2_init(void)
{
TIMSK2=0;
ASSR=32; //外部时钟输入使能
TCCR2A=0; //普通模式
TCCR2B=3; //32分频
TCNT2=0; // T/C2开始值
NOP();
NOP();
NOP();
NOP();
TIFR2=0; //清标致位
TIMSK2=0; // 预分频 32768/32 ,计数允许
TIFR2=1;
}
void watchdog_init(void)
{
WDR(); //this prevents a timout on enabling
WDTCSR=(1<<WDCE)|(1<<WDE);
WDTCSR=(0<<WDE);
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
timer2_init();
//watchdog_init();
MCUCR = 0x00;
EIMSK = 0x00;
EICRA = 0x00; //extended ext ints
TIMSK0 = 0x01; //timer 0 interrupt sources
TIMSK1 = 0x00; //timer 1 interrupt sources
TIMSK2 = 0x01; //timer 2 interrupt sources
PCMSK0 = 0x00; //pin change mask 0
PCMSK1 = 0x00; //pin change mask 1
PCMSK2 = 0x00; //pin change mask 2
PCICR = 0x00; //pin change enable
//PRR = 0xa2; //power controller
SEI(); //re-enable interrupts
ADCSRA=0X16;
ADMUX=0X00; //关ADC
ACSR=(1<<ACD);
SMCR=(0<<SM2)|(1<<SM1)|(0<<SM0); //设定为掉电模式
//all peripherals are now initialized
}
/* AD转换 */
void ADconv (void)
{WDR();
CLI();
ADMUX=0XE0; //1.1V基准,ADC0通道0B11100000
ADCSRA=0XC6; //使能和转换
while(!(ADCSRA & (1<<ADIF)));//转换测试
ADcon=ADCL;
ADcon=ADCH;
ADCSRA=0X16;
ADMUX=0X00; //关ADC
SEI();
}
/******************************************
CRC3校验函数
输 入: ptr需要进行校验的数据包
len需要校验的数据包字节数
输 出: 校验码;
调 用: 无;
被调用: 从机协议打包函数;
功 能: 将一给定的数据包进行CRC12校验给调用者返回校验码
******************************************/
unsigned char CRC3(unsigned char *data, unsigned char len)
{
unsigned char i;
unsigned char j;
j = 0;
crc=0;
while(len)
{
/*多项式除法*/
if(*data & (0x80>>j)) //如果该位为1
crc |= 0x01; //则在余数尾部添1否则添0
if(crc >= 0x8)
crc ^= 11;
crc <<= 1;
j++;
if(j == 8)
{
j = 0;
data++;
len--;
}
}
return(crc);
}
#pragma interrupt_handler timer0_ovf_isr:17
void timer0_ovf_isr(void) //中断程序
{
unsigned char i,j;
TCNT0=196; //产生16.8K的信号
if (((flag&0x02)!=0)&&((flag&0x04)==0))//RF开关
{//1
if ((PINC&0x08)==0)//测试输入电平 如输入为1跳到高计数
{//2
if ((flag&0x01)==0)//检测以前的解码状态
{//2-1
LO_COUNT++;//最大计数 FFH
if (LO_COUNT==0)
{//2-1'
LO_COUNT--;
}//2-1'
return;//大于FFH跳出中断
}//2-1
DECODER_STATUS_L; //变成当前状态
LO_COUNT_SAVE=LO_COUNT;//保存低电平计数
LO_COUNT=0;//更新低电平计数
if ((HI_COUNT_SAVE>MAXDURATION)||(HI_COUNT_SAVE==0))//如果高电平大于限定值
{//2-2
BITCOUNTER=CODELANGTH;//代码是错误的
data[0]=0;
data[1]=0;
data[2]=0;
}//2-2
return;//跳出中断
}//2
else//高计数
{//3
if ((flag&0x01)!=0)//检测以前的解码状态
{//4
HI_COUNT++;
if (HI_COUNT==0)//大于FFH跳出中断
{//4-1
HI_COUNT--;
}//4-1
return;//跳出中断
}//4
DECODER_STATUS_H; //变成当前状态
HI_COUNT_SAVE=HI_COUNT;//保存高电平计数
HI_COUNT=0;//更新低电平计数
if ((LO_COUNT_SAVE>MAXDURATION)||(LO_COUNT_SAVE==0))//如果低电平大于限定值
{//3-1
BITCOUNTER=CODELANGTH;//代码是错误的
data[0]=0;
data[1]=0;
data[2]=0;
return;//跳出中断
}//3-1
}//3
if (HI_COUNT_SAVE<LO_COUNT_SAVE)//为1的数据存贮
{//5
i=data[2]&0x80; //保存第七位
data[2]<<=1;
data[2]+=1;
j=data[1]&0x80; //保存第七位
if(i){data[1]<<=1;data[1]+=1;}
else data[1]<<=1;
if(j){data[0]<<=1;data[0]+=1;}
else data[0]<<=1;
BITCOUNTER--;
if (BITCOUNTER==0)//解码完成
{//5-3
if(CRC3(data,3)==0)
{//n
DECODER_FLAG_H;
DECODER_EN_L;
eaddr0=data[0];
eaddr1=data[1];
return;
}//n
else //解码错误
{
goto give_up;
}
}//5-3
return;
}//5
else //为0的数据存贮
{//6
i=data[2]&0x80; //保存第七位
data[2]<<=1;
j=data[1]&0x80; //保存第七位
if(i){data[1]<<=1;data[1]+=1;}
else data[1]<<=1;
if(j){data[0]<<=1;data[0]+=1;}
else data[0]<<=1;
BITCOUNTER--;
if (BITCOUNTER==0)//解码完成
{//6-3
if(CRC3(data,3)==0)
{//n
DECODER_FLAG_H;
DECODER_EN_L;
eaddr0=data[0];
eaddr1=data[1];
return;
}//n
else //解码错误
{
goto give_up;
}
}//6-3
return;
}//6
give_up:
data[0]=0;
data[1]=0;
data[2]=0;
BITCOUNTER=CODELANGTH;
DECODER_FLAG_L;
LO_COUNT_SAVE=0;
HI_COUNT_SAVE=0;
}//1
}
#pragma interrupt_handler timer2_ovf_isr:10
void timer2_ovf_isr(void) //中断程序
{//00
unsigned char i;
//RF_ON;//关RF使能
//DECODER_EN_L;//关RF接收数据
flag|=0x80;
flagh|=0x80;
bitclr(PORTD,0);
acount++;
if(acount>1)
{
tm1620(); //刷新显示
flagh^=0x04; //闪烁LED 32768/32*2=0.5s
acount=0;
}
bcount++;
if(bcount>3) //
{//3
if(SPFC!=0) //开蜂鸣器
{
bitset(PORTD,0);
SPFC--;
}
/* RF_OFF; //开RF使能
data[0]=0;
data[1]=0;
data[2]=0;
BITCOUNTER=CODELANGTH;
DECODER_FLAG_L;
LO_COUNT_SAVE=0;
HI_COUNT_SAVE=0;
DECODER_EN_H;//开RF接收数据 */
flag&=~0x80;
bcount=0;
sec--;
sec0--;
if(sec0==0)
{
sec0=3;
flagh |=BIT(1); //3sec
}
if(sec==0) //秒判断 32768/32*4*SEC
{//4
flagh |=BIT(0); //倒计时时间到
sec=60;
if((PIND&0X06)==2)
{
minu15++;
if(minu15>15) //15分钟自动全部清除
{
datas[0]=datas[1]=datas[2]=datas[3]=datas[4]=datas[5]=datas[6]=datas[7]=0;
dipdata[3]=dipdata[4]=dipdata[5]=0;
dipdata[0]=dipdata[1]=dipdata[2]=0;
dipdata[5]|=0x80; //电源LED
minu15=0;
minu30=0;
}
}
if((PIND&0X06)==4)
{
minu30++;
if(minu30>30) //30分钟自动全部清除
{
datas[0]=datas[1]=datas[2]=datas[3]=datas[4]=datas[5]=datas[6]=datas[7]=0;
dipdata[3]=dipdata[4]=dipdata[5]=0;
dipdata[0]=dipdata[1]=dipdata[2]=0;
dipdata[5]|=0x80; //电源LED
minu30=0;
minu15=0;
}
}
}//4
}//3
}//00
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -