📄 reader.c
字号:
/*---------------------------------------------------------
阅读器的防碰撞的初步程序
---------------------------------------------------------*/
#include<stdio.h>
#include<c8051f020.h>
#define BYTE_BIT0 0X01
#define BYTE_BIT1 0X02
#define BYTE_BIT2 0X04
#define BYTE_BIT3 0X08
#define BYTE_BIT4 0X10
#define BYTE_BIT5 0X20
#define BYTE_BIT6 0X40
#define BYTE_BIT7 0X80
sbit CLK1 =P0^2;
sbit DATA=P0^3;
#define LED_ON 0xE3
#define LED_OFF 0X1c
#define PWR_UP1 0X10
#define PWR_UP0 0XEF
#define CS0 0XF7 //P4.3 1111 0111
#define CS1 0X08 //P4.3 0000 1000
#define CE1 0X04 //P4.2 0000 0100
#define CE0 0XFB //P4.2 1111 1011
#define DR1 0X02 //P4.1 0000 0010
#define DR0 0XFD //P4.1 1111 1101
#define TEST_2 0x8E //MSB D143~D136
#define TEST_1 0x08 // D135~D128
#define TEST_0 0x1C // D127~D120
#define DATA2_W 0x10 //0x10=2 字节 //频道2 发送/接收数据长度(单位:Bit)
#define DATA1_W 0x80 //0x80=16字节 //频道1 发送/接收数据长度(单位:Bit)
#define ADDR2_4 0x00
#define ADDR2_3 0x1c
#define ADDR2_2 0xcc
#define ADDR2_1 0xcc
#define ADDR2_0 0xcc
//频道1 接收地址 (当前模块地址) <- 只使用到频道1
#define ADDR1_4 0x00
#define ADDR1_3 0xcc
#define ADDR1_2 0xcc
#define ADDR1_1 0xcc
#define ADDR1_0 0xcc
#define ADDR_W 0x10 //0x10=2字节 //发送/接收地址宽度(单位:Bit)
#define CRC_L 0x1 //CRC模式 0:8位 1:16位
#define CRC_EN 0x1 //CRC校验 0:禁用 1:启用
#define RX2_EN 0x0 //双频道功能 0:禁用 1:启用
#define CM 0x1 //0:Direct mode 1:ShockBurst mode
#define RFDR_SB 0x0 //传输速率 0:250kbps 1:1Mbps (250kbps比1Mbps传输距离更远)
#define XO_F 0x3 //16M //nRF2401晶振频率
#define RF_PWR 0x3 //信号发射功率
#define RF_CH 0x2 //Channel RF 频率设置
//Channel = 2400MHz + RF_CH * 1.0MHz
#define RXEN 0x0 //0:Tx 1:Rx 阅读器最先处于发送状态;
//<将设置信息组合成每个字节的数据信息,此区域无需修改>
#define RFConfig_Bit0 TEST_2
#define RFConfig_Bit1 TEST_1
#define RFConfig_Bit2 TEST_0
#define RFConfig_Bit3 DATA2_W
#define RFConfig_Bit4 DATA1_W
#define RFConfig_Bit5 ADDR2_4
#define RFConfig_Bit6 ADDR2_3
#define RFConfig_Bit7 ADDR2_2
#define RFConfig_Bit8 ADDR2_1
#define RFConfig_Bit9 ADDR2_0
#define RFConfig_Bit10 ADDR1_4
#define RFConfig_Bit11 ADDR1_3
#define RFConfig_Bit12 ADDR1_2
#define RFConfig_Bit13 ADDR1_1
#define RFConfig_Bit14 ADDR1_0
#define RFConfig_Bit15 (ADDR_W<<2 | CRC_L<<1 | CRC_EN)
#define RFConfig_Bit16 (RX2_EN<<7 | CM<<6 | RFDR_SB<<5| XO_F<<2 |RF_PWR)
#define RFConfig_Bit17 (RF_CH<<1 | RXEN)
//通过宏定义将18字节的寄存器参数按照各个功能分解,以便于参数的调整
unsigned char code nRF2401_Conf[18] ={
RFConfig_Bit0, RFConfig_Bit1, RFConfig_Bit2, RFConfig_Bit3, RFConfig_Bit4,
RFConfig_Bit5, RFConfig_Bit6, RFConfig_Bit7, RFConfig_Bit8, RFConfig_Bit9,
RFConfig_Bit10, RFConfig_Bit11, RFConfig_Bit12, RFConfig_Bit13, RFConfig_Bit14,
RFConfig_Bit15, RFConfig_Bit16, RFConfig_Bit17
};
bdata unsigned char DATA_BUF; //用于ByteRead 和 ByteWrite函数
unsigned char Manchesterbuf[16];
#define DATA7 ((DATA_BUF&BYTE_BIT7) != 0) //判断数据的最高位是否为1
#define DATA0 ((DATA_BUF&BYTE_BIT0) != 0) //判断数据的最低位是否为1
#define SYSCLK 11059200 //系统时钟
#define BAUDRATE 9600 //系统波特率
void Delay100(void)
{
unsigned int i;
for(i=0;i<100;i++);
}
void Delay(void)
{
unsigned int i;
for(i=0;i<10;i++);
}
//系统设置
void SYSCLK_Init(void)
{
int i;
OSCXCN=0x67; //设置系统时钟
for(i=0;i<256;i++);
while(!(OSCXCN&0x80)); //等待外部时钟稳定
OSCICN=0x88;
XBR0=0X04; //设置串口引脚
XBR2=0X40; //交叉IO口使能
P6=P6&LED_ON; //LED灯亮
Delay100();
Delay100();
P6=P6|LED_OFF; //LED灯灭
}
//串口初始化函数
void UART0_Init(void)
{
SCON0=0X50; //方式1,8位UART,允许接收
TMOD=0X20; //定时器1,模式2,8位重装载
TH1=-(SYSCLK/BAUDRATE/16); //根据波特率设置定时器1的重载值;
TR1=1; //启动定时器1;
CKCON|=0X10; //定时器1使用SYSCLK为时基;
PCON|=0X80; //SMOD00=1;
}
//写每一位的数据。
void ByteWrite(unsigned char send)
{
unsigned char i;
DATA_BUF=send;
for (i=0;i<8;i++)
{
CLK1=0;
if (DATA7) //总是发送最高位
{
DATA=1;
}
else
{
DATA=0;
}
Delay();
CLK1=1; // CLK1=1; 0000 0001 P4^0;
Delay();
CLK1=0;
DATA_BUF=DATA_BUF<<1;
}
}
// <2401配置寄存器的写入方式>
void Config2401(void)
{
unsigned int i;
unsigned char variablel;
P4=P4&CS0;
P4=P4&CE0;
CLK1=0;
DATA=0;
P4=P4|PWR_UP1;
for(i=0;i<10;i++)
Delay100();
//从上电到进入配置模式需要3ms的延时
P4=P4|CS1;//使RF2401进入配置方式
Delay100();
for(i=3;i<18;i++)
{
variablel=nRF2401_Conf[i];
ByteWrite(variablel);
}
Delay100();
P4=P4&CS0; //CS置低使配置有效
Delay100();
}
//读每一位的数据;
unsigned char ByteRead(void)
{
unsigned char i;
for (i=0;i<8;i++)
{
DATA_BUF=DATA_BUF<<1;
CLK1=1; //P4=P4|0X01; // CLK1=1; 0000 0001
DATA=1; //设置为输入状态
if (DATA) //读取最高位,保存至最末尾,通过左移位完成整个字节
{
DATA_BUF|=BYTE_BIT0;
}
else
{
DATA_BUF&=~BYTE_BIT0;
}
CLK1=0;
Delay100();
}
return DATA_BUF;
}
//将读出的数据存储在RxBuf;
void nrf2401_Rxpack(unsigned char *RxBuf,unsigned int *x)
{
unsigned int i;
*x=0;
for(i=0;i<DATA1_W/8;i++)
{
*RxBuf=ByteRead();
RxBuf++;
*x=*x+1;
}
}
void SetTxMode(void)
{
//设置为配置模式
unsigned int i;
P4=P4&CS0;
P4=P4&CE0;
CLK1=0;
DATA=0;
P4=P4|PWR_UP1; //先进入空闲模式
for(i=0;i<10;i++)
Delay100();
P4=P4|CS1; //进入配置模式
Delay100();
//配置寄存器0字节RXEN 设置为0:发送模式
CLK1=0;
DATA =0;
Delay();
CLK1=1; // CLK1=1;
Delay();
CLK1=0; //P4=P4&0XFE; //CLK1=0;
P4=P4&CS0; //CS=0;使配置有效
P4=P4|CE1;
Delay100();
Delay100();
Delay100();
}
void SetRxMode(void)
{
unsigned int i;
P4=P4&CS0;
P4=P4&CE0;
CLK1=0;
DATA=0;
P4=P4|PWR_UP1; //进入空闲模式
for(i=0;i<10;i++)
Delay100();
P4=P4|CS1; //进入配置模式
Delay100();
CLK1=0;
DATA =1;
Delay();
CLK1=1; // CLK1=1;
Delay();
CLK1=0; //P4=P4&0XFE; //CLK1=0;
P4=P4&CS0; //CS=0; 4.3 1111 0111;
P4=P4|CE1; //CE=1; 4.2 0000 0100 ??è?·??í??ê?
Delay100();
Delay100();
}
//进行Manchester编码
void Manchester_fun(unsigned char *TxBuf)
{
unsigned char i,k=0;
for (i=0;i<8;i++)
{
if(TxBuf[i]==1)
{
Manchesterbuf[k]=1;
k++;
Manchesterbuf[k]=0;
k++;
}
else
{
Manchesterbuf[k]=0;
k++;
Manchesterbuf[k]=1;
k++;
}
}
}
//接收方通道硬件地址
unsigned char TxAddress[]={0xcc,0xcc,0xcc,0xcc};
//nRF2401数据发送函数
void nRF2401_TxPacket(unsigned char TxBuf[])
{
int i;
unsigned char variable2;
Manchester_fun(TxBuf);
P4=P4|PWR_UP1;
P4=P4&CS0;
P4=P4&CE0; //进入空闲模式
CLK1=0;
DATA=0;
Delay();
P4=P4|CE1; //进入收发模式
Delay100();
for(i=0;i< (ADDR_W/8);i++) //写入接收地址(按字节对齐)
{
variable2=TxAddress[i];
ByteWrite(variable2);
}
for(i=0;i<(DATA1_W/8);i++) //写入需要发送的数据(按字节对齐)
{
variable2=Manchesterbuf[i];
ByteWrite(variable2);
}
P4=P4&CE0; //CE置低使发送有效
Delay100();
Delay100();
}
unsigned int checkconflict_fun(unsigned char *Rxbuf,unsigned char *Readdatabuf)
{
unsigned int i,k;
for(i=0;i<16;i=i+2)
{
if((Rxbuf[i]==1)&&(Rxbuf[i+1]==0))
{
*Readdatabuf=1; //收到的数据是下降沿,即为数据1;
Readdatabuf++;
k++;
}
else if((Rxbuf[i]==0)&&(Rxbuf[i+1]==1))
{
*Readdatabuf=0; //收到的数据是上降沿,即为数据0;
Readdatabuf++;
k++;
}
else
break;
}
return k; //返回碰撞位
}
void main(void)
{
unsigned char Txbuf1[8]={1,1,1,1,1,1,1,1,},Rxbuf[16],Readdatabuf[8];
unsigned char Txbuf2[8]={0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,};
unsigned char Txbuf3[8]={0X0A,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,};
unsigned char Txbuf4[8]={0,1,2,3,4,5,6,7,};
unsigned char Txbuf5[8]={11,20,30,50,10,41,98,75,};
unsigned char send_flag=1,recive_flag=0,LED=0X1C;
unsigned int countbit,k=0,m,n,l;
unsigned int *p=&countbit;
unsigned int over_flag=1,conflict_bit;
unsigned long int i=0;
WDTCN=0xde; // 禁止看门狗定时器
WDTCN=0xad;
SYSCLK_Init(); //初始化CPU;
UART0_Init(); //配置串口
Config2401(); //配置nRF2401;
while(1)
{
i=0;
while(i<100) //发送阶段
{ SetTxMode( );
i++;
P4=P4|CE1;
nRF2401_TxPacket(Txbuf1);
P6=P6&LED_ON; //LED灯亮
}
SetRxMode(); //设置为接收模式
P4=P4|CE1;
P6=P6|LED_OFF;
for(i=0;i<600;i++)
{
for(k=0;k<6000;k++)
{
if((P4&DR1)!=0) //检查是否接收到数据
{
P6=P6|LED_ON;
nrf2401_Rxpack(Rxbuf,p); //接收到数据,读出来
conflict_bit=checkconflict_fun( Rxbuf,Readdatabuf); //检查是否有碰撞,并返回碰撞位
if(conflict_bit<8) //碰撞位小于8
{
Txbuf1[conflict_bit]=0; //把碰撞位置为0
}
else //没有碰撞
{
m=0;
while(m<600)
{ P6=P6|LED_OFF;
SetTxMode( ); //设置为发送模式
m++;
P4=P4|CE1;
nRF2401_TxPacket(Readdatabuf); //发送接收到的标签号作为确认信息
P6=P6&LED_ON;
for(l=0;l<5;l++)
{
Delay100();
}
}
for(l=0;l<8;l++) //向串口写读出的标签号
{
SBUF0=Readdatabuf[l];
while(TI0==0);
TI0=0;
}
for(n=0;n<8;n++) //确认了一个标签号后,进行下一次搜索,把发送的数据改为1111 1111
{
Txbuf1[n]=1;
}
}
recive_flag=1;
break; //接收到了数据就跳出接收数据循环
}
}
if(recive_flag==1)
break; //接收到了数据就跳出接收数据循环
}
recive_flag=0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -