📄 main.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 + -