⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 一个无线收发程序,使用megal8进行无线收发,定义了无线收发的协议
💻 C
字号:
#include <iom8v.h>
#include "VARTYPEDEF.H"
#include "var.h"
#include "varextern.h"
#include "configure.h"
#include "CC1020.h"
#include <STDLIB.h>

/*
void EEPROM_write(uint uiAddress, uchar ucData)
{
    while(EECR & (1<<EEWE));    //等待上一次写操作结束 
    EEAR = uiAddress;           // 设置地址和数据寄存器
    EEDR = ucData;
    EECR |= (1<<EEMWE);         // 置位EEMWE 
    EECR |= (1<<EEWE);          // 置位EEWE 以启动写操作
}

uchar EEPROM_read(uint uiAddress)
{
    while(EECR & (1<<EEWE));    // 等待上一次写操作结束 
    EEAR = uiAddress;           // 设置地址寄存器
    EECR |= (1<<EERE);          // 设置EERE 以启动读操作
    return EEDR;                // 自数据寄存器返回数据 
}
*/



//系统初始状态的初始化
void SysInit(void)
{
	//DDRB=0;DDRC=0;DDRD=0;
//    DDRB|=0X06;PORTB=0X06;
    DDRD |= 0X18; PORTD &= ~0X18 ;//设置灯和峰鸣器控制口为输出,初始情况下控制峰鸣器和灯不响不亮
//	DDRC=BIT5;//RS485输出
	DDRC &= ~0x02;//PC1为输入
	uart0_init();				  //波特率为19200BPS/4=4800bps/s 	
    initUART_REC(0);              //串口接收变量初始化    
	CLRBIT(DDRB,BIT2);            //设置LOCK引脚的方向为输入	      
    Ini_SPI();                    //配置CC1020的SPI接口线模式 
	REC.command=CMD_FREE;
	TXD.ups=0;
	TXD.rps=0;
	//AD的操作
    ADCSRA = 0XE2;//4分频、自由转换模式,启动AD转换器
	ADMUX = 0XC1;//选中ADC1通道,参考电压2.56V
}


void ChangetoRFTX(void)
{   uint i;
	if (SetupCC1020TX(TXANALOG,PA_POWER)!=LOCK_NOK){
       	REC.Step=0;
       	TXD.Header1=0;  	      
        MCUCR  = 0x03;				             //发送时,在上升沿把数据发到DIO上
        GICR   = 0x40;				             //enable INT0 外部中断 通用中断控制寄存器
        SETBIT(DDR_DIO_OUT,DIO_OUT);     	   	 //PD7--DIO设置为输出,PD2--DCLK设置为输入
        CLRBIT(PIN_DIO_IN,DIO_OUT);     	   	 //PD7--DIO设置为输出,PD2--DCLK设置为输入
       	State = TXSTATE;
       	NextState=TXSTATE;
       	REC.RF_bitnum=0;
	}else{
		ChangetoRFRX();
	}
}
	
void ChangetoRFRX(void)
{   
	if (SetupCC1020RX(RXANALOG,PA_POWER)!=LOCK_NOK){
    	TXD.Step=0; 		   	      
        CLRBIT(DDR_DIO_IN,DIO_IN);     //PD7--DIO设置为输入,PD2--DCLK设置为输入  	
        MCUCR = 0x02;				     //接收时,在下降沿从DIO读取数据
        GICR  = 0x40;				     //enable INT0 外部中断 通用中断控制寄存器
    	State = RXSTATE;
    	NextState= RXSTATE;
	}
}


// Configures all the CC1020 registers according to the values stored in EEPROM
void SetupCC1020All(void)
{ 
    //设置MAIN之外的32个寄存器
    uint  counter;
	uchar tmp;
    ulong FreqA,FreqB;

  	for(counter=1; counter<=0x20; counter++){
  	    WriteToCC1020Register(counter, DefConfig[counter]);
		//Send(DefConfig[counter]);
  	}
	PA_POWER=DefConfig[CC1020_PA_POWER];
    TXANALOG=DefConfig[CC1020_ANALOG];
    RXANALOG=TXANALOG;
	//开始频点
	FREQSTART = DefConfig[CC1020_FREQ_2A];
	FREQSTART = (FREQSTART<<8) |DefConfig[CC1020_FREQ_1A];
	FREQSTART = (FREQSTART<<8) |DefConfig[CC1020_FREQ_0A];
	//信道间隔
    FREQDIFF  = DefConfig[CONFIG_GAP1];
	FREQDIFF = (FREQDIFF<<8) |DefConfig[CONFIG_GAP0];

    //根据跳线值设置频点

	if (WP_STATE){//如果是工作模式
	    tmp=i2c_read(0);//从EEPROM中读取数据
		if (tmp>16) tmp=1;
	}else{
		tmp=0;
	}

    GICR  = 0x00;          //关闲INT0中断
    FreqA = FREQSTART + tmp*FREQDIFF;
	//FreqA = FeqConfig[tmp];
	FreqB = FreqA +0XAAA;
	//配置频率字A
	WriteToCC1020Register(CC1020_FREQ_0A, FreqA);
	FreqA>>=8;	WriteToCC1020Register(CC1020_FREQ_1A, FreqA);
	FreqA>>=8;	WriteToCC1020Register(CC1020_FREQ_2A, FreqA);
	//配置频率字b
	WriteToCC1020Register(CC1020_FREQ_0B, FreqB);
	FreqB>>=8;	WriteToCC1020Register(CC1020_FREQ_1B, FreqB);
	FreqB>>=8;	WriteToCC1020Register(CC1020_FREQ_2B, FreqB);
	WriteToCC1020Register(CC1020_PA_POWER, PA_POWER);
    GICR  = 0x40;          //打开INT0中断
}

//延时
void delay(uint a )
{   uint i,j;
	for ( i=0;i<a;i++)
	    for ( j=0;j<100;j++);    
}

//延时
//void delay1(uint a)
//{   uint i,j;
//	for ( i=0;i<a;i++);   
//}

void InitCC1020(void)
{
	SetupCC1020PD();
    ResetCC1020();
    SetupCC1020All();
   	WakeUpCC1020ToTX(TXANALOG);      //唤醒TX成功
    CalibrateCC1020(PA_POWER);       //校准完成 
    WakeUpCC1020ToRX(RXANALOG);		 //唤醒RX成功
    CalibrateCC1020(PA_POWER);       //校准完成 
	GICR=0;
}
uchar ReadPowerStatus()
{
    uint compare;
	compare = (ADCH<<8) + ADCL ;
	//Send(compare>>8);
	//Send(compare);
	
	if(compare < 0x28F)
	    return 1 ;
    return 0;
}
uchar SetFrequentResult()
{
    if ( (i2c_read(0)!= (TXD.Buffer[6]+1)) || (TXD.Buffer[6] > 15))
	    return 0 ;
	return 1 ;
}
void RadioTransmitData(void)
{
    uchar temp ,writeepromright = 0;
	uint i;
    REC.ups=0;
	
//	GICR = 0 ;//禁止无线中断
	///////////////////头
	for(i = 0;i<3;i++)
	    EnCode(0xfa);
    EnCode(0x02);
	REC.chksum = 0x01;
	EnCode(0x01);//设备类型
	
	////////////////////返回命令
	EnCode(RETURN_Command);
	REC.chksum += RETURN_Command ;
	
	/////////////////////////标签ID
	for(i=0;i<4;i++)
	{
	    REC.chksum += DefConfig[CONFIG_UID+i];
        EnCode(DefConfig[CONFIG_UID+i]);
	}
	
	///////////////////////如果要读EEPROM数据
	if( SystemCommand == READ_EEPROM || SystemCommand == WRITE_EEPROM){	
    	//EEPROM地址	
    	EnCode( EEPROM_Address>>8 ); //地址高四位
    	REC.chksum += ( (uchar) (EEPROM_Address>>8) ) ;
    	EnCode( EEPROM_Address ) ; //地址低四位
    	REC.chksum += ( (uchar)EEPROM_Address ) ;
    	
    	//EEPROM长度
    	EnCode( EEPROM_Length ); //长度高四位
    	REC.chksum += EEPROM_Length ;
    	
    	for(i=0;i< EEPROM_Length;i++) //EEPROM数据
    	{
    	    temp = i2c_read( EEPROM_Address + i +16 ) ;//16是真实用户数据的存储位置,称为偏移量
			if(SystemCommand == READ_EEPROM){
			    REC.chksum += temp ;
				EnCode(temp) ;
			}else if(SystemCommand == WRITE_EEPROM){
			    if( TXD.Buffer[9+i] != temp )
				{ writeepromright = 1 ; }
			}
    	}
		if(SystemCommand == WRITE_EEPROM)
		{
		    REC.chksum += writeepromright ;
			EnCode( writeepromright ) ;
		}
    }
	if( SystemCommand == SET_FREQUENT )
	{
	    EnCode(SetFrequentResult());
		REC.chksum += SetFrequentResult() ;
	}
	/////////////////测电池值
	if(SystemCommand == READ_UID){
		temp = ReadPowerStatus() ; //Acquire the Power Value which was samplinged by the AD convert 
    	EnCode(temp) ;
    	REC.chksum += temp ;
    }
	
	//写校验
	EnCode(REC.chksum);
	
	/////////数据包尾
	for(i = 0;i<5;i++)//结束
	    EnCode(0xf0);
	//////
	REC.rps=0;REC.Step=0;
			 
}
void main()
{
    uint i=0,j;
	Waittimes=0;
	
	WP_STATE = SET_PIN&SET_STATE;

	REC.SentTimes = 0 ;
    SREG=0;       			       //关所有中断
	WDTCR = 0x00;//关闭WDT
	SysInit();    //系统初始化
	InitI2c();
	InitCC1020();	               //CC1020初始化
	SREG   =(1<<7); //开中断
	
	if (WP_STATE){                     			//如果不是设置模式
   	    timer1_init(0x73,0X61);                 //5S超时
       	TIMSK    |= 0x04;                       //开始超时等待
   	}else{
	    OPENLED;
	}
	ChangetoRFRX(); 
//	timer0_init();
    while (1){
		//ReadPowerStatus();
		SANDSUM=rand();
		if (REC.command == CMD_HEAD){ //接收数据广播
		    RadioTransmitData();
//			if(WP_STATE)
			 REC.command = CMD_WAIT ;
		}else if (REC.command==CMD_WAIT){ //接收了要数据的命令,发送无线数据
			if ( (TIMSK&0X04)==0 && (WP_STATE)){
			    Waittimes = SANDSUM %0X10;//
                timer1_init(TCNT1High,TCNT1Low);//起动定时器1,开始排队计时
				TIMSK    |= 0x04;      //timer1 interrupt sources 
			}else if( !WP_STATE && State== RXSTATE ){//如果是在设置模式,此时已准备好回收数据,则转为发模式
			    ChangetoRFTX() ;
			}
			if (GICR==0){
			    ChangetoRFRX();
			    if (REC.SentTimes==2) REC.command=CMD_ACTI;
				if( !WP_STATE ) REC.command = CMD_FREE ;
			}
   		}else if (REC.command==CMD_TEST){//频点测试
			while (1){
       			if (State==RXSTATE){
    			    ChangetoRFTX();
       			}else{
       		    	ChangetoRFRX();
    			} 
				delay(25000);
				initUART_REC(CMD_TEST);
			}
		}else if (REC.command==CMD_ACK){//已发送完数据,等待关电
			if (WP_STATE){
    			SetupCC1020PD();//关掉CC1020,使其处于省电模式
				OPENLED;
				OPENBEEP;
				REC.command=CMD_ACTI;//进入休眠模式
			}
		}else if (REC.command==CMD_ACTI){//已发送完数据,等待关电  
		    if ( WP_STATE && (TIMSK==0)){
			    timer0_init();
				TIMSK = 0x01; //timer interrupt sources
				GICR=0;
				CLOSE_DDR |= CLOSE_BIT ;            //将与电源控制线引脚,方向改为输出
			}
		}else if( REC.command == CMD_FREE ){
		    //CPU空闲时
			CLOSEBEEP;
		//	i2c_write(1,0xcc);
	//		Send(i2c_read(1));
	//		Send(0xfd);
		}
		if( WP_STATE != (SET_PIN & SET_STATE) )
		{
		    WP_STATE = SET_PIN&SET_STATE ;
			SREG = 0 ;
			WDT_ON(0x18) ;              //看门狗等待0.55秒复位
			while(1) ;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -