AVR单片机IO口模拟SPI四种模式的程序

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

时钟相位(CPHA)和时钟极性(CPOL)的不同组合使得SPI传输有了4种方式

如果CPOL =0,SCK 引脚在空闲状态保持低电平;

如果CPOL =1,SCK 引脚在空闲状态保持高电平

时序图如下:

//IO端口定义

#define SPI_SCK PC0

#define SPI_MOSI PC1

#define SPI_MISO PC2

#define SPI_DDR DDRC

#define SPI_PORT PROTC

#define SPI_PIN PINC

//端口操作符定义

#define SCK_SET SPI_PORT|=_BV(SPI_SCK)

#define SCK_CLR SPI_PORT&=~_BV(SPI-SCK)

#define MOSI_SET SPI_PORT|=_BV(SPI_MOSI)

#define MOSI_CLR SPI_PORT&=~_BV(SPI_MOSI)

#define MISO_PIN PINC&_BV(SPI_MISO)

#define DELAY_BUS //如需要延时,用延时函数替代此符号

//模式1:CPOL=1 CPHA=1

void spi_init(void)

{

SCK_SET;

SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK);

}

uint8_t spi_readwrite_byte(uint8_t data)

{

uint8_t i,ret=0;

for(i=0;i<8;i++)

{

//下降沿模拟

if(data&0x80)//设置输出

MOSI_SET;

else

MOSI_CLR;

SCK_CRL;//SCK产生下降沿

DELAY_BUS;

//上升沿模拟

ret<<=1;

if(MISO_PIN)//读数据

ret|=1;

SCK_SET; //SCK产生上升沿

data<<=1;

DELAY_BUS;

}

return ret;

}

//模式2:CPOL=0 CPHA=1

void spi_init(void)

{

SCK_CLR;

SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK);

}

uint8_t spi_readwrite_byte(uint8_t data) {

uint8_t i,ret=0;

for(i=0;i<8;i++)

{

//上升沿模拟

if(data&0x80)//设置输出

MOSI_SET;

else

MOSI_CLR;

SCK_SET;//SCK产生上升沿

DELAY_BUS;

//下降沿模拟

ret<<=1;

if(MISO_PIN)//读数据

ret|=1;

SCK_CLR; //SCK产生下降沿

data<<=1;

DELAY_BUS;

}

return ret;

}

//模式3:CPOL=1 CPHA=0

void spi_init(void)

{

SCK_SET;

SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK);

}

uint8_t spi_readwrite_byte(uint8_t data) {

uint8_t i,ret=0;

//设置好输出口

if(data&0x80)

MOSI_SET;

else

MOSI_CLR;

for(i=0;i<8;i++)

{

DELAY_BUS;

//下降沿模拟

ret<<=1;

if(MISO_PIN)//读数据

ret|=1;

SCK_CRL;//SCK产生下降沿

DELAY_BUS;

//上升沿模拟

data<<=1;

if(data&0x80)//设置输出

MOSI_SET;

else

MOSI_CLR;

SCK_SET; //SCK产生上升沿

}

return ret;

}

//模式4:CPOL=0 CPHA=0

void spi_init(void)

{

SCK_CLR;

SPI_DDR|=_BV(SPI_MOSI)|_BV(SPI_SCK);

}

uint8_t spi_readwrite_byte(uint8_t data) {

uint8_t i,ret=0;

//设置好输出口

if(data&0x80)

MOSI_SET;

else

MOSI_CLR;

for(i=0;i<8;i++)

{

DELAY_BUS;

//上升沿模拟

ret<<=1;

if(MISO_PIN)//读数据

ret|=1;

SCK_SET;//SCK产生上升沿

DELAY_BUS;

相关文档
最新文档