標(biāo)題:
求助按鍵計數(shù)+無線傳輸計數(shù)值和按鍵時間間隔+超時未按鍵計數(shù)
[打印本頁]
作者:
Proteus111
時間:
2020-1-6 15:06
標(biāo)題:
求助按鍵計數(shù)+無線傳輸計數(shù)值和按鍵時間間隔+超時未按鍵計數(shù)
#include<reg52.h>
#include<intrins.h>
#define uint unsigned int //常用數(shù)據(jù)預(yù)定義
#define uchar unsigned char
sfr T2MOD=0xc9;
sbit K1=P3^2; //按鍵中斷輸入
sbit beep=P1^0; //蜂鳴器 低電平觸發(fā)
sbit relay=P1^7; //繼電器 低電平觸發(fā)
uint t0,t1,t2; //定時器計數(shù)標(biāo)志位
uint time,result; //存儲種莖間隔
double ti;
uint alarm; //定時器0計數(shù)個數(shù)設(shè)置
sbit rs=P1^4;
sbit rw=P1^5;
sbit en=P1^6;
uchar busy;
uchar table0[]="OFF l_num: ";
uchar table1[]="s_num: ";
uchar TempBuffer1[10],TempBuffer2[10];
uchar KeyValue=0;
unsigned long int num1=0,num2=0;
uchar flag=0; //啟動標(biāo)志位
sbit NRF_CE = P1^1;
sbit NRF_CSN = P1^2;
sbit NRF_MISO = P3^6;
sbit NRF_MOSI = P3^5;
sbit NRF_SCK = P3^4;
sbit NRF_IRQ = P3^7;
uchar rece_buf[32];
/********** NRF24L01寄存器操作命令 ***********/
#define READ_REG 0x00 //讀配置寄存器,低5位為寄存器地址
#define WRITE_REG 0x20 //寫配置寄存器,低5位為寄存器地址
#define RD_RX_PLOAD 0x61 //讀RX有效數(shù)據(jù),1~32字節(jié)
#define WR_TX_PLOAD 0xA0 //寫TX有效數(shù)據(jù),1~32字節(jié)
#define FLUSH_TX 0xE1 //清除TX FIFO寄存器.發(fā)射模式下用
#define FLUSH_RX 0xE2 //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL 0xE3 //重新使用上一包數(shù)據(jù),CE為高,數(shù)據(jù)包被不斷發(fā)送.
#define NOP 0xFF //空操作,可以用來讀狀態(tài)寄存器
/********** NRF24L01寄存器地址 *************/
#define CONFIG 0x00 //配置寄存器地址
#define EN_AA 0x01 //使能自動應(yīng)答功能
#define EN_RXADDR 0x02 //接收地址允許
#define SETUP_AW 0x03 //設(shè)置地址寬度(所有數(shù)據(jù)通道)
#define SETUP_RETR 0x04 //建立自動重發(fā)
#define RF_CH 0x05 //RF通道
#define RF_SETUP 0x06 //RF寄存器
#define STATUS 0x07 //狀態(tài)寄存器
#define OBSERVE_TX 0x08 // 發(fā)送檢測寄存器
#define CD 0x09 // 載波檢測寄存器
#define RX_ADDR_P0 0x0A // 數(shù)據(jù)通道0接收地址
#define RX_ADDR_P1 0x0B // 數(shù)據(jù)通道1接收地址
#define RX_ADDR_P2 0x0C // 數(shù)據(jù)通道2接收地址
#define RX_ADDR_P3 0x0D // 數(shù)據(jù)通道3接收地址
#define RX_ADDR_P4 0x0E // 數(shù)據(jù)通道4接收地址
#define RX_ADDR_P5 0x0F // 數(shù)據(jù)通道5接收地址
#define TX_ADDR 0x10 // 發(fā)送地址寄存器
#define RX_PW_P0 0x11 // 接收數(shù)據(jù)通道0有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P1 0x12 // 接收數(shù)據(jù)通道1有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P2 0x13 // 接收數(shù)據(jù)通道2有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P3 0x14 // 接收數(shù)據(jù)通道3有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P4 0x15 // 接收數(shù)據(jù)通道4有效數(shù)據(jù)寬度(1~32字節(jié))
#define RX_PW_P5 0x16 // 接收數(shù)據(jù)通道5有效數(shù)據(jù)寬度(1~32字節(jié))
#define FIFO_STATUS 0x17 // FIFO狀態(tài)寄存器
/*————————————————————————————————————————————————————————————————————*/
/****** STATUS寄存器bit位定義 *******/
#define MAX_TX 0x10 //達(dá)到最大發(fā)送次數(shù)中斷
#define TX_OK 0x20 //TX發(fā)送完成中斷
#define RX_OK 0x40 //接收到數(shù)據(jù)中斷
/*——————————————————————————————————————————————————*/
/********* 24L01發(fā)送接收數(shù)據(jù)寬度定義 ***********/
#define TX_ADR_WIDTH 5 //5字節(jié)地址寬度
#define RX_ADR_WIDTH 5 //5字節(jié)地址寬度
#define TX_PLOAD_WIDTH 32 //32字節(jié)有效數(shù)據(jù)寬度
#define RX_PLOAD_WIDTH 32 //32字節(jié)有效數(shù)據(jù)寬度
const uchar TX_ADDRESS[TX_ADR_WIDTH]={0xFF,0xFF,0xFF,0xFF,0xFF}; //發(fā)送地址
const uchar RX_ADDRESS[RX_ADR_WIDTH]={0xFF,0xFF,0xFF,0xFF,0xFF}; //發(fā)送地址
void delay_us(uchar num)
{
uchar i;
for(i=0;i>num;i++)
_nop_();
}
void delay_150us()
{
uint i;
for(i=0;i>150;i++);
}
void delay(uint t)
{
uchar k;
while(t--)
for(k=0;k<200;k++);
}
/***************************************************************/
/*******************************************************************/
uchar SPI_RW(uchar byte)
{
uchar bit_ctr;
for(bit_ctr=0;bit_ctr<8;bit_ctr++) // 輸出8位
{
NRF_MOSI=(byte&0x80); // MSB TO MOSI
byte=(byte<<1); // shift next bit to MSB
NRF_SCK=1;
byte|=NRF_MISO; // capture current MISO bit
NRF_SCK=0;
}
return byte;
}
/*********************************************/
/* 函數(shù)功能:給24L01的寄存器寫值(一個字節(jié)) */
/* 入口參數(shù):reg 要寫的寄存器地址 */
/* value 給寄存器寫的值 */
/* 出口參數(shù):status 狀態(tài)值 */
/*********************************************/
uchar NRF24L01_Write_Reg(uchar reg,uchar value)
{
uchar status;
NRF_CSN=0; //CSN=0;
status = SPI_RW(reg); //發(fā)送寄存器地址,并讀取狀態(tài)值
SPI_RW(value);
NRF_CSN=1; //CSN=1;
return status;
}
/*************************************************/
/* 函數(shù)功能:讀24L01的寄存器值 (一個字節(jié)) */
/* 入口參數(shù):reg 要讀的寄存器地址 */
/* 出口參數(shù):value 讀出寄存器的值 */
/*************************************************/
uchar NRF24L01_Read_Reg(uchar reg)
{
uchar value;
NRF_CSN=0; //CSN=0;
SPI_RW(reg); //發(fā)送寄存器值(位置),并讀取狀態(tài)值
value = SPI_RW(NOP);
NRF_CSN=1; //CSN=1;
return value;
}
/*********************************************/
/* 函數(shù)功能:讀24L01的寄存器值(多個字節(jié)) */
/* 入口參數(shù):reg 寄存器地址 */
/* *pBuf 讀出寄存器值的存放數(shù)組 */
/* len 數(shù)組字節(jié)長度 */
/* 出口參數(shù):status 狀態(tài)值 */
/*********************************************/
uchar NRF24L01_Read_Buf(uchar reg,uchar *pBuf,uchar len)
{
uchar status,u8_ctr;
NRF_CSN=0; //CSN=0
status=SPI_RW(reg); //發(fā)送寄存器地址,并讀取狀態(tài)值
for(u8_ctr=0;u8_ctr<len;u8_ctr++)
pBuf[u8_ctr]=SPI_RW(0XFF); //讀出數(shù)據(jù)
NRF_CSN=1; //CSN=1
return status; //返回讀到的狀態(tài)值
}
/**********************************************/
/* 函數(shù)功能:給24L01的寄存器寫值(多個字節(jié)) */
/* 入口參數(shù):reg 要寫的寄存器地址 */
/* *pBuf 值的存放數(shù)組 */
/* len 數(shù)組字節(jié)長度 */
/**********************************************/
uchar NRF24L01_Write_Buf(uchar reg, uchar *pBuf, uchar len)
{
uchar status,u8_ctr;
NRF_CSN=0;
status = SPI_RW(reg); //發(fā)送寄存器值(位置),并讀取狀態(tài)值
for(u8_ctr=0; u8_ctr<len; u8_ctr++)
SPI_RW(*pBuf++); //寫入數(shù)據(jù)
NRF_CSN=1;
return status; //返回讀到的狀態(tài)值
}
/*********************************************/
/* 函數(shù)功能:24L01接收數(shù)據(jù) */
/* 入口參數(shù):rxbuf 接收數(shù)據(jù)數(shù)組 */
/* 返回值: 0 成功收到數(shù)據(jù) */
/* 1 沒有收到數(shù)據(jù) */
/*********************************************/
uchar NRF24L01_RxPacket(uchar *rxbuf)
{
uchar state;
state=NRF24L01_Read_Reg(STATUS); //讀取狀態(tài)寄存器的值
NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中斷標(biāo)志
if(state&RX_OK) //接收到數(shù)據(jù)
{
NRF_CE = 0;
NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//讀取數(shù)據(jù)
NRF24L01_Write_Reg(FLUSH_RX,0xff); //清除RX FIFO寄存器
NRF_CE = 1;
delay_150us();
return 0;
}
return 1;//沒收到任何數(shù)據(jù)
}
/**********************************************/
/* 函數(shù)功能:設(shè)置24L01為發(fā)送模式 */
/* 入口參數(shù):txbuf 發(fā)送數(shù)據(jù)數(shù)組 */
/* 返回值; 0x10 達(dá)到最大重發(fā)次數(shù),發(fā)送失敗*/
/* 0x20 成功發(fā)送完成 */
/* 0xff 發(fā)送失敗 */
/**********************************************/
uchar NRF24L01_TxPacket(uchar *txbuf)
{
uchar state;
NRF_CE=0; //CE拉低,使能24L01配置
NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH); //寫數(shù)據(jù)到TX BUF 32個字節(jié)
NRF_CE=1; //CE置高,使能發(fā)送
while(NRF_IRQ==1); //等待發(fā)送完成
state=NRF24L01_Read_Reg(STATUS); //讀取狀態(tài)寄存器的值
NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中斷標(biāo)志
if(state&MAX_TX) //達(dá)到最大重發(fā)次數(shù)
{
NRF24L01_Write_Reg(FLUSH_TX,0xff); //清除TX FIFO寄存器
return MAX_TX;
}
if(state&TX_OK) //發(fā)送完成
{
return TX_OK;
}
return 0xff; //發(fā)送失敗
}
/********************************************/
/* 函數(shù)功能:檢測24L01是否存在 */
/* 返回值; 0 存在 */
/* 1 不存在 */
/********************************************/
uchar NRF24L01_Check(void)
{
uchar check_in_buf[5]={0x11,0x22,0x33,0x44,0x55};
uchar check_out_buf[5]={0x00};
NRF_SCK=0;
NRF_CSN=1;
NRF_CE=0;
NRF24L01_Write_Buf(WRITE_REG+TX_ADDR, check_in_buf, 5);
NRF24L01_Read_Buf(READ_REG+TX_ADDR, check_out_buf, 5);
if((check_out_buf[0] == 0x11)&&\
(check_out_buf[1] == 0x22)&&\
(check_out_buf[2] == 0x33)&&\
(check_out_buf[3] == 0x44)&&\
(check_out_buf[4] == 0x55))return 0;
else return 1;
}
void NRF24L01_RT_Init(void)
{
NRF_CE=0;
NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//選擇通道0的有效數(shù)據(jù)寬度
NRF24L01_Write_Reg(FLUSH_RX,0xff); //清除RX FIFO寄存器
NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(uchar*)TX_ADDRESS,TX_ADR_WIDTH);//寫TX節(jié)點(diǎn)地址
NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(uchar*)RX_ADDRESS,RX_ADR_WIDTH); //設(shè)置TX節(jié)點(diǎn)地址,主要為了使能ACK
NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01); //使能通道0的自動應(yīng)答
NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址
NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//設(shè)置自動重發(fā)間隔時間:500us + 86us;最大自動重發(fā)次數(shù):10次
NRF24L01_Write_Reg(WRITE_REG+RF_CH,0); //設(shè)置RF通道為2.400GHz 頻率=2.4+0GHz
NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0F); //設(shè)置TX發(fā)射參數(shù),0db增益,2Mbps,低噪聲增益開啟
NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0f); //配置基本工作模式的參數(shù);PWR_UP,EN_CRC,16BIT_CRC,接收模式,開啟所有中斷
NRF_CE=1; //CE置高,使能發(fā)送
}
void SEND_BUF(uchar *buf)
{
NRF_CE=0;
NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e);
NRF_CE=1;
delay_us(15);
NRF24L01_TxPacket(buf);
NRF_CE=0;
NRF24L01_Write_Reg(WRITE_REG+CONFIG, 0x0f);
NRF_CE=1;
}
//****************************************************************************//
//********************************LCD1602*************************************//
void delay_1ms()
{
uchar i,j;
for(i=0;i<10;i++)
for(j=0;j<20;j++);
}
void busy_1602()
{
do
{
en=0;
rw=1;
rs=0;
en=1;
busy=P0;
en=0;
delay_1ms();
}while(busy&&0x10==1);
}
void lcd_wcom(uchar com)
{
busy_1602();
en=0;
rs=0;
rw=0;
en=1;
P0=com;
en=0;
}
void lcd_wdat(uchar dat)
{
busy_1602();
en=0;
rs=1;
rw=0;
en=1;
P0=dat;
en=0;
}
void lcd_init()
{
lcd_wcom(0x38); //8位數(shù)據(jù),雙列,5*7字形
lcd_wcom(0x0c); //開啟顯示屏,關(guān)光標(biāo),光標(biāo)不閃爍
lcd_wcom(0x06); //顯示地址遞增,即寫一個數(shù)據(jù)后,顯示位置右移一位
lcd_wcom(0x01); //清屏
}
//整型轉(zhuǎn)換為字符串,便于傳輸
void IntToStr(unsigned long int t, uchar *str, char n)
{
uchar a[10];
char i, j;
a[0]=(t/1000000000)%10; //取得整數(shù)值到數(shù)組
a[1]=(t/100000000)%10;
a[2]=(t/10000000)%10;
a[3]=(t/1000000)%10;
a[4]=(t/100000)%10;
a[5]=(t/10000)%10;
a[6]=(t/1000)%10;
a[7]=(t/100)%10;
a[8]=(t/10)%10;
a[9]=(t/1)%10;
for(i=0; i<10; i++) //轉(zhuǎn)成ASCII碼
a[i]=a[i]+'0';
for(i=0; a[i]=='0' && i<=8; i++);
for(j=10-n; j<i; j++) //填充空格
{ *str=' '; str++; }
for(; i<10; i++)
{ *str=a[i]; str++; } //加入有效的數(shù)字
}
void lcd_wstr(uchar *s) //寫字符串子程序,輸入:*s
{
while(*s>0)
{
lcd_wdat(*s);
s++;
}
}
//**************************************************************************//
//*************************初始化、中斷函數(shù)*********************************//
void IntConfiguration()
{
//設(shè)置INT0
IT0=1 ; //下降沿觸發(fā)
EX0=1; //打開INT0的中斷允許
//設(shè)置定時器
TMOD=0x03; //定時器0工作方式3
TH0=6; //定時器0計數(shù)250次,為271.275us
TL0=6;
ET0=1; //開定時器0中斷
ET1=1; //開定時器1中斷
EA=1; //打開總中斷
T2CON=0x00; //實(shí)現(xiàn)16位自動重載定時
TCLK=0;
RCLK=0;
T2MOD=0x00;
RCAP2H=0x30;
RCAP2L=0xb0;
TL2=0x00;
TH2=0x4c;
ET2=1;
}
void Int0() interrupt 0 //外部中斷0的中斷函數(shù)
{
delay_1ms();
if(K1==0)
KeyValue=1;
}
void TL0_time() interrupt 1 //定時器0中斷函數(shù)
{
TL0=6;
t0++;
}
void TH0_time() interrupt 3 //定時器0中斷函數(shù)
{
TH0=6;
t1++;
if(t1==alarm) //標(biāo)記長度合格
{
beep=1;
relay=1;
TR1=0; //關(guān)閉定時器T01
TH0=6;
t1=0;
}
}
void timer2() interrupt 5
{
TF2=0;
t2++;
}
//**************************主函數(shù)*****************************************//
void main()
{
uchar i;
while(NRF24L01_Check()); // 等待檢測到NRF24L01,程序才會向下執(zhí)行
NRF24L01_RT_Init();
lcd_init();
lcd_wcom(0x80); //寫指令
lcd_wstr(table0);
lcd_wcom(0xc0);
lcd_wstr(table1);
IntConfiguration();
if(NRF_IRQ==0) // 如果無線模塊接收到數(shù)據(jù)
{
if(NRF24L01_RxPacket(rece_buf)==0)
{
if( rece_buf[1]=='1') //第1位以后是收到的命令數(shù)據(jù),rece_buf[0]是數(shù)據(jù)位數(shù)長度
{ flag=1;
lcd_wcom(0x80);
lcd_wstr("ON l_num: ");
alarm=(rece_buf[2]+rece_buf[3]*0.1)*3686; //rece_buf[2]、[3]表示計時長度
}
if( rece_buf[1]=='2') //第1位以后是收到的命令數(shù)據(jù),rece_buf[0]是數(shù)據(jù)位數(shù)長度
flag=0;
}
}
if(flag)
{
while(1)
{
if(KeyValue)
{
TR0=0; //關(guān)閉定時器T00
TR2=0;
TL0=6;
t0=0;
while((i<50)&&(K1==0)) //判斷種莖是否離開
{
delay(1); //延時200us
i++;
}
TR0=1; //待種莖離開,開啟定時器T00
KeyValue=0;
num1++;
IntToStr(num1,&TempBuffer1[0],10);
for(i=1;i<=10;i++)
{
rece_buf[i]=TempBuffer1[i-1];
}
rece_buf[0]=10;
SEND_BUF(rece_buf);
IntToStr(num2,&TempBuffer1[0],10);
for(i=1;i<=10;i++)
{
rece_buf[i]=TempBuffer1[i-1];
}
rece_buf[0]=10;
SEND_BUF(rece_buf);
time=TH2*256+TL2;
ti=time*0.001085+t2*50;
result=(int)ti;
IntToStr(result,&TempBuffer2[0],10);
for(i=1;i<=10;i++)
{
rece_buf[i]=TempBuffer2[i-1];
}
rece_buf[0]=10;
SEND_BUF(rece_buf);
}
else
{
TR2=1;
if(t0==alarm)
{
beep=0;
relay=0;
TR1=1;
num2++;
}
}
}
}
}
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1