www.pudn.com > AVRem4095.rar > AVRem4095.c


/*在提取出同步时钟信号后,就可以通过检测出两个上升沿(或下降沿)的时间间隔来提取数据了。 
两个上升沿(或下降沿)的时间间隔总共有t=T’,t=1.5T’,t=2T’三种情况。  
如果检测到两个上升沿之间的间隔t=T’时,则收到一个与前一个逻辑值相同的数据, 
在b上升沿之后t=T’时间的的c处检测到上升沿,得到与前一个逻辑值con_receive相同的数据1。 
将此数据存放入存储器中,并同时将当前逻辑值1赋给状态位con_receive; 
如果检测到两个上升沿之间的时间间隔t=1.5T’时,两种情况:当前一个数据值con_receive为1时, 
得到两个数据00,并将逻辑值0赋给con_receive;当前一个数据为0时,得到一个数据1, 
并将逻辑值1赋给con_receive。如图3,在c上升沿之后t=1.5T’时间的d处检测到上升沿, 
由于在c上升沿得到的逻辑值为1,则得到数据00,con_receive的值也相应变为0; 
又经过T’时间后到达e上升沿,得到与前一个逻辑值相同的数据0; 
又经过t=1.5T’时间到达f上升沿,由于前一个数据的逻辑值为0, 
则得到数据1,con_receive也相应变为1;如果检测到两个上升沿之间的时间间隔t=2T’时, 
得到两个数据01,并将逻辑值1赋给con_receive。如图3,在f上升沿之后的t=2T’时间的g处检测到上升沿, 
得到两个数据01; 
但是这个程序是,在周期中间的下降沿才是1,上升沿是0. 
*/ 
//采用外部晶振8.000Mhz 
#include  
#define RXB8 1 
#define TXB8 0 
#define UPE 2 
#define OVR 3 
#define FE 4 
#define UDRE 5 
#define RXC 7 
#define FRAMING_ERROR (1< 
///////////////////////////////////////////////////////////////// 
unsigned char global_flag=0;  
#define MAXCARDCHAR   10 
#define _WHICH_EXT0 0    
#define _CARD_DATA 0 
#define _set(c,b) (c)|=1<<(b) 
#define _clr(c,b) (c)&=(~(1<<(b))) 
#define _flag(c,b) ((c)&(1<<(b)))//==(1<<(b))) 
#define _EXTFALL      MCUCR=0x02    
#define _EXTRIS       MCUCR=0x03     
#define _TCONT_OFF    TCCR0=0x00 
#define _TCONT_ON     TCCR0=0x03   
 
bit f_cyc=0; //0表示下降沿空跳,1表示周期中间;  
bit f_pr=1; //这个是记录前一次的状态值。 
unsigned int t_value=0,header_data=0,Lcardbytein[10]; 
unsigned char data_head=0,header_data_count=0,cyc=0,c_count=0,data=0;     
unsigned char rbit=0,one_cyc=0,cardbytein[15],parity=0; 
unsigned char TH1=0,TL1=0; 
void all_parameter_init(void);  
void all_parameter_init(void){ 
            header_data_count=0;    
            TCCR1B=0x00;  
            rbit=0; 
            cyc=0;  
            data=0;  
            header_data=0; 
            t_value=0;  
            GICR|=0x40;  
                 
}                              
// External Interrupt 0 service routine 
interrupt [EXT_INT0] void ext_int0_isr(void) 
{  
/* 
GICR&=0xbf;  
TCCR1B=0x02;  
   t_value=TCNT1; 
   TCNT1H=0x00;TCNT1L=0x00;    //定时值清零;      
Lcardbytein[data++]=t_value; 
if(data>=150){ 
while(1); 
} 
    
t_value=0;  
GICR|=0x40;    
*/ 
GICR&=0xbf; 
if(TCCR1B==0x00){  
        TCNT1H=0x00;TCNT1L=0x00; 
        TCCR1B=0x02; 
        t_value=0;  
        GICR|=0x40;  
        header_data=0; 
        data=0;  
        header_data|=0x0001;  
        f_pr=1; 
        header_data_count=1;     
        parity=0; 
        return; 
}    
else{    
t_value=TCNT1;  
TCNT1H=0x00;TCNT1L=0x00; 
header_data<<=1;                  //这里先移,数据是0x03fe              
      
     if(header_data_count<9){      //处理数据头  
        if(t_value>999){           //表示数据为三个:101 
            header_data_count=1; 
            header_data=0; 
            header_data|=0x0001;    
            f_pr=1; 
            goto end; 
        }    
        else if(t_value>730){ 
            if(f_pr==1){             //数据0 
               header_data_count=0;  
               header_data=0; 
               f_pr=0; 
            } 
            else{                   //数据1 
               header_data_count=1;  
               header_data=0; 
               header_data|=0x0001;     
               f_pr=1; 
            } 
            goto end; 
        }          
        else if(t_value>480){  
           if(f_pr==1){           //数据1 
              header_data|=0x0001; 
              header_data_count++;  
              f_pr=1; 
              f_cyc=1;       
           } 
           else{                   //数据0 
               header_data_count=0;  
               header_data=0; 
               f_pr=0;            
           } 
            goto end; 
        } 
        else{ 
            header_data_count=0;    
            TCCR1B=0x00;  
            goto end; 
        } 
     }  
     else{                       //数据头处理过了,这里是数据         
        rbit<<=1;     
        if(t_value>1180){ 
            all_parameter_init(); 
            return; 
        } 
        if(t_value<480){ 
            all_parameter_init(); 
            return; 
        } 
        if(t_value>999){ 
           if(f_pr){ 
                rbit&=0xfe; 
                rbit<<=1; 
                rbit|=0x01;  
                cyc+=2;    
                f_pr=1; 
                f_cyc=1;  
                goto data_dw; 
           } 
           else{ 
                all_parameter_init(); 
                return;            
           }  
                  
        }     
        else if(t_value>730){  
           if(f_pr){ 
              rbit&=0xfe; 
              f_pr=0; 
              cyc++; 
           } 
           else{ 
              rbit&=0xfe; 
              rbit<<=1; 
              rbit|=0x01;  
              cyc+=2;    
              f_pr=1;            
           }    
           goto data_dw;  
        } 
        else if(t_value>480){ 
           if(f_pr){ 
              rbit|=0x01; 
              cyc++; 
           } 
           else{ 
              rbit&=0xfe; 
              cyc++;           
           } 
        }     
data_dw: 
 
        if(cyc>=5){    
           if(cyc==6){//cyc有可能在之前增加的时候超过5; 这里是取校验位 
             cardbytein[data]=(rbit>>1); 
           } 
           else{ 
             cardbytein[data]=rbit; 
           }  
           parity=(((cardbytein[data]&0x10)>>4)+((cardbytein[data]&0x08)>>3)+((cardbytein[data]&0x04)>>2)+((cardbytein[data]&0x02)>>1));    
           if((parity&0x01)==(cardbytein[data]&0x01)){//cyc有可能在之前增加的时候超过5; 不取校验位 
                if(cyc==6){ 
                        cyc=1; 
                        cardbytein[data]=(rbit>>2); 
                        if(rbit&0x01){rbit=0x01;} 
                        else rbit=0x00; 
                } 
                else{ 
                        cardbytein[data]=rbit>>1; 
                        rbit=0x00;    
                        cyc=0; 
                }                 
               data++; 
           } 
           else{  
                all_parameter_init(); 
                return; 
           }    
                     
           if(data>9){//测试    
                _set(global_flag,_CARD_DATA);  
                return; 
           } 
        } 
         
     }  
end:      
t_value=0;  
GICR|=0x40;  
} 
} 
// Timer 1 overflow interrupt service routine 
interrupt [TIM1_OVF] void timer1_ovf_isr(void) 
{  
if(_flag(global_flag,_CARD_DATA)){  
PORTA^=0X01;                      
}     
TCNT1H=0x00; 
TCNT1L=0x00; 
TCCR1B=0X00; 
// Place your code here 
} 
// Declare your global variables here 
void main(void) 
{ 
// Declare your local variables here 
// Input/Output Ports initialization 
// Port A initialization 
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T  
PORTA=0x00; 
DDRA=0xff; 
// Port B initialization 
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T  
PORTB=0x00; 
DDRB=0x00; 
// Port C initialization 
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T  
PORTC=0x00; 
DDRC=0x00; 
// Port D initialization 
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In  
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T  
PORTD=0x04; 
DDRD=0x00; 
// Timer/Counter 0 initialization 
// Clock source: System Clock 
// Clock value: Timer 0 Stopped 
// Mode: Normal top=FFh 
// OC0 output: Disconnected 
TCCR0=0x00; 
TCNT0=0x00; 
OCR0=0x00; 
// Timer/Counter 1 initialization 
// Clock source: System Clock 
// Clock value: 1000.000 kHz 
// Mode: Normal top=FFFFh 
// OC1A output: Discon. 
// OC1B output: Discon. 
// Noise Canceler: Off 
// Input Capture on Falling Edge 
// Timer 1 Overflow Interrupt: On 
// Input Capture Interrupt: Off 
// Compare A Match Interrupt: Off 
// Compare B Match Interrupt: Off 
TCCR1A=0x00; 
TCCR1B=0x00;//TCCR1B=0x02; 
TCNT1H=0x00; 
TCNT1L=0x00; 
ICR1H=0x00; 
ICR1L=0x00; 
OCR1AH=0x00; 
OCR1AL=0x00; 
OCR1BH=0x00; 
OCR1BL=0x00; 
// Timer/Counter 2 initialization 
// Clock source: System Clock 
// Clock value: Timer 2 Stopped 
// Mode: Normal top=FFh 
// OC2 output: Disconnected 
ASSR=0x00; 
TCCR2=0x00; 
TCNT2=0x00; 
OCR2=0x00; 
/* 
// External Interrupt(s) initialization 
// INT0: On 
// INT0 Mode: Any change 
// INT1: Off 
// INT2: Off 
GICR|=0x40; 
MCUCR=0x01; 
MCUCSR=0x00; 
GIFR=0x40; 
*/ 
// External Interrupt(s) initialization 
// INT0: On 
// INT0 Mode: Falling Edge 
// INT1: Off 
// INT2: Off 
GICR|=0x40; 
MCUCR=0x02; 
MCUCSR=0x00; 
GIFR=0x40; 
// Timer(s)/Counter(s) Interrupt(s) initialization 
TIMSK=0x04; 
// USART initialization 
// Communication Parameters: 8 Data, 1 Stop, No Parity 
// USART Receiver: Off 
// USART Transmitter: On 
// USART Mode: Asynchronous 
// USART Baud rate: 9600 
UCSRA=0x00; 
UCSRB=0x48; 
UCSRC=0x86; 
UBRRH=0x00; 
UBRRL=0x33; 
// Analog Comparator initialization 
// Analog Comparator: Off 
// Analog Comparator Input Capture by Timer/Counter 1: Off 
ACSR=0x80; 
SFIOR=0x00; 
// Global enable interrupts 
#asm("sei") 
putchar('d'); 
while (1) 
      { 
      // Place your code here  
         if(_flag(global_flag,_CARD_DATA)){  
                UCSRA=0x00; 
                UCSRB=0x48; 
                UCSRC=0x86; 
                UBRRH=0x00; 
                UBRRL=0x33;          
             for(data=0;data<10;data++){      
                 putchar(cardbytein[data]); 
             } 
             _clr(global_flag,_CARD_DATA); 
             all_parameter_init(); 
         } 
      }; 
}