想做USB主,但是發(fā)現(xiàn)單片機(jī)根本沒(méi)法讀CH374的寄存器。是先低電平片選,然后發(fā)送要查看的寄存器地址以及讀的指令,然后用spi接收就行了吧?是還差什么流程嗎?為什么CH374根本沒(méi)有返回值么?這個(gè)問(wèn)題不解決根本沒(méi)法往后做,也不知道怎么調(diào),時(shí)間快來(lái)不及了,望哪位大神指點(diǎn)一下迷津,非常感謝??!
首先,確保硬件連接沒(méi)問(wèn)題,CH374芯片的RD#引腳和WR#引腳為低電平(接地)并且CS#引腳為高電平,CS#引腳、SCK引腳、SDI引腳和SDO引腳以及INT#引腳連接正確。SPI具體讀寫流程參考: /* CH374芯片 硬件標(biāo)準(zhǔn)SPI串行連接的硬件抽象層 V1.0 */ /* 提供I/O接口子程序,提供寄存器級(jí)讀寫子程序 */
#include "HAL.H"
/* 本例中的硬件連接方式如下(實(shí)際應(yīng)用電路可以參照修改下述定義及子程序) */ /* 單片機(jī)的引腳 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數(shù)據(jù)寄存器 */ sfr SPSR = 0xAA; /* SPI狀態(tài)寄存器 */ sfr SPCR = 0xD5; /* SPI控制寄存器 */ #define SPI_IF_TRANS 0x80 /* SPI字節(jié)傳輸完成標(biāo)志,在SPSR的位7 */
void CH374_PORT_INIT( ) /* 由于使用通用I/O模擬并口讀寫時(shí)序,所以進(jìn)行初始化 */ { /* 如果是硬件SPI接口,那么可使用mode3(CPOL=1&CPHA=1)或mode0(CPOL=0&CPHA=0),CH374在時(shí)鐘上升沿采樣輸入,下降沿輸出,數(shù)據(jù)位是高位在前 */ CH374_SPI_SCS = 1; /* 禁止SPI片選 */ /* 對(duì)于雙向I/O引腳模擬SPI接口,那么必須在此設(shè)置SPI_SCS,SPI_SCK,SPI_SDI為輸出方向,SPI_SDO為輸入方向 */ SPCR = 0x5C; /* 設(shè)置SPI模式3, DORD=0(MSB first), CPOL=1, CPHA=1, CH374也支持SPI模式0 */ }
UINT8 Spi374Exchange( UINT8 d ) /* 硬件SPI輸出且輸入8個(gè)位數(shù)據(jù) */ { /* 為了提高速度,可以將該子程序做成宏以減少子程序調(diào)用層次 */ SPDR = d; /* 先將數(shù)據(jù)寫入SPI數(shù)據(jù)寄存器,然后查詢SPI狀態(tài)寄存器以等待SPI字節(jié)傳輸完成 */ while ( ( SPSR & SPI_IF_TRANS ) == 0 ); /* 查詢SPI狀態(tài)寄存器以等待SPI字節(jié)傳輸完成 */ SPSR &= ~ SPI_IF_TRANS; /* 清除SPI字節(jié)傳輸完成標(biāo)志,有的單片機(jī)會(huì)自動(dòng)清除 */ return( SPDR ); /* 先查詢SPI狀態(tài)寄存器以等待SPI字節(jié)傳輸完成,然后從SPI數(shù)據(jù)寄存器讀出數(shù)據(jù) */ }
#define Spi374OutByte( d ) Spi374Exchange( d ) /* SPI輸出8個(gè)位數(shù)據(jù) */ #define Spi374InByte( ) Spi374Exchange( 0xFF ) /* SPI輸入8個(gè)位數(shù)據(jù) */
void Spi374Start( UINT8 addr, UINT8 cmd ) /* SPI開始 */ { // CH374_SPI_SCS = 1; /* 對(duì)于雙向I/O引腳模擬SPI接口,那么必須確保已經(jīng)設(shè)置SPI_SCS,SPI_SCK,SPI_SDI為輸出方向,SPI_SDO為輸入方向 */ CH374_SPI_SCS = 0; /* SPI片選有效 */ Spi374OutByte( addr ); Spi374OutByte( cmd ); }
#define Spi374Stop( ) { CH374_SPI_SCS = 1; } /* SPI結(jié)束 */ //void Spi374Stop( void ) /* SPI結(jié)束 */ //{ // CH374_SPI_SCS = 1; /* SPI片選無(wú)效 */ //}
UINT8 Read374Byte( UINT8 mAddr ) /* 從指定寄存器讀取數(shù)據(jù) */ { UINT8 d; Spi374Start( mAddr, CMD_SPI_374READ ); d = Spi374InByte( ); Spi374Stop( ); return( d ); }
void Write374Byte( UINT8 mAddr, UINT8 mData ) /* 向指定寄存器寫入數(shù)據(jù) */ { Spi374Start( mAddr, CMD_SPI_374WRITE ); Spi374OutByte( mData ); Spi374Stop( ); }
void Read374Block( UINT8 mAddr, UINT8 mLen, PUINT8 mBuf ) /* 從指定起始地址讀出數(shù)據(jù)塊 */ { Spi374Start( mAddr, CMD_SPI_374READ ); while ( mLen -- ) *mBuf++ = Spi374InByte( ); Spi374Stop( ); }
void Write374Block( UINT8 mAddr, UINT8 mLen, PUINT8 mBuf ) /* 向指定起始地址寫入數(shù)據(jù)塊 */ { Spi374Start( mAddr, CMD_SPI_374WRITE ); while ( mLen -- ) Spi374OutByte( *mBuf++ ); Spi374Stop( ); }
我又試了一下,發(fā)現(xiàn)之所以讀不了寄存器的值,是因?yàn)榍懊嬗幸粋€(gè)CH374復(fù)位的語(yǔ)句,去掉之后就可以讀寄存器了,但其值并不是該寄存器復(fù)位后的值,最大的問(wèn)題就是:只要我執(zhí)行了寫得操作,之后無(wú)論我讀哪個(gè)寄存器,得到的值都是ff。這是為什么呢?????謝謝!
應(yīng)該是你SPI讀寫時(shí)序有問(wèn)題,.你把所有的寄存器都讀一下看是不是正常的,上電后50MS延時(shí)保證CH374復(fù)位完畢.
之前那個(gè)問(wèn)題其實(shí)是我SPIstop時(shí)把片選置低了,改過(guò)后就好了,可是我把同樣的通信程序應(yīng)用到另一個(gè)大程序中,連上一個(gè)USB設(shè)備后,又不能通信了(讀的所有寄存器都是FF),沒(méi)辦法我又回到原來(lái)的測(cè)試程序,居然也不行了。時(shí)序應(yīng)該是對(duì)的呀,然后就怎么折騰都不行了。。太奇怪了。難道是我的374出了問(wèn)題,怎么判斷是不是硬件上出了問(wèn)題呀(如果不換新芯片的話)??謝謝。。
還有個(gè)問(wèn)題。讀寄存器時(shí)374的片選到底是需要一個(gè)從高到低的沿還是只有是低電平就行了呢?
你看下我們的程序,是需要一個(gè)高到低的過(guò)程。
麻煩幫看一下程序,我覺(jué)得沒(méi)錯(cuò)呀,因?yàn)槲沂荢CI的時(shí)鐘同步模式做的SPI,貌似不能設(shè)CPOL和CPHA,會(huì)與這個(gè)有關(guān)嗎?但是頁(yè)不能有一段時(shí)間能通信,然后就不行的吧。。。謝謝 void main(void) { ClockConfig(MUL_BY_8,MUL_BY_4,MUL_BY_4); mDelaymS( 50 ); // 等待CH374復(fù)位完成 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對(duì)應(yīng)管教pD.5設(shè)置為輸出 PORTD.DR.BIT.B5=1;/* 禁止SPI片選 */ PORT4.DDR.BIT.B0=0;//INT中斷對(duì)應(yīng)管教p4.0設(shè)置為輸入 } UINT8 Read374Byte( UINT8 mAddr ) /* 從指定寄存器讀取數(shù)據(jù) */ { 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; }
問(wèn)下你用的什么單片機(jī),首先需要確認(rèn)你的單片機(jī)的SPI信號(hào)是有出來(lái)的,默認(rèn)CH374芯片支持SPI的模式0和模式3,采樣方式為上升沿輸出數(shù)據(jù),下降沿輸入數(shù)據(jù)。
是瑞薩的RX62N,SPI信號(hào)都是有的。就是374沒(méi)有任何反饋。謝謝
那你直接去讀取0X00-0X1f寄存去的數(shù)據(jù)看下讀取出來(lái)的數(shù)據(jù)是多少?SPI不存在沒(méi)有任何反應(yīng)。至少應(yīng)該讀取出來(lái)的數(shù)據(jù)是0XFF。
對(duì),讀的就是0xff,不過(guò)我現(xiàn)在總算找到原因了,因?yàn)榫驮谖腋膭?dòng)的半分鐘內(nèi),我的374芯片的V3引腳和焊盤脫落了。。。。這人品。。。。不過(guò)還是非常謝謝你們啦。。