想测试发送0xaa,但接收不对,而且接收更像是乱码,改了很多地方都不对,不知道问题出在哪里,希望各位大神帮忙看看代码错在哪。我用的keil3编译环境,51单片机,电力线载波芯片是MI200E,测试接收0xaa是通过8个led灯(也用串口显示过,和led灯显示相匹配)第一次提问题,不知道怎么把MI200E的数据手册和应用手册贴出来,在代码后贴出了文档在百度文库上的网址,麻烦各位大神了,小弟这次是碰到棘手困难了,在这先谢了。代码如下:
/********发送程序*********************/
#include
#include
#define uchar unsigned char
#define uint unsigned int
//sbit MOSI=P1^0; //主设备发送从设备接收线,master output subordinate input
//sbit MISO=P1^1; //从设备发送主设备接收线 master input subordinate output
sbit SDO=P1^2; //p1.3口模拟主机输出 主设备发送从设备接收
sbit SDI=P1^1; //p3.2口模拟主机输入,接到外部中断0 主设备接收从设备发送
sbit sck=P1^3; //SPI时钟
sbit cs=P1^4; //片选 p1.3
sbit MI200E_RST=P1^5; //复位
sbit ceshi1=P0^6;
sbit ceshi2=P0^7;
uchar num;
uchar RDSR_command; //用来读0x82
uchar CRC_H,CRC_L;
uchar step,i;
void delay(uint z);//延时
void cudelay_50us();
void init_MI200E();//初始化
void Write_CommandReg(uchar add,uchar com);//写控制指令
uchar Read_CommandReg(uchar add);//读控制指令
void Write_DataReg(uchar add,uchar dat);//写数据,dat应是16位的
void Write_DataReg2(uchar add,uchar dat_H,uchar dat_L);//改进,将高低8位分开发送
uchar Read_DataReg(uchar add);//读数据
void send();
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void cudelay_50us()
{
uchar i;
for(i=0;i<5;i++);
}
void init_MI200E() //初始化
{
MI200E_RST=0;
delay(600); //要求延时超过500ms
MI200E_RST=1;
delay(60); //要求延时超过50ms
Write_CommandReg(0x01,0xFF);
Write_CommandReg(0x0C,0x58);
Write_CommandReg(0x0D,0x01); //应用笔记这样写
// Write_CommandReg(0x0D,0x0A); //数据手册这样写
Write_CommandReg(0x10,0x66);
Write_CommandReg(0x12,0x66);
Write_CommandReg(0x14,0x66);
Write_CommandReg(0x11,0x88);
Write_CommandReg(0x13,0x88);
Write_CommandReg(0x15,0x88);
Write_CommandReg(0x07,0xFF);
Write_CommandReg(0x0A,0x00);
Write_CommandReg(0x0B,0x00);
}
void init()
{
TMOD=0x01;//设置定时器0工作方式1
TH0=(65536-2293)/256;//定时5ms
TL0=(65536-2293)%256;
EA=1;
ET0=1;//开定时器0
TR0=1;//启动定时器0
}
//写入控制寄存器
void Write_CommandReg(uchar add,uchar com)
{
uchar i;
uchar mark;
cs=0;
mark=0x80;
_nop_(); //_nop_();延时1us
_nop_();
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(add&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
mark=0x80;
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(com&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
_nop_();
sck=0;
cs=1;
}
//读取控制寄存器
uchar Read_CommandReg(uchar add) //时序有问题,返回的readdata有三个高,目测是TI、carr和
{ //Frame,但P2口值检测出Frame为高
uchar i;
uchar mark;
uchar readdata;
cs=0;
mark=0x80;
_nop_();
_nop_();
for(i=0;i<8;i++)
{
sck=0;
// _nop_();
if(add&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
_nop_();
_nop_();
for(i=0;i<8;i++)
{ //此处不能加延时
sck=0;
_nop_();
readdata<<=1;
if(SDI)
{
readdata|=1;
}
else
{
readdata&=0xFE;
}
sck=1;
_nop_();
}
_nop_();
sck=0;
_nop_();
cs=1;
return(readdata);
}
//写入数据寄存器
void Write_DataReg(uchar add,uchar dat)
{
uchar i;
uchar mark;
uchar marklong;
cs=0;
mark=0x80;
marklong=0x8000;
_nop_();
_nop_();
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(add&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
for(i=0;i<16;i++)
{
sck=0;
_nop_();
if(dat&marklong)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
marklong>>=1;
}
_nop_();
sck=0;
cs=1;
}
void Write_DataReg2(uchar add,uchar dat_H,uchar dat_L)
{
uchar i;
uchar mark;
uint marklong;
cs=0;
mark=0x80;
marklong=0x8000;
nop();
nop();
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(add&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(dat_H&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(dat_L&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
_nop_();
sck=0;
cs=1;
}
//读取数据寄存器
uchar Read_DataReg(uchar add)
{
uchar i;
uchar mark;
uint readdata;
cs=0;
mark=0x80;
readdata=0;
_nop_();
_nop_();
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(add&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
_nop_();
_nop_();
for(i=0;i<16;i++)
{
sck=0;
_nop_();
readdata<<=1;
if(SDI)
{
readdata|=1;
}
else
{
readdata&=0xFE;
}
sck=1;
_nop_();
}
_nop_();
sck=0;
cs=1;
return(readdata);
}
void send()
{
// Write_CommandReg(0x01,0x01); //bit6~4扩频码字,bit3~2波特率选择,bit1~0载波频率
//配置进入发送状态
switch(step)
{
case 0:
{
Write_CommandReg(0x01,0x0d);//将0x01的bit2、3至高,其余不变,以最低速率发送bit2、3
// Write_CommandReg(0x02,0x00);//将TI复位
Write_DataReg2(0x04,0xff,0xff); //发送0xff,0xff引导码
step=1;
}
break;
case 1:
{
Write_CommandReg(0x02,0xfd);//将0x02的CRC清零
// Write_CommandReg(0x02,0x00);//将TI复位
Write_DataReg2(0x04,0x1a,0x0c);//发送bit3 0x1a和bit4 波特率和长度
step=2;
}
break;
case 2:
{
Write_CommandReg(0x01,0x01);//将bit2、3恢复原设波特率1600和76.8kHZ
// Write_CommandReg(0x02,0x00);//将TI复位
Write_DataReg(0x04,0xaa);//发送bit5,即使改成0xaaaa也不对
for(i=0;i<10;i++) //延时50us
{
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
}
CRC_H=Read_CommandReg(0xa8); //读CRC
CRC_L=Read_CommandReg(0xa9);
step=3;
}
break;
case 3:
{
// Write_CommandReg(0x02,0x00);//将TI复位
Write_DataReg2(0x04,CRC_H,CRC_L);//发送CRC
step=0;
}
break;
default:
{delay(10);}
break;
}
}
void main()
{
init();
init_MI200E();
Write_CommandReg(0x02,0x80);
Write_DataReg2(0x04,0xff,0xff);
Write_CommandReg(0x01,0x01); //bit6~4扩频码字,bit3~2波特率选择,bit1~0载波频率
step=0;
sck=0;
SDI=1;
while(1);
}
void timer0() interrupt 1//2.5ms
{
// P1|=1;
TH0=(65536-2293)/256;//
TL0=(65536-2293)%256;//重装初值
// Write_CommandReg(0x02,0x80);
RDSR_command=Read_CommandReg(0x82);
P2=RDSR_command;
if((RDSR_command & 0x80)==0x80) //每隔2.5ms查询0x82,判断bit7 TI是否为1
{ ceshi2=0;
// P1&=0xFE;
Write_CommandReg(0x02,0x00);//将TI复位
// delay(5);
send(); //TI为1执行发送,TI为1往发送寄存器写入数据,之后TI需复位
// Write_CommandReg(0x01,0x0d);//将0x01的bit2、3至高,其余不变,以最低速率发送bit2、3
// Write_DataReg2(0x04,0xff,0xff); //发送0xff,0xff引导码
// P1|=1;
// P0=0xaa;
}
// P1&=0xFE;
}
/*************接收程序************************/
#include
#include
#define uchar unsigned char
#define uint unsigned int
//sbit MOSI=P1^0; //主设备发送从设备接收线,master output subordinate input
//sbit MISO=P1^1; //从设备发送主设备接收线 master input subordinate output
sbit SDO=P1^2; //p1.3口模拟主机输出 主设备发送从设备接收
sbit SDI=P1^1; //p3.2口模拟主机输入,接到外部中断0 主设备接收从设备发送
sbit sck=P1^3; //SPI时钟
sbit cs=P1^4; //片选 p1.3
sbit MI200E_RST=P1^5; //复位
sbit ceshi1=P0^6;
sbit ceshi2=P0^7;
uchar num;
uchar RDSR_command; //用来读0x82
uchar RDRR_command; //用来读0x83
uchar RDRB0_DataReg; //用来读取数据寄存器0x84
uchar CRC_H,CRC_L,CRC_flag;
uchar step,i;
void delay(uint z);
void cudelay_50us();
void init_MI200E();
void Write_CommandReg(uchar add,uchar com);
uchar Read_CommandReg(uchar add);
void Write_DataReg(uchar add,uchar dat);
void Write_DataReg2(uchar add,uchar dat_H,uchar dat_L);
uchar Read_DataReg(uchar add);
void send();
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void cudelay_50us()
{
uchar i;
for(i=0;i<5;i++);
}
void init_MI200E() //初始化
{
MI200E_RST=0;
delay(600); //要求延时超过500ms
MI200E_RST=1;
delay(60); //要求延时超过50ms
Write_CommandReg(0x01,0xFF);
Write_CommandReg(0x0C,0x58);
Write_CommandReg(0x0D,0x01); //应用笔记这样写
// Write_CommandReg(0x0D,0x0A); //数据手册这样写
Write_CommandReg(0x10,0x66);
Write_CommandReg(0x12,0x66);
Write_CommandReg(0x14,0x66);
Write_CommandReg(0x11,0x88);
Write_CommandReg(0x13,0x88);
Write_CommandReg(0x15,0x88);
Write_CommandReg(0x07,0xFF);
Write_CommandReg(0x0A,0x00);
Write_CommandReg(0x0B,0x00);
}
void init()
{
TMOD=0x01;//设置定时器0工作方式1
TH0=(65536-2293)/256;//定时5ms
TL0=(65536-2293)%256;
EA=1;
ET0=1;//开定时器0
TR0=1;//启动定时器0
}
//写入控制寄存器
void Write_CommandReg(uchar add,uchar com)
{
uchar i;
uchar mark;
cs=0;
mark=0x80;
_nop_(); //_nop_();延时1us
_nop_();
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(add&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
mark=0x80;
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(com&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
_nop_();
sck=0;
cs=1;
}
//读取控制寄存器
uchar Read_CommandReg(uchar add)
{
uchar i;
uchar mark;
uchar readdata;
cs=0;
mark=0x80;
_nop_();
_nop_();
for(i=0;i<8;i++)
{
sck=0;
// _nop_();
if(add&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
_nop_();
for(i=0;i<8;i++)
{ //此处不能加延时
sck=0;
_nop_();
readdata<<=1;
if(SDI)
{
readdata|=1;
}
else
{
readdata&=0xFE;
}
sck=1;
// nop();
}
_nop_();
sck=0;
_nop_();
cs=1;
return(readdata);
}
//写入数据寄存器
void Write_DataReg(uchar add,uchar dat)
{
uchar i;
uchar mark;
uchar marklong;
cs=0;
mark=0x80;
marklong=0x8000;
_nop_();
_nop_();
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(add&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
for(i=0;i<16;i++)
{
sck=0;
_nop_();
if(dat&marklong)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
marklong>>=1;
}
_nop_();
sck=0;
cs=1;
}
void Write_DataReg2(uchar add,uchar dat_H,uchar dat_L)
{
uchar i;
uchar mark;
uint marklong;
cs=0;
mark=0x80;
marklong=0x8000;
nop();
nop();
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(add&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(dat_H&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(dat_L&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
_nop_();
sck=0;
cs=1;
}
//读取数据寄存器
uchar Read_DataReg(uchar add)
{
uchar i;
uchar mark;
uint readdata;
cs=0;
mark=0x80;
readdata=0;
_nop_();
_nop_();
for(i=0;i<8;i++)
{
sck=0;
_nop_();
if(add&mark)
{
SDO=1;
}
else
{
SDO=0;
}
sck=1;
_nop_();
mark>>=1;
}
_nop_();
_nop_();
for(i=0;i<16;i++)
{
sck=0;
_nop_();
readdata<<=1;
if(SDI)
{
readdata|=1;
}
else
{
readdata&=0xFE;
}
sck=1;
_nop_();
}
_nop_();
sck=0;
cs=1;
return(readdata);
}
void send()
{
// Write_CommandReg(0x01,0x01); //bit6~4扩频码字,bit3~2波特率选择,bit1~0载波频率
//配置进入发送状态
switch(step)
{
case 0:
{
Write_CommandReg(0x01,0x0d);//将0x01的bit2、3至高,其余不变,以最低速率发送bit2、3
Write_DataReg2(0x04,0xff,0xff); //发送0xff,0xff引导码
step=1;
}
break;
case 1:
{
Write_CommandReg(0x02,0xfd);//将0x02的CRC清零
Write_DataReg2(0x04,0x1a,0x0c);//发送bit3 0x1a和bit4 波特率和长度
step=2;
}
break;
case 2:
{
Write_CommandReg(0x01,0x01);//将bit2、3恢复原设波特率1600和76.8kHZ
Write_DataReg(0x04,0xaa);//发送bit5
for(i=0;i<10;i++) //延时50us
{
nop(); nop(); nop(); nop(); nop();
}
CRC_H=Read_CommandReg(0xa8); //读CRC
CRC_L=Read_CommandReg(0xa9);
step=3;
}
break;
case 3:
{
Write_DataReg2(0x04,CRC_H,CRC_L);//发送CRC
ceshi1=1;
ceshi2=0;
Write_CommandReg(0x02,0x00);//将TI复位
step=0;
}
break;
default:
{}
break;
}
}
void receive()
{
switch(step)
{
case 0:
{
RDRR_command=Read_CommandReg(0x83);
if(RDRR_command!=0x00)
{
Write_CommandReg(0x01,0x81);
step=1;
}
}
break;
case 1:
{
if((RDSR_command & 0x40)==0x40)
{
step=2;
}
else
{
step=1;
}
}
break;
case 2:
{
Write_CommandReg(0x02,0x7a);//将CRC标志位置1
RDRB0_DataReg=Read_DataReg(0x84);//读取0x84
Write_CommandReg(0x02,0x30);//将RI清零
P0=RDRB0_DataReg;
step=3;
}
break;
case 3:
{
CRC_flag=Read_DataReg(0x84);//读取CRC校验标志位
// P0=CRC_flag;
if(CRC_flag==1)
{
Write_CommandReg(0x02,0x00);//将EPF和CRC标志位清零
}
}
break;
default:
{}
break;
}
}
void main()
{
init();
init_MI200E();
// Write_CommandReg(0x02,0x80);
Write_CommandReg(0x02,0x00);
Write_CommandReg(0x01,0x81);//bit6~4扩频码字,bit3~2波特率选择,bit1~0载波频率
Write_CommandReg(0x01,0x8d);//配置接收状态
step=0;
sck=0;
SDI=1;
while(1);
}
void timer0() interrupt 1//2.5ms
{
// P1|=1;
TH0=(65536-2293)/256;//
TL0=(65536-2293)%256;//重装初值
RDSR_command=Read_CommandReg(0x82);
P2=RDSR_command;
if(((RDSR_command & 0x20)==0x20)&&((RDSR_command & 0x10)==0x10)) //每隔2.5ms查询0x82,判断carr和frame是否为1
{
// P1&=0xFE;
// Write_CommandReg(0x02,0x00);//将TI复位
// delay(2.5);
receive(); //carr和frame为1执行接收
// cudelay_50us();
// ceshi2=0;
// Write_CommandReg(0x02,0x30);//将RI清零
//Write_DataReg2(0x04,0xff,0xff);
// P1|=1;
// P0=0xaa;
}
// P1&=0xFE;
}
MI200E数据手册网址:CSDN移动问答
MI200E应用笔记网址:CSDN移动问答