|
调试华普的RFM12BP近一个月了,官方的程序多少有点不靠谱,最后用逻辑分析仪分析官方的演示模块才搞定。可是效果没有官方说的那么完美,最严重的问题就是发送玩一个字节时nIRQ没有产生一个下降沿,从逻辑分析仪的观察来看,nIRQ一直是低电平,接上上拉也无济于事。现在只能靠检测SDO是否被拉高来判断数据是否发送完成,严重消耗单片机资源。有时一上电就在等待SDO拉高中陷入死循环,但如果上电就正常的话,就可以一直工作(想不通啊)。求教各位调过RFM12系列无线模块的高手,问题出在那里?
附上发射和接收的程序,使用stc 1t的单片机模拟spi
发射的
#include <STC_NEW_8051.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit nSEL=P1^4;
sbit SDO=P1^6;
sbit SDI=P1^5;
sbit SCK=P1^7;
sbit LED=P2^7;
sbit nIRQ=P3^3;
bit busy;
void delay_1ms() //1毫秒延时函数
{
uint y;
for(y=900;y>0;y--);
}
void delay_1us() //1微秒延时函数
{
_nop_();
_nop_();
_nop_();
}
void delay_sec(uint z) //毫秒延时
{
while(z--)
{
delay_1ms();
}
}
void Uart_Send(uchar dat) //串口发送
{
while (busy); //Wait for the completion of the previous data is sent
busy = 1;
SBUF = dat; //Send data to UART buffer
}
void Uart_Init(void) //9600bps@12MHz
{
PCON &= 0x7f; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xfe; //串口1选择定时器1为波特率发生器
TMOD &= 0x0f; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xD9; //设定定时初值
TH1 = 0xD9; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
void Uart_Isr() interrupt 4 using 1
{
if (RI)
{
RI = 0; //Clear receive interrupt flag
//P0 = SBUF; //P0 show UART data
//bit9 = RB8; //P2.2 show parity bit
}
if (TI)
{
TI = 0; //Clear transmit interrupt flag
busy = 0; //Clear transmit busy flag
}
}
uint RF12_WRT_CMD(uint cmd) //RF12写入命令
{
uchar i;
uchar temp;
temp=0;
SCK=0;
_nop_();
nSEL=0;
_nop_();
for(i=0;i<16;i++)
{
if(cmd&0x8000)
{
SDI=1;
}
else
{
SDI=0;
}
SCK=1;
delay_1us();
delay_1us();
delay_1us();
delay_1us();
temp<<=1;
if(SDO)
{
temp|=0x0001;
}
SCK=0;
delay_1us();
delay_1us();
delay_1us();
delay_1us();
cmd<<=1;
}
SCK=0;
nSEL=1;
return(temp);
}
void RF12_init() //RF12初始化
{
RF12_WRT_CMD(0x80D8);
RF12_WRT_CMD(0x8209);
RF12_WRT_CMD(0xA640);
RF12_WRT_CMD(0xC647);
RF12_WRT_CMD(0x94C0);
RF12_WRT_CMD(0xC2AC);
RF12_WRT_CMD(0xCA81);
RF12_WRT_CMD(0xCA83);
RF12_WRT_CMD(0x9820);
RF12_WRT_CMD(0xC040);
RF12_WRT_CMD(0xC4B7);
RF12_WRT_CMD(0x8289);
}
uchar RF12_recive() //RF12接收
{
uint date;
RF12_WRT_CMD(0x0000);
date=RF12_WRT_CMD(0xB000);
date=(char)date&0x00FF;
return(date);
}
void wait_SDI() //等待SDI可以拉高以发送下一字节
{ //代替nIRQ
bit RGIT;
Loop:
SCK=0;
nSEL=0;
SDI=0;
SCK=1;
if(SDO) //Polling SDO
{
RGIT=1;
}
else
{
RGIT=0;
}
SCK=0;
SDI=1;
nSEL=1;
if(RGIT==0)
{
goto Loop;
}
else
{
RGIT=0;
}
}
void RF12_send(uchar date) //RF12发送
{
uint temp;
//while(nIRQ);
temp=0xB800|date;
wait_SDI();
RF12_WRT_CMD(temp);
}
void device_init() //设备及中断初始化
{
Uart_Init();
ES=1;
EA=1;
nIRQ=1;
RF12_init();
//nIRQ=1;
delay_sec(500);
}
void main()
{
uchar i,check,date;
device_init();
while(1)
{
RF12_WRT_CMD(0xB8AA);
RF12_WRT_CMD(0xB8AA);
RF12_WRT_CMD(0x8229);
//while(nIRQ);
//delay_1ms();
//delay_1ms();
wait_SDI();
RF12_send(0xAA);
RF12_send(0xAA);
RF12_send(0x2D);
RF12_send(0xD4);
for(i=0;i<16;i++)
{
date=0x30|i;
RF12_send(date);
check+=date;
}
RF12_send(check);
RF12_send(0xAA);
//while(nIRQ);
wait_SDI();
RF12_WRT_CMD(0x8289);
check=0;
LED=0;
delay_sec(500);
LED=1;
delay_sec(500);
}
}
接收的
#include <STC_NEW_8051.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit nSEL=P1^4;
sbit SDO=P1^6;
sbit SDI=P1^5;
sbit SCK=P1^7;
sbit LED=P2^7;
sbit nIRQ=P3^3;
uchar RF12_recive_date[17]; //数据接收缓存区
bit busy;
void delay_1ms() //1ms延时函数
{
uint y;
for(y=900;y>0;y--);
}
void delay_1us(void) //1us延时函数
{
_nop_();
_nop_();
_nop_();
}
void delay_sec(uint z) //毫秒延时
{
while(z--)
{
delay_1ms();
}
}
void Uart_Send(uchar dat) //串口发送
{
while (busy); //Wait for the completion of the previous data is sent
busy = 1;
SBUF = dat; //Send data to UART buffer
}
void Uart_Init(void) //9600bps@12MHz
{
PCON &= 0x7f; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
AUXR &= 0xfe; //串口1选择定时器1为波特率发生器
TMOD &= 0x0f; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TL1 = 0xD9; //设定定时初值
TH1 = 0xD9; //设定定时器重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
void Uart_Isr() interrupt 4 using 1
{
if (RI)
{
RI = 0; //Clear receive interrupt flag
//P0 = SBUF; //P0 show UART data
//bit9 = RB8; //P2.2 show parity bit
}
if (TI)
{
TI = 0; //Clear transmit interrupt flag
busy = 0; //Clear transmit busy flag
}
}
uint RF12_WRT_CMD(uint cmd) //RF12写命令
{
uchar i;
uchar temp;
temp=0;
SCK=0;
nSEL=0;
for(i=0;i<16;i++)
{
if(cmd&0x8000)
{
SDI=1;
}
else
{
SDI=0;
}
SCK=1;
delay_1us();
delay_1us();
delay_1us();
delay_1us();
temp<<=1;
if(SDO)
{
temp|=0x0001;
}
SCK=0;
delay_1us();
delay_1us();
delay_1us();
delay_1us();
cmd<<=1;
}
SCK=0;
nSEL=1;
return(temp);
}
void RF12_init() //RF12初始化
{
RF12_WRT_CMD(0x80D8);
RF12_WRT_CMD(0x8209);
RF12_WRT_CMD(0xA640);
RF12_WRT_CMD(0xC647);
RF12_WRT_CMD(0x94C0);
RF12_WRT_CMD(0xC2AC);
RF12_WRT_CMD(0xCA81);
RF12_WRT_CMD(0xCA83);
RF12_WRT_CMD(0x9820);
RF12_WRT_CMD(0xC040);
RF12_WRT_CMD(0xC4B7);
RF12_WRT_CMD(0x8289);
}
uchar RF12_recive() //RF12接收
{
uint date;
RF12_WRT_CMD(0x0000);
date=RF12_WRT_CMD(0xB000);
date=(char)date&0x00FF;
return(date);
}
void main()
{
uchar date,i,check;
i=0;
Uart_Init();
ES=1;
EA=1;
RF12_init();
RF12_WRT_CMD(0xB000);//新加
while(1)
{
while(!nIRQ)
{
date=RF12_recive();
RF12_recive_date=date;
Uart_Send(date);
//check+=RF12_recive_date;
i++;
if(i==17)
{
i=0;
RF12_WRT_CMD(0xCA81);
RF12_WRT_CMD(0xCA83);
delay_sec(500);
}
}
}
}
大二学生写的,不是很规范,高手莫喷,哈哈 |
|