/********************************************************************************
模块名称: spi.h
模块说明: c51单片机的i/o模拟spi操作
创建时间: 2005/03/09
创建者: xichen
********************************************************************************/
#ifndef SPI_H
#define SPI_H
sbit SPIS_N = P2^1;
sbit SPIC = P2^3;
sbit SPID = P2^2;
sbit SPIQ = P2^4;
extern void spi_reset();
extern void spi_write(unsigned char spi_bValue);
extern unsigned char spi_read();
#endif
/*******************************************************************************
模块名称: spi.c
模块说明: c51单片机的i/o模拟spi操作
创建时间: 2005/03/09
创建者: xichen
********************************************************************************/
#include "includes.h"
#define set_spi_cs() SPIS_N =1
#define clr_spi_cs() SPIS_N =0
#define set_spi_clk() SPIC =1
#define clr_spi_clk() SPIC =0
#define set_spi_di() SPID =1
#define clr_spi_di() SPID =0
#define read_spi_do() SPIQ
//------------------------------------------
void spi_reset()
{
set_spi_cs();
}
//-----------------------------------------
void spi_write(unsigned char spi_bValue)
{
unsigned char no;
clr_spi_cs();
for (no=0;no<8;no++)
{
clr_spi_clk();
if ((spi_bValue &0x80)==0x80)
set_spi_di();
else
clr_spi_di();
set_spi_clk();
spi_bValue = (spi_bValue <<1);
}
}
//----------------------------------------------
unsigned char spi_read()
{
unsigned char no,spi_bValue;
clr_spi_cs();
for (no=0;no<8;no++)
{
clr_spi_clk();
spi_bValue = (spi_bValue <<1);
set_spi_clk();
if (read_spi_do() ==1)
spi_bValue |=0x01;
else
spi_bValue &=~0x01;
}
return spi_bValue;
}
再一个SPI模拟
#i nclude "COMMON.h"
#i nclude "SPI.H"
#i nclude "INTRINS.H"
/*------------------------------------------------------------------------*/
void SPIReset(void)
{
SPICLK = 0;
}
/*------------------------------------------------------------------------*/
void SPISendByte(unsigned char UC)
{
unsigned char i = 0;
CloseInt(); //要关中断
for(i=0;i<8;i++)
{
SPICLK = LOW;
SPIDI = (bit)(UC&0x80);UC<<=1;//Delay(0);
SPICLK = HIGH;//4个nop 8us
_nop_();
_nop_();
_nop_();
_nop_();
}
SPICLK = LOW;
OpenInt();//开中断
//开中断
/*
#pragma ASM
PUSH ACC;
PUSH 01H;
MOV 01H,#08H
LOOP:
SETB SPICLK
MOV A,R7;
RLC A;
MOV SPIDI,C;
DJNZ 01,LOOP
POP 01H;
pop ACC;
#pragma ENDASM
*/
}
/*-------------------------------------------------------------------------*/
void SPIInit(void)
{
SPICLK = LOW;
SPIDI = LOW;
SPIDO = HIGH;
}
/*------------------------------------------------------------------------*/
unsigned char SPIReadByte(void)
{
unsigned char i = 0,SPIData = 0;
CloseInt();
//要关中断
for(i=0;i<8;i++)
{
SPICLK = LOW;Delay8us();
SPICLK = HIGH;//Delay(10); //这个时间真还不太好控制
SPIData=(SPIData<<1)|SPIDO;
}
SPICLK = LOW;
// #pragma ASM
// #pragma ENDASM
OpenInt();//开中断
return SPIData;
}
/*------------------------------------------------------------------------*/
unsigned long SPIRead24Bit(void)
{
unsigned long SPIData = 0;
unsigned char Data[3] = {0,0,0};
unsigned char i;
CloseInt();//要关中断
/*
for(i=0;i<3*8;i++)
{
SPICLK = LOW;Delay8us();Delay8us();Delay8us();Delay8us();Delay8us();Delay8us();
SPICLK = HIGH;//Delay(8); //这个时间真还不太好控制
if(SPIDO)
{
SPIData=SPIData<<1;
SPIData|=0x01;
}
else
{
SPIData=(SPIData<<1);
SPIData|=0x00;
}
}
*/
for(i=0;i<8;i++)
{
SPICLK = LOW;Delay8us();Delay8us();Delay6us();
SPICLK = HIGH;
Data[0]=(Data[0]<<1)|SPIDO;
}
for(i=0;i<8;i++)
{
SPICLK = LOW;Delay8us();Delay8us();Delay6us();
SPICLK = HIGH;
Data[1]=(Data[1]<<1)|SPIDO;
}
for(i=0;i<8;i++)
{
SPICLK = LOW;Delay8us();Delay8us();Delay6us();
SPICLK = HIGH;
Data[2]=(Data[2]<<1)|SPIDO;
}
SPICLK = LOW;
SPIData = Data[0]*65536+Data[1]*256+Data[2];
OpenInt();//开中断
return SPIData;
}
上一篇:几种常用的模拟SPI读写一体化模块(C51)
下一篇:51模拟SPI同步收发程序.C
推荐阅读最新更新时间:2024-03-16 15:25