/************************************************************************ * ---- 居加居 ---- * 文件名: Main.c * 编写人员: Kinve JQ * 说明: * 版本: V0.1 * 编写日期: 2018-08-21 * 程序维护: * 维护记录: * 2018-09-30.Kinve:1.创建文件 * 免责声明: * (c) Author Kinve JQ. All rights reserved. **************************************************************************/ #include #include #include "Common.h" #include "Delay.h" #include "Timer.h" #include "Interrupt.h" #include "Flash.h" #include "Version.h" #include "Packdata.h" #include "DHT11.h" #include "Keys.h" #include "Adc.h" #define USE_2401_API #ifdef USE_2401_API #include "nRF24L01_API.h" #else #include "NRF24L01_inte.H" #define TX_PLOAD_WIDTH NRF24L01_TX_PLOAD_LEN #define RX_PLOAD_WIDTH NRF24L01_TX_PLOAD_LEN #endif unsigned char P12_Led_state = 0; unsigned char P04_Delay_state = 0; unsigned char Sys_Type = SysRun_Norm; //*********************************************************************************************************** // Application: SPI Function // Master send 0x90 and recevie 0x4E // Master send 0x01 and recevie 0x55 // Master send 0x02 and recevie 0x56 // Master send 0x03 and recevie 0x4F // Master send 0x04 and recevie 0x54 // // Master recevie 0x4E and 0x4F form slave after transmitting //*********************************************************************************************************** //----------------------------------------------------------------------------------------------------------- void SPI_Error ( void ) { DBG ( "\nSPI error.\n" ); while ( 1 ) // SPI error and P0.7 flash/ { P07 = 1; Timer0_Delay1ms ( 500 ); P07 = 0; Timer0_Delay1ms ( 500 ); } } //----------------------------------------------------------------------------------------------------------- void SPI_Initial ( void ) { clr_SPIEN; //禁止SPI P15_Quasi_Mode; // P15 (SS) Quasi mode P10_Quasi_Mode; // P10(SPCLK) Quasi mode P00_Quasi_Mode; // P00 (MOSI) Quasi mode P01_Quasi_Mode; // P22 (MISO) Quasi mode //SS仅在从机有效 set_DISMODF; // 1 = 禁止模式错误检测. SS的特征依赖SSOE 位 clr_SSOE; // SS 作为 0.普通IO 1.自动拉低 clr_LSBFE; // 0.MSB first clr_CPOL; // 0.SPI空闲时SCL为低 clr_CPHA; // 0.在第1个边沿采样 set_MSTR; // 主设备 //SPICLK_DIV16; // Select SPI clock=1Mhz SPICLK_DIV4; // 16/4=4Mhz, 24l01速度不能太快,最大的数据传输率为 10Mbps set_SPIEN; // 使能SPI clr_SPIF; // 清标志位 } //----------------------------------------------------------------------------------------------------------- void Start_Sending_SPI ( uint8 *pu8MID, uint8 *pu8DID ) { SS = 0; SPDR = 0x90; Timer3_Delay10us ( 1 ); // Send 0x90 to Slave while ( ! ( SPSR & SET_BIT7 ) ); clr_SPIF; if ( SPDR != 0x4E ) SPI_Error(); DBG ( "\nSlave Return %c!\n", SPDR ); SPDR = 0x01; // Send 0x01 to Slave Timer3_Delay10us ( 1 ); while ( ! ( SPSR & SET_BIT7 ) ); clr_SPIF; if ( SPDR != 0x55 ) SPI_Error(); DBG ( "\nSlave Return %c!\n", SPDR ); SPDR = 0x02; // Send 0x02 to Slave Timer3_Delay10us ( 1 ); while ( ! ( SPSR & SET_BIT7 ) ); clr_SPIF; if ( SPDR != 0x56 ) SPI_Error(); DBG ( "\nSlave Return %c!\n", SPDR ); SPDR = 0x03; // Send 0x03 to Slave Timer3_Delay10us ( 1 ); while ( ! ( SPSR & SET_BIT7 ) ); clr_SPIF; if ( SPDR != 0x4F ) SPI_Error(); DBG ( "\nSlave Return %c!\n", SPDR ); SPDR = 0x04; // Send 0x04 to Slave Timer3_Delay10us ( 1 ); while ( ! ( SPSR & SET_BIT7 ) ); clr_SPIF; if ( SPDR != 0x54 ) SPI_Error(); DBG ( "\nSlave Return %c!\n", SPDR ); SPDR = 0xFF; Timer3_Delay10us ( 1 ); while ( ! ( SPSR & SET_BIT7 ) ); clr_SPIF; *pu8MID = SPDR; // Receive Slave 1st DATA from Slave DBG ( "\nSlave Return %c!\n", SPDR ); SPDR = 0xFF; Timer3_Delay10us ( 1 ); while ( ! ( SPSR & SET_BIT7 ) ); clr_SPIF; *pu8DID = SPDR; // Receive Slave 2nd DATA from Slave DBG ( "\nSlave Return %c!\n", SPDR ); SS = 1; } //1.关闭POR (TA 保护) 上电复位(检测电源上升到系统可以工作的电压) #ifdef N76E003_IAR __sfr __no_init volatile unsigned char PORDIS @ 0XFD; #else sfr PORDIS = 0XFD; #endif void CLOSE_POR ( void ) { TA = 0XAA; TA = 0X55; PORDIS = 0X5A; TA = 0XAA; TA = 0X55; PORDIS = 0XA5; } /****************************************************************************** This code illustrates how to do APROM and CONFIG IAP from LDROM. APROM are re-programmed by the code to output P1 as 55h and P0 as aah. The CONFIG2 is also updated to disable BOD reset. User needs to configure CONFIG0 = 0x7F, CONFIG1 = 0xFE, CONFIG2 = 0xFF. ******************************************************************************/ //2.关闭BOD 欠压检测 (监测运行期间VDD电平) #ifdef N76E003_IAR __sfr __no_init volatile unsigned char BODCON0 @ 0XA3; __sfr __no_init volatile unsigned char BODCON1 @ 0XAB; //__sfr __no_init volatile unsigned char CONFIG2 @ 0XFD; #else //sfr BODCON0 = 0XA3; //sfr BODCON1 = 0XAB; #endif void CLOSE_BOD ( void ) { BODCON0 &= ~ ( 1 << 7 ); //0 =禁用欠压检测电路 } enum { UMKNOW_RESET, POWER_ON_RESET, //上电复位 BROWN_OUT_RESET, //欠压复位 RST_PIN_RESET, //RST引脚复位 HARD_FAULT_RESET, //硬件故障复位 WATCHGOD_TIMER_RESET, //看门狗定时器复位 SOFTWARE_RESET, //软件复位 MAX_RESET }; /* RST pin reset Brown-out reset Software reset Power-on reset Watchgod Timer reset Hard Fault reset */ unsigned char Reset_Reason ( void ) { unsigned char res = UMKNOW_RESET; if ( PCON & ( 1 << 4 ) ) { PCON &= ~ ( 1 << 4 ); res = POWER_ON_RESET; } if ( BODCON0 & ( 1 << 1 ) ) { BODCON0 &= ~ ( 1 << 1 ); res = BROWN_OUT_RESET; } if ( AUXR1 & ( 1 << 6 ) ) { AUXR1 &= ~ ( 1 << 6 ); res = RST_PIN_RESET; } if ( AUXR1 & ( 1 << 5 ) ) { AUXR1 &= ~ ( 1 << 5 ); res = HARD_FAULT_RESET; } if ( WDCON & ( 1 << 3 ) ) { WDCON &= ~ ( 1 << 3 ); res = WATCHGOD_TIMER_RESET; } if ( AUXR1 & ( 1 << 7 ) ) { AUXR1 &= ~ ( 1 << 7 ); res = SOFTWARE_RESET; } return res; } void ResetSys ( void ) { AUXR1 &= ~ ( 1 << 7 ); //software reset flag clear EA = 0; TA = 0xAA; TA = 0x55; CHPCON |= ( 1 << 7 ); //software reset } void P12_Flash ( unsigned char num ) { unsigned char i; for ( i = 0; i < num && num < 5 ; i++ ) { P12 = 1; Timer3_Delay100ms ( 1 ); P12 = 0; Timer3_Delay100ms ( 1 ); } P12_Led_state = P12; } #if 0 unsigned char flag; //NRF24L01中断处理 #ifdef N76E003_IAR #pragma vector=0x3B __interrupt void NRF24L01_Handler ( void ) #else void NRF24L01_Handler ( void ) interrupt 7 //interrupt address is 0x001B #endif { clr_EPI; //关闭管脚中断7 flag = PIF; PIF = 0x00; //清除全部标志 DBG ( "\nNRF24L01 interrupt!\n" ); set_EPI; //开启管脚中断7 } void NRF24L01_Interrupt_P03 ( void ) { //P0M1|=SET_BIT3;P0M2&=~SET_BIT3; //input PICON &= ~ ( SET_BIT0 | SET_BIT1 ); PICON |= ( 0x00 ); //[1:0]=0.端口0 PICON |= SET_BIT5; //通道3=1.边沿触发 PINEN |= SET_BIT3; // 1 = 低电平/ 下降沿触发中断 PIPEN &= ~SET_BIT3; //0 = 关闭中断(高电平/ 上升沿触发中断) EIE |= SET_BIT1; //管脚中断,最多8个,中断号7 EA = 1; //总中断 } #endif //96位 UID与128位UCID unsigned char xdata UIDBuf[12]; //本机的存储96bit的UID内容 unsigned char xdata UID_Master[12]; //主机的存储96bit的UID内容 UINT8 UID_BYTE ( UINT8 Addr ) { UINT8 DATATEMP; set_IAPEN; IAPAL = Addr; IAPAH = 0x00; IAPCN = READ_UID; set_IAPGO; DATATEMP = IAPFD; clr_IAPEN; return DATATEMP; } //读出芯片的96bit的UID void ReadUID_UCID ( UINT8 UID, UINT8 *out ) { UINT8 i; for ( i = 0; i < 12; i++ ) { out[i] = UID_BYTE ( i + UID ); //ucid=0x20 } } int Humi,Temp,Light; //printf 用int //最长4byte #define GET_VER_POS(NUM,VER) ((VER>>(8*NUM))&0xff) //----------------------------------------------------------------------------------------------------------- void main ( void ) { unsigned char reset_num, i; //unsigned char datatemp[8]; unsigned char TxBuf[TX_PLOAD_WIDTH] = {'>', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; // unsigned char RxBuf[RX_PLOAD_WIDTH] = {0}; unsigned char PackBuf[TX_PLOAD_WIDTH]; pDataBuff CheckRxBuf = {0}; unsigned char CheckUID = 0; //uint8 u8MID, u8DID; reset_num = Reset_Reason(); CLOSE_POR(); CLOSE_BOD(); Set_All_GPIO_Quasi_Mode; //NRF24L01_Interrupt_P03(); //定时器 Timer0_init ( TIMER_SCAN ); //1ms //ResetSys(); InitialUART0_Timer1 ( 115200 ); /* 115200 Baud Rate*/ Timer3_Delay10us ( 1000 ); DBG ( "\nHome Light %s, Build by Kinve in %ld\n", THIS_VER, CUSTOM_VER ); ReadUID_UCID ( 0x00, UIDBuf ); //0x00=uid 0x20=ucid DBG ( "UID=%x%x%x%x\n", UIDBuf[0], UIDBuf[1], UIDBuf[2], UIDBuf[3] ); #if 0 //call read byte datatemp[5] = Read_APROM_BYTE ( 0x3885 ); if ( datatemp[5] != 0x4A ) { //call write byte for ( i = 0; i < sizeof ( datatemp ); i++ ) { if ( i == 5 ) Write_DATAFLASH_BYTE ( 0x3880 + i, 0x4A ); else Write_DATAFLASH_BYTE ( 0x3880 + i, GET_VER_POS ( i, CUSTOM_VER ) ); datatemp[i] = Read_APROM_BYTE ( ( UINT16 code * ) ( 0x3880 + i ) ); } } #endif for ( i = 0; i < sizeof ( UID_Master ); i++ ) { UID_Master[i] = Read_APROM_BYTE ( ( UINT16 code * ) ( 0x3881 + i ) ); } if(Fast_Check_CS()) { Sys_Type = SysRun_Test; } SPI_Initial(); NRF24L01_Wait_Check(); // 等待检测到NRF24L01,程序才会向下执行 NRF24L01_RT_Init (); DBG ( "NRF24L01 init OK!\n" ); while ( 1 ) { switch(Sys_Type) { case SysRun_Test: if ( System_Flag_500Ms) { System_Flag_500Ms = 0; P12_Led_state = !P12_Led_state; P12 = P12_Led_state; } if(Keys[KEY_CS].Res == ONE_HITS_KEY_FLAG) //本机请求ID { Keys[KEY_CS].Res = NO_KEY_FLAG; memset(TxBuf, 0, sizeof(TxBuf)); TxBuf[0] = '*'; //*(1byte)+?(1byte) TxBuf[1] = '?'; PackData(TxBuf, 2, PackBuf); SEND_BUF ( PackBuf, sizeof(PackBuf) ); DBG ( "Send: %s\n", &PackBuf[2] ); } if(Keys[KEY_CS].Res == LONG_KEY_FLAG) //删除配对ID { Keys[KEY_CS].Res = NO_KEY_FLAG; //保存到flash memset(UID_Master, 0xFF, sizeof(UID_Master)); Write_DATAFLASH_BYTE ( 0x3880, 0xFF ); for ( i = 0; i < sizeof ( UID_Master ); i++ ) { Write_DATAFLASH_BYTE ( 0x3881 + i, UID_Master[i] ); } P12_Flash(4); DBG ( "Clear Pair Num\n" ); } break; case SysRun_Norm: default: if ( System_Flag_1s ) { System_Flag_1s = 0; P12_Led_state = !P12_Led_state; P12 = P12_Led_state; //温湿度获取 DHT11_Read_Data( &DHT11_Data ); Adc_read(); if( abs(Light-Group_Light) > 10 ){ Humi = DHT11_Data.humi_int; Temp = DHT11_Data.temp_int; Light = Group_Light; DBG ( "Humi:%02u%% - Temp:%02uC - Light:%02u\n", Humi, Temp, Light ); } } if(Keys[KEY_CS].Res == ONE_HITS_KEY_FLAG)//配对发 { Keys[KEY_CS].Res = NO_KEY_FLAG; memset(TxBuf, 0, sizeof(TxBuf)); TxBuf[0] = '>'; //*(1byte)+?(1byte) TxBuf[1] = 'L'; //灯 TxBuf[2] = 'T'; //翻转 memcpy(&TxBuf[3], UID_Master, 12); PackData(TxBuf, 15, PackBuf); SEND_BUF ( PackBuf, sizeof(PackBuf) ); DBG ( "Send: %s\n", &PackBuf[2] ); } break; } if ( NRF_IRQ == 0 ) { if ( NRF24L01_RxPacket ( RxBuf, sizeof ( RxBuf ) ) ) { if(CheckData(RxBuf, RX_PLOAD_WIDTH, &CheckRxBuf)){ P12_Flash ( 2 ); DBG ( "Recv: %s\n", &(CheckRxBuf.Data[2]) ); switch(CheckRxBuf.Data[2]){ case '*': //配对 switch(CheckRxBuf.Data[3]){ case '?': //对方收到,发送ID memset(TxBuf, 0, sizeof(TxBuf)); TxBuf[0] = '*'; //*(1byte)+Y(1byte)+uid(12byte) TxBuf[1] = '1'; memcpy(&TxBuf[2], UIDBuf, 12); PackData(TxBuf, 14, PackBuf); SEND_BUF ( PackBuf, sizeof(PackBuf) ); DBG ( "Send: %s\n", &PackBuf[2] ); break; case '1': //本机收到,保存ID memcpy(UID_Master, &CheckRxBuf.Data[4], 12); //保存到flash Write_DATAFLASH_BYTE ( 0x3880, 0x4A ); for ( i = 0; i < sizeof ( UID_Master ); i++ ) { Write_DATAFLASH_BYTE ( 0x3881 + i, UID_Master[i] ); } //返回成功 memset(TxBuf, 0, sizeof(TxBuf)); TxBuf[0] = '*'; //*(1byte)+Y(1byte)+uid(10byte) TxBuf[1] = '2'; PackData(TxBuf, 2, PackBuf); SEND_BUF ( PackBuf, sizeof(PackBuf) ); DBG ( "Send: %s\n", &PackBuf[2] ); DBG ( "Pair Save OK\n" ); break; case '2': //对方收到,我已保存ID DBG ( "One Client Pair OK\n" ); break; } break; case '>': //数据 switch(CheckRxBuf.Data[3]){ case 'L': if(CheckRxBuf.Data[4] == 'T'){ CheckUID = 0; if(0 == memcmp(&(CheckRxBuf.Data[5]), UIDBuf, 12)){ P04_Delay_state = !P04_Delay_state; P04 = P04_Delay_state; CheckUID = 1; } //返回成功 memset(TxBuf, 0, sizeof(TxBuf)); TxBuf[0] = '<'; //*(1byte)+Y(1byte)+uid(10byte) TxBuf[1] = 'L'; TxBuf[2] = 'T'; TxBuf[3] = CheckUID?'Y':'N'; PackData(TxBuf, 4, PackBuf); SEND_BUF ( PackBuf, sizeof(PackBuf) ); DBG ( "Send: %s\n", &PackBuf[2] ); } break; } break; } } } } } } //----------------------------------------------------------------------------------------------------------- /*************** (C) COPYRIGHT Kinve JQ *******END OF FILE **************/