📄 exam.c
字号:
// V1.1
/* ********************************************************************************************** */
/* 例子:操作4线接口SPI存储器25F512、25F020 */
/* 连线: USB2SPI_SCK/D3 <-> 25FXX_SCK, USB2SPI_DO/D5 <-> 25FXX_SI, USB2SPI_DI/D7 <-> 25FXX_SO, USB2SPI_CS0 <-> 25FXX_CS# */
BOOL WINAPI AT25F512_ReadBlock( // 读AT25F512的块 (包括:输出器件读命令码,输出3字节共24位地址,读入数据块)
ULONG iIndex, // 指定USB2SPI设备序号
ULONG iAddress, // 指定操作地址
ULONG iInLength, // 准备读取的数据字节数,单次建议小于1024字节
PVOID oInBuffer ) // 指向一个缓冲区,返回后是读入的数据
{
static BOOL mTheFirst = TRUE;
if ( mTheFirst ) { // 首次进入时需要设置I/O方向
if ( USBIO_SetStream( iIndex, 0x81 ) == FALSE ) return( FALSE ); // 设置串口流模式:SPI为单入单出,SPI字节中的位顺序是高位在前
mTheFirst = FALSE;
}
if ( iInLength == 0 || iInLength > mDEFAULT_BUFFER_LEN ) return( FALSE );
*( (PUCHAR)oInBuffer + 0 ) = 0x03; // 读存储器命令码,注意各器件不一定命令码相同
*( (PUCHAR)oInBuffer + 1 ) = (UCHAR)( iAddress >> 16 & 0xFF ); // 指定读操作的地址A23-A16
*( (PUCHAR)oInBuffer + 2 ) = (UCHAR)( iAddress >> 8 & 0xFF ); // 指定读操作的地址A15-A8
*( (PUCHAR)oInBuffer + 3 ) = (UCHAR)( iAddress & 0xFF ); // 指定读操作的地址A7-A0
// memset( (PUCHAR)oInBuffer + 4, 0xFF, iInLength ); // 对于有些SPI器件,可能要求在读出数据时SI输入保持为1或者0,那么就要在此设置
if ( USBIO_StreamSPI4( iIndex, 0x80, iInLength + 4, oInBuffer ) == FALSE ) return( FALSE ); // 处理4线接口SPI数据流,自动片选为CS0
/* 对于25F512的读操作,要先输出4个字节命令及地址,再输入若干个字节数据,调用API和API返回时都是指总长度,所以返回数据的前4个字节是在输出命令及地址时输入的,应该丢弃 */
memmove( oInBuffer, (PUCHAR)oInBuffer + 4, iInLength ); // 因为USB2SPI的SPI是数据流,所以实际返回数据应该去掉自己发出的4个字节(命令和地址)
return( TRUE );
}
/* ********************************************************************************************** */
/* 例子:操作类似SPI的非标准串行时序的8位ADC芯片ADC0831、TLC0831 */
/* 连线: USB2SPI_SCK/D3 <-> ADC0831_CLK, USB2SPI_DI/D7 <-> ADC0831_DO, USB2SPI_CS2 <-> ADC0831_CS# */
BOOL WINAPI ADC0831_ReadADC( // 读取ADC结果
ULONG iIndex, // 指定USB2SPI设备序号
PUCHAR oADC ) // 指向一个字节单元,返回读出的ADC结果
{
static BOOL mTheFirst = TRUE;
UCHAR mBuffer[ 256 ];
ULONG i;
if ( mTheFirst ) { // 首次进入时需要设置I/O方向
if ( USBIO_Set_D5_D0( iIndex, 0x0C, 0x04 ) == FALSE ) return( FALSE ); // 设置USB2SPI的D5-D0引脚的I/O方向,DCK/D3输出默认为0,D2输出默认为1
mTheFirst = FALSE;
}
for ( i = 0; i < 12; i ++ ) {
mBuffer[ i ] = 0x00; // CS=0 for 1st bit to 12th bit
}
mBuffer[ i++ ] = 0x04; // CS=1 for 13th bit
if ( USBIO_BitStreamSPI( iIndex, i, mBuffer ) == FALSE ) return( FALSE ); // 处理SPI位数据流,输入输出共13位,实际未全部用到
*oADC = 0;
for ( i = 0; i < 8; i ++ ) { // 将每字节的位7合并为8位ADC结果数据
*oADC = ( *oADC << 1 ) | ( mBuffer[ i + 1 ] >> 7 ); // 位7移到位0,跳过首字节无效数据,第2个时钟的输入数据才是MSB位
}
return( TRUE );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -