返回信息流正在搞底层SPI口的驱动,发现好多SPI的驱动写法都不一样,那位大牛给详细解说一下,从硬件到软件实现,谢谢啦!
PS:遇到的问题如下:
1.主从设备的时钟如何解决,是只要SCK脚相互连接就可以?还是得在软件上加上升下降沿?
2.主设备把要写的数据放到SI线上,从设备如何处理该线上的数据?
3.读写数据时可以不发地址吗?
4.#define GPIOA_ODR_Addr (GPIOA_BASE+12) 这个语句见过好多次,那个GPIOA_BASE一般指的什么?
问题有点多 谢谢啦
这是一条镜像帖。来源:北邮人论坛 / embedded-system / #12368同步于 2012/6/12
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Embedded_System机器人发帖
真心求教SPI口的问题
feijie
2012/6/12镜像同步5 回复
订阅后,新回复会通过你的通知中心匿名送达。
5 条回复
看你的硬件有没有SPI模块,如果有的话就按照手册去用,你向一个寄存器写数,SPI模
块自动给你发出去。如果用GPIO模拟,就得你自己实现所有的时序
【 在 feijie (往事往已) 的大作中提到: 】
: 正在搞底层SPI口的驱动,发现好多SPI的驱动写法都不一样,那位大牛给详细解说一下,从硬件到软件实现,谢谢啦!
: PS:遇到的问题如下:
: 1.主从设备的时钟如何解决,是只要SCK脚相互连接就可以?还是得在软件上加上升下降沿?
: ...................
【 在 ArmStrong 的大作中提到: 】
: 看你的硬件有没有SPI模块,如果有的话就按照手册去用,你向一个寄存器写数,SPI模
: 块自动给你发出去。如果用GPIO模拟,就得你自己实现所有的时序
:
: ...................
谢谢 现在就是自己用GPIO口模拟~~老是弄不好!
SPI是有好多种,还是建议你用硬件SPI,比较简单
如果说用软件模拟SPI的话,网上有好多版本,我这个经过了很多测试,从来没问题,只不过是用给NRF24L01的和MSP430的,你可以参考下,改改其中的定义应该就能用
/****************SPI结构无线模块宏定义************/
#define nRF24L01_CE BIT2//P4.0
#define nRF24L01_CSN BIT0//P4.1
#define nRF24L01_SCK BIT1//P3.3
#define nRF24L01_MOSI BIT3//P3.1
#define nRF24L01_MISO BIT4//P3.2
#define nRF24L01_IRQ BIT5//P1.4
//
//
#define nRF24L01_CE_DIR P1DIR
#define nRF24L01_CSN_DIR P1DIR
#define nRF24L01_SCK_DIR P1DIR
#define nRF24L01_MOSI_DIR P1DIR
#define nRF24L01_MISO_DIR P1DIR
#define nRF24L01_IRQ_DIR P1DIR
#define nRF24L01_IRQ_IE P1IE
#define nRF24L01_IRQ_IES P1IES
//
#define nRF24L01_CE_OutPort P1OUT
#define nRF24L01_CSN_OutPort P1OUT
#define nRF24L01_SCK_OutPort P1OUT
#define nRF24L01_MOSI_OutPort P1OUT
#define nRF24L01_MISO_InPort P1IN
#define nRF24L01_IRQ_InPort P1IN
#define nRF24L01_CE_OutDIR() setbit(nRF24L01_CE_DIR,nRF24L01_CE)
#define nRF24L01_CSN_OutDIR() setbit(nRF24L01_CSN_DIR,nRF24L01_CSN)
#define nRF24L01_SCK_OutDIR() setbit(nRF24L01_SCK_DIR,nRF24L01_SCK)
#define nRF24L01_MOSI_OutDIR() setbit(nRF24L01_MOSI_DIR,nRF24L01_MOSI)
#define nRF24L01_MISO_InDIR() clrbit(nRF24L01_MISO_DIR,nRF24L01_MISO)
#define nRF24L01_IRQ_InDIR() clrbit(nRF24L01_IRQ_DIR,nRF24L01_IRQ)
//
#define nRF24L01_Set_CE() setbit(nRF24L01_CE_OutPort,nRF24L01_CE)
#define nRF24L01_Clear_CE() clrbit(nRF24L01_CE_OutPort,nRF24L01_CE)
#define nRF24L01_Set_CSN() setbit(nRF24L01_CSN_OutPort,nRF24L01_CSN)
#define nRF24L01_Clear_CSN() clrbit(nRF24L01_CSN_OutPort,nRF24L01_CSN)
#define nRF24L01_Set_SCK() setbit(nRF24L01_SCK_OutPort,nRF24L01_SCK)
#define nRF24L01_Clear_SCK() clrbit(nRF24L01_SCK_OutPort,nRF24L01_SCK)
#define nRF24L01_Set_MOSI() setbit(nRF24L01_MOSI_OutPort,nRF24L01_MOSI)
#define nRF24L01_Clear_MOSI() clrbit(nRF24L01_MOSI_OutPort,nRF24L01_MOSI)
//
//SPI Commands
#define nRF24L01_R_REGISTER 0x00
#define nRF24L01_W_REGISTER 0x20
#define nRF24L01_R_RX_PAYLOAD 0x61
#define nRF24L01_W_TX_PAYLOAD 0xA0
#define nRF24L01_FLUSH_TX 0xE1
#define nRF24L01_FLUSH_RX 0xE2
#define nRF24L01_REUSE_TX_PL 0xE3
#define nRF24L01_NOP 0xFF
//
//
//
//
//
//Register Definitions
#define nRF24L01_CONFIG 0x00
#define nRF24L01_EN_AA 0x01
#define nRF24L01_EN_RXADDR 0x02
#define nRF24L01_SETUP_AW 0x03
#define nRF24L01_SETUP_RETR 0x04
#define nRF24L01_RF_CH 0x05
#define nRF24L01_RF_SETUP 0x06
#define nRF24L01_STATUS 0x07
#define nRF24L01_OBSERVE_TX 0x08
#define nRF24L01_CD 0x09
#define nRF24L01_RX_ADDR_P0 0x0A
#define nRF24L01_RX_ADDR_P1 0x0B
#define nRF24L01_RX_ADDR_P2 0x0C
#define nRF24L01_RX_ADDR_P3 0x0D
#define nRF24L01_RX_ADDR_P4 0x0E
#define nRF24L01_RX_ADDR_P5 0x0F
#define nRF24L01_TX_ADDR 0x10
#define nRF24L01_RX_PW_P0 0x11
#define nRF24L01_RX_PW_P1 0x12
#define nRF24L01_RX_PW_P2 0x13
#define nRF24L01_RX_PW_P3 0x14
#define nRF24L01_RX_PW_P4 0x15
#define nRF24L01_RX_PW_P5 0x16
#define nRF24L01_FIFO_STATUS 0x17
void Init_nRF24L01_IO(void)
{
nRF24L01_CE_OutDIR();
nRF24L01_CSN_OutDIR();
nRF24L01_SCK_OutDIR();
nRF24L01_MOSI_OutDIR();
nRF24L01_MISO_InDIR();
nRF24L01_IRQ_InDIR();
//
nRF24L01_Clear_CE();
nRF24L01_Set_CSN();
nRF24L01_Clear_SCK();
nRF24L01_Clear_MOSI();
nRF24L01_IRQ_IE|= nRF24L01_IRQ; //无线中断脚使能
nRF24L01_IRQ_IES|=nRF24L01_IRQ; //下降沿使能
}
//
//
//function SpiWrite();
/******************************************************************************************/
void nRF24L01SpiWrite(unsigned char byte)
{
unsigned char i;
nRF24L01_Clear_SCK();
//delay_us(1);
for (i=0;i<8;i++) // Setup byte circulation bits
{
if ((byte&BIT7)==BIT7) // Put DATA_BUF.7 on data line
nRF24L01_Set_MOSI(); //MOSI=1;
else
nRF24L01_Clear_MOSI(); //MOSI=0;
nRF24L01_Set_SCK(); // Set clock line high
//delay_us(1);
byte=byte<<1;
nRF24L01_Clear_SCK(); // Set clock line low
//delay_us(1);
}
//delay_us(1);
}
//
//
//function SpiRead();
/*****************************************************************************************/
unsigned char nRF24L01SpiRead(void)
{
unsigned char i;
unsigned char temp=0;
nRF24L01_Clear_SCK();
//delay_us(1);
for (i=0;i<8;i++) // Setup byte circulation bits
{
nRF24L01_Set_SCK(); // Set clock line high
//delay_us(1);
temp=temp<<1; // Right shift DATA_BUF
if ((nRF24L01_MISO_InPort&nRF24L01_MISO)==nRF24L01_MISO)
{temp|=1;} // Read data
nRF24L01_Clear_SCK(); // Set clock line low
//delay_us(1);
}
//delay_us(1);
return temp; // Return function parameter
}
【 在 feijie 的大作中提到: 】
: 正在搞底层SPI口的驱动,发现好多SPI的驱动写法都不一样,那位大牛给详细解说一下,从硬件到软件实现,谢谢啦!
: PS:遇到的问题如下:
: 1.主从设备的时钟如何解决,是只要SCK脚相互连接就可以?还是得在软件上加上升下降沿?
: ...................
谢谢,研究研究~~~
【 在 buptzym 的大作中提到: 】
: SPI是有好多种,还是建议你用硬件SPI,比较简单
: 如果说用软件模拟SPI的话,网上有好多版本,我这个经过了很多测试,从来没问题,只不过是用给NRF24L01的和MSP430的,你可以参考下,改改其中的定义应该就能用
: /****************SPI结构无线模块宏定义************/
: ...................