想做USB主,但是发现单片机根本没法读CH374的寄存器。是先低电平片选,然后发送要查看的寄存器地址以及读的指令,然后用spi接收就行了吧?是还差什么流程吗?为什么CH374根本没有返回值么?这个问题不解决根本没法往后做,也不知道怎么调,时间快来不及了,望哪位大神指点一下迷津,非常感谢!!
首先,确保硬件连接没问题,CH374芯片的RD#引脚和WR#引脚为低电平(接地)并且CS#引脚为高电平,CS#引脚、SCK引脚、SDI引脚和SDO引脚以及INT#引脚连接正确。SPI具体读写流程参考: /* CH374芯片 硬件标准SPI串行连接的硬件抽象层 V1.0 */ /* 提供I/O接口子程序,提供寄存器级读写子程序 */
#include "HAL.H"
/* 本例中的硬件连接方式如下(实际应用电路可以参照修改下述定义及子程序) */ /* 单片机的引脚 CH374芯片的引脚 P1.4 SCS# P1.5 SDI P1.6 SDO P1.7 SCK */ sbit P14 = P1^4; #define CH374_SPI_SCS P14 /* 假定CH374的SCS引脚 */
sfr SPDR = 0x86; /* SPI数据寄存器 */ sfr SPSR = 0xAA; /* SPI状态寄存器 */ sfr SPCR = 0xD5; /* SPI控制寄存器 */ #define SPI_IF_TRANS 0x80 /* SPI字节传输完成标志,在SPSR的位7 */
void CH374_PORT_INIT( ) /* 由于使用通用I/O模拟并口读写时序,所以进行初始化 */ { /* 如果是硬件SPI接口,那么可使用mode3(CPOL=1&CPHA=1)或mode0(CPOL=0&CPHA=0),CH374在时钟上升沿采样输入,下降沿输出,数据位是高位在前 */ CH374_SPI_SCS = 1; /* 禁止SPI片选 */ /* 对于双向I/O引脚模拟SPI接口,那么必须在此设置SPI_SCS,SPI_SCK,SPI_SDI为输出方向,SPI_SDO为输入方向 */ SPCR = 0x5C; /* 设置SPI模式3, DORD=0(MSB first), CPOL=1, CPHA=1, CH374也支持SPI模式0 */ }
UINT8 Spi374Exchange( UINT8 d ) /* 硬件SPI输出且输入8个位数据 */ { /* 为了提高速度,可以将该子程序做成宏以减少子程序调用层次 */ SPDR = d; /* 先将数据写入SPI数据寄存器,然后查询SPI状态寄存器以等待SPI字节传输完成 */ while ( ( SPSR & SPI_IF_TRANS ) == 0 ); /* 查询SPI状态寄存器以等待SPI字节传输完成 */ SPSR &= ~ SPI_IF_TRANS; /* 清除SPI字节传输完成标志,有的单片机会自动清除 */ return( SPDR ); /* 先查询SPI状态寄存器以等待SPI字节传输完成,然后从SPI数据寄存器读出数据 */ }
#define Spi374OutByte( d ) Spi374Exchange( d ) /* SPI输出8个位数据 */ #define Spi374InByte( ) Spi374Exchange( 0xFF ) /* SPI输入8个位数据 */
void Spi374Start( UINT8 addr, UINT8 cmd ) /* SPI开始 */ { // CH374_SPI_SCS = 1; /* 对于双向I/O引脚模拟SPI接口,那么必须确保已经设置SPI_SCS,SPI_SCK,SPI_SDI为输出方向,SPI_SDO为输入方向 */ CH374_SPI_SCS = 0; /* SPI片选有效 */ Spi374OutByte( addr ); Spi374OutByte( cmd ); }
#define Spi374Stop( ) { CH374_SPI_SCS = 1; } /* SPI结束 */ //void Spi374Stop( void ) /* SPI结束 */ //{ // CH374_SPI_SCS = 1; /* SPI片选无效 */ //}
UINT8 Read374Byte( UINT8 mAddr ) /* 从指定寄存器读取数据 */ { UINT8 d; Spi374Start( mAddr, CMD_SPI_374READ ); d = Spi374InByte( ); Spi374Stop( ); return( d ); }
void Write374Byte( UINT8 mAddr, UINT8 mData ) /* 向指定寄存器写入数据 */ { Spi374Start( mAddr, CMD_SPI_374WRITE ); Spi374OutByte( mData ); Spi374Stop( ); }
void Read374Block( UINT8 mAddr, UINT8 mLen, PUINT8 mBuf ) /* 从指定起始地址读出数据块 */ { Spi374Start( mAddr, CMD_SPI_374READ ); while ( mLen -- ) *mBuf++ = Spi374InByte( ); Spi374Stop( ); }
void Write374Block( UINT8 mAddr, UINT8 mLen, PUINT8 mBuf ) /* 向指定起始地址写入数据块 */ { Spi374Start( mAddr, CMD_SPI_374WRITE ); while ( mLen -- ) Spi374OutByte( *mBuf++ ); Spi374Stop( ); }
我又试了一下,发现之所以读不了寄存器的值,是因为前面有一个CH374复位的语句,去掉之后就可以读寄存器了,但其值并不是该寄存器复位后的值,最大的问题就是:只要我执行了写得操作,之后无论我读哪个寄存器,得到的值都是ff。这是为什么呢?????谢谢!
应该是你SPI读写时序有问题,.你把所有的寄存器都读一下看是不是正常的,上电后50MS延时保证CH374复位完毕.
之前那个问题其实是我SPIstop时把片选置低了,改过后就好了,可是我把同样的通信程序应用到另一个大程序中,连上一个USB设备后,又不能通信了(读的所有寄存器都是FF),没办法我又回到原来的测试程序,居然也不行了。时序应该是对的呀,然后就怎么折腾都不行了。。太奇怪了。难道是我的374出了问题,怎么判断是不是硬件上出了问题呀(如果不换新芯片的话)??谢谢。。
还有个问题。读寄存器时374的片选到底是需要一个从高到低的沿还是只有是低电平就行了呢?
你看下我们的程序,是需要一个高到低的过程。
麻烦帮看一下程序,我觉得没错呀,因为我是SCI的时钟同步模式做的SPI,貌似不能设CPOL和CPHA,会与这个有关吗?但是页不能有一段时间能通信,然后就不行的吧。。。谢谢 void main(void) { ClockConfig(MUL_BY_8,MUL_BY_4,MUL_BY_4); mDelaymS( 50 ); // 等待CH374复位完成 CH374_PORT_INIT( ); /* CH374接口初始化 */// d=Read374Byte(REG_USB_SETUP); }
void CH374_PORT_INIT( ) { SPIInit(0,1,1); SPIStart(0,0); PORTD.DDR.BIT.B5=1;//SCS对应管教pD.5设置为输出 PORTD.DR.BIT.B5=1;/* 禁止SPI片选 */ PORT4.DDR.BIT.B0=0;//INT中断对应管教p4.0设置为输入 } UINT8 Read374Byte( UINT8 mAddr ) /* 从指定寄存器读取数据 */ { UINT8 d; Spi374Start( mAddr, CMD_SPI_374READ ); d = SPIReceiveData(0); Spi374Stop( ); return( d ); } void Spi374Start( UINT8 addr, UINT8 cmd ) /* SPI开始 */ { PORTD.DR.BIT.B5=0;/* SPI片选有效 */ SPISendData(0,addr ); SPISendData(0,cmd ); } void Spi374Stop( ) { CH374_SPI_SCS = 1; PORTD.DR.BIT.B5=1; }
问下你用的什么单片机,首先需要确认你的单片机的SPI信号是有出来的,默认CH374芯片支持SPI的模式0和模式3,采样方式为上升沿输出数据,下降沿输入数据。
是瑞萨的RX62N,SPI信号都是有的。就是374没有任何反馈。谢谢
那你直接去读取0X00-0X1f寄存去的数据看下读取出来的数据是多少?SPI不存在没有任何反应。至少应该读取出来的数据是0XFF。
对,读的就是0xff,不过我现在总算找到原因了,因为就在我改动的半分钟内,我的374芯片的V3引脚和焊盘脱落了。。。。这人品。。。。不过还是非常谢谢你们啦。。