单片机模拟SPI程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
时钟相位(CPHA)和时钟极性(CPOL)的不同组合使得SPI传输有了4种方式如果CPOL =0,SCK 引脚在空闲状态保持低电平;
如果CPOL =1,SCK 引脚在空闲状态保持高电平
时序图如下:
(一)A VR单片机实现代码
//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;
//下降沿模拟
data<<=1;
if(data&0x80)//设置输出
MOSI_SET;
else
MOSI_CLR;
SCK_CLR; //SCK产生下降沿
}
return ret;
}
(二)其它单片机实现代码
#include "iom8535v.h"
#define _CPOL 1
#define _CPHA 0
#define SCK_IO DDRA|=0X01
#define MOSI_IO DDRA|=0X02
#define MISO_IO DDRA&=0XFB
#define SSEL_IO DDRA|=0X08
#define SCK_D(X) (X?(PORTA|=0X01):(PORTA&=0XFE)) #define MOSI_D(X) (X?(PORTA|=0X02):(PORTA&=0XFD)) #define SSEL_D(X) (X?(PORTA|=0X08):(PORTA&=0XF7))
#define MISO_I() (PINA&0X04)
void delay()
{
unsigned char m,n;
for(n=0;n<5;n++);
for(m=0;m<100;m++);
}
/************************************************ 端口方向配置与输出初始化
************************************************/ void SPI_Init(void)
{
SCK_IO ;
MOSI_IO ;