jd_chuying1990 2014-05-04 11:59 采纳率: 0%
浏览 4983

51单片机模拟spi控制电力载波芯片MI200E,发送0xaa,接收有显示,但不是0xaa。

想测试发送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移动问答

  • 写回答

4条回答 默认 最新

  • PlainJi 2014-05-04 12:31
    关注

    你这个程序好长……
    挑点儿重点的就可以了

    评论

报告相同问题?

悬赏问题

  • ¥15 MATLAB yalmip 可转移负荷的简单建模出错,如何解决?
  • ¥15 数学的三元一次方程求解
  • ¥20 iqoo11 如何下载安装工程模式
  • ¥15 本题的答案是不是有问题
  • ¥15 关于#r语言#的问题:(svydesign)为什么在一个大的数据集中抽取了一个小数据集
  • ¥15 C++使用Gunplot
  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?