376硬件SPI读写数据

在使用硬件SPI时,例程里的Spi376Exchange( UINT8 d )能实现输出且输入8个位数据吗? UINT8 Spi376Exchange( 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数据寄存器读出数据 */ }

我感觉此程序只能输出8个位数据吧?

void xWriteCH376Data( UINT8 mData ) /* 向CH376写数据 */ { Spi376Exchange( mData ); // mDelay0_5uS( ); /* 确保读写周期大于0.6uS */ } UINT8 xReadCH376Data( void ) /* 从CH376读数据 */ { // mDelay0_5uS( ); /* 确保读写周期大于0.6uS */ return( Spi376Exchange( 0xFF ) ); }

从376读数据时,为什么形参要带0xff,这样能对写入的数据取反吗?请多指教

补充: 我的mcu接收和发送字节的状态是两个标志位RX_BYTE和TX_BYTE,所以开始我改成如下:

RX_BYTE 接收字节状态。UART模式和SPI从模式 0:没有接收字节 1:收到的字节就绪 TX_BYTE 发送字节状态。UART模式和SPI主模式 0:没有发送字节 1:写到数据缓冲器寄存器的最后字节已发送

UINT8 Spi376Exchange( 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数据寄存器读出数据 */

CH376_SPI_SCS = 0; U1DBUF = d; //加入要发送的数据 while (!U1TX_BYTE); //读取接收状态 CH376_SPI_SCS = 1; U1TX_BYTE = 0; return(U1DBUF); } 我感觉这样只能向376写数据,不能读数据,跑程序证明SPI通讯不正常,就参照模拟spi的方式,把写和读分成两个函数,如下

void Spi376OutByte( UINT8 d ) /* SPI输出8个位数据 */ { P1SEL |= 0xE0; // P1_7, P1_6, and P1_5 are peripherals P1SEL &= ~0x10; // P1_4 is GPIO (SSN) P1DIR |= 0x10; // SSN is set as output U1CSR &= ~0xA0; // SPI Master Mode CH376_SPI_SCS = 0; U1DBUF = d; //将数据写入SPI数据寄存器 while(!U1TX_BYTE); //查询接收字节的状态 U1TX_BYTE = 0; //清除SPI字节传输完成标志 CH376_SPI_SCS = 1; // CH376在时钟上升沿采样输入 }

UINT8 Spi376InByte( void ) /* SPI输入8个位数据 */ { UINT8 d; P1SEL |= 0xF0; // P1_4, P1_5, P1_6, and P1_7 are peripherals

U1CSR &= ~0x80; U1CSR |= 0x20; // SPI Slave Mode

while(!U1RX_BYTE); U1RX_BYTE = 0; d = U1DBUF; return( d ); }

端口初始化程序如下:

void CH376_PORT_INIT( void ) /* 由于使用SPI读写时序,所以进行初始化 */ { CH376_SPI_SCS = 1; //INTT PERCFG |= 0x02; // PERCFG.U1CFG = 1 P1SEL &= ~0x10; // P1_4 is GPIO (SSN) P1DIR |= 0x10; // SSN is set as output //Baud Rate set U1BAUD = 0x00; // BAUD_M = 0 U1GCR |= 0x11; // BAUD_E = 17 Fsck=(((256+BAUD_m)*2^BAUD_E)/2^28)*32M=4M // Configure phase, polarity, and bit order U1GCR &= ~0xC0; // CPOL = CPHA = 0 U1GCR |= 0x20; // ORDER = 1 MSB先传输 }

帮忙给看看这样给行吗?有没有问题?


这跟SPI底层有关系,Spi376Exchange函数既可以输入也可以输出数据,数据是循环发送的,发送一组数据数为了产生8位时钟来输入输出数据,就读而言,产生时钟后读到覆盖SPDR的数据。


只有登录才能回复,可以选择微信账号登录