资源描述
/*
* SPI.c
*
* Created on: 2014-8-1
* Author: John
*/
#include"MSP430F247.h"
//P5.0:CS(模组片选段,高电平有效)
//P5.1:SID(串行数据输入端)
//P5.3:CLK(串行同步时钟,上升沿时读取SID数据)
//************硬件SPI管脚宏定义*****************
#define SPI_SIMO BIT1 //X.1
#define SPI_SOMI BIT2 //X.2
#define SPI_CLK BIT3 //X.3
#define SPI_CS BIT0 //X.0
//************硬件SPI控制端口宏定义***************
//#define SPI_SEL2 P5SEL2
#define SPI_SEL P5SEL
#define SPI_DIR P5DIR
#define SPI_OUT P5OUT
#define SPI_REN P5REN
//************使能端CS端口宏定义******************
//#define SPI_CS_SEL2 P5SEL2
#define SPI_CS_SEL P5SEL
#define SPI_CS_OUT P5OUT
#define SPI_CS_DIR P5DIR
//************定义发送/接收缓存*******************
unsigned char *SPI_Tx_Buffer;
unsigned char *SPI_Rx_Buffer;
//************定义待发送/接收的字节数**************
unsigned char SPI_Tx_Size=0;
unsigned char SPI_Rx_Size=0;
//************定义发送/接收模式标志****************
unsigned char SPI_Rx_Or_Tx=0; //0:仅接收 1:仅发送 2:收发
/***********************************************
*名 称:SPI_init() 初始化函数
*功 能:对硬件SPI进行初始化设置
*入口参数:无
*出口参数:无
*说 明:如需使用后面的读写函数,在程序开始必须先调用该初始化函数
*范 例:SPI_init();
***********************************************/
void SPI_B1_init(void)
{
//管脚初始化为SP功能
SPI_SEL |= SPI_CLK+SPI_SOMI+SPI_SIMO; //设置第二功能
// SPI_SEL2 |= SPI_CLK+SPI_SOMI+SPI_SIMO;
SPI_DIR |= SPI_CLK+SPI_SIMO; //设置输出
// SD卡SPI模式下,需要将SOMI加上拉电阻
// SPI_REN |= SPI_SOMI;
//SPI_OUT |= SPI_SOMI;
// 使能CS管脚为输出功能
SPI_CS_SEL &= ~SPI_CS;
// SPI_CS_SEL2 &= ~SPI_CS;
SPI_CS_OUT |= SPI_CS;
SPI_CS_DIR |= SPI_CS;
//复位UCB1
UCB1CTL1 |= UCSWRST;
//3_pin,8_pin SPI 主机模式 上升沿
UCB1CTL0 = UCCKPL+UCMSB+UCMST+UCMODE_0+UCSYNC;
//时钟选择SMCLK,MSB first
UCB1CTL1 = UCSWRST+UCSSEL_2;
//f_UCxCLK=8MHz/40=200kHz
UCB1BR0 = 40;
UCB1BR1 = 0;
//UCA0MCTL=0;
//开启UCA0
UCB1CTL1 &= ~UCSWRST;
//清除中断标志位
UC1IFG &= ~(UCB1RXIFG+UCB1TXIFG);
_bis_SR_register(GIE);
}
/***********************************************
*名 称:SPI_CS_High() 使能控制函数
*功 能:3线硬件SPI模式,控制使能CS管脚为高电平
*入口参数:无
*出口参数:无
*说 明:此处的CS管脚可以根据硬件的需要,任意指定管脚做CS均可
*范 例:SPI_CS_High();
***********************************************/
void SPI_CS_High()
{
SPI_CS_OUT |= SPI_CS;
}
/***********************************************
*名 称:SPI_CS_Low()
*功 能:3线硬件SPI模式,控制使能CS管脚为低电平
*入口参数:无
*出口参数:无
*说 明:此处的CS管脚可以根据硬件的需要,任意指定管脚做CS均可
*范 例:SPI_CS_Low();
***********************************************/
void SPI_CS_Low()
{
SPI_CS_OUT &= ~SPI_CS;
}
/***********************************************
*名 称:SPI_Interrupt_Sel() 中断选择函数
*功 能:开启发送或接收中断
*入口参数:onOff=0;关闭发送中断;打开接收中断;
onOff=1;关闭接收中断;打开发送中断;
onOff=2;打开发送中断;打开接收中断;
*出口参数:无
*说 明:使用此函数来控制选择当前中断模式,便于合理的运用中断
*范 例:SPI_Interrupt_Sel(0); //关闭发送中断;打开接收中断
* SPI_Interrupt_Sel(1); //关闭接收中断;打开发送中断;
***********************************************/
void SPI_Interrupt_Sel(unsigned char onOff)
{
if(onOff==0)
{
UC1IE &= ~UCB1TXIE;
UC1IE |= UCB1RXIE;
}
else if(onOff==1)
{
UC1IE &= ~UCB1RXIE;
UC1IE |= UCB1TXIE;
}
else
{
UC1IE |= UCB1TXIE;
UC1IE |= UCB1RXIE;
}
}
/***********************************************
*名 称:SPI_RxFrame() 接收帧函数
*功 能:3线硬件SPI模式下,接收指定数目的字节
*入口参数:*PBuffer:指向存放接收数据的数组
size:要接收的字节数
*出口参数:0:当前硬件SPI在忙
* 1;当前数据已发送完毕
*说 明:使用此函数可以接收指定个数的一帧数据
*范 例:SPI_RxFrame(CMD,6); //接收6个字节,并依此放入CMD中
***********************************************/
unsigned char SPI_RxFrame(unsigned char *pBuffer,unsigned int size)
{
if(size==0) return(1);
if(UCB1STAT&UCBUSY) return(0); //判断硬件SPI正忙,返回0
_disable_interrupts(); //关闭总中断
SPI_Rx_Or_Tx=0; //开启接收模式
SPI_Rx_Buffer = pBuffer; //将发送缓存指向待发送的数组地址
SPI_Rx_Size = size-1; //待发送的数据个数
SPI_Interrupt_Sel(SPI_Rx_Or_Tx); //SPI中断开启选择
_enable_interrupts(); //开总中断
UCB1TXBUF=0XFF; //在接收模式下,也要先发送一次空字节,以便提供通信时钟
// _bis_SR_register(LPM0_bits); //进入低功耗模式0
return(1);
}
/***********************************************
*名 称:SPI_TxFrame() 发送帧函数
*功 能:3线硬件SPI模式下,发送指定数目的字节缓存
*入口参数:*PBuffer:指向待发送数组地址
size:待发送的字节数
*出口参数:0:当前硬件SPI在忙
* 1;当前数据已发送完毕
*说 明:使用此函数可以发送指定个数的一帧数据
*范 例:SPI_TxFrame(CMD,6); //从CMD中取出并发送6个字节
***********************************************/
unsigned char SPI_TxFrame(unsigned char *pBuffer,unsigned int size)
{
if(size==0) return(1);
if(UCB1STAT&UCBUSY) return(0); //判断硬件SPI正忙,返回0
_disable_interrupts(); //关闭总中断
SPI_Rx_Or_Tx=1; //开启接收模式
SPI_Tx_Buffer = pBuffer; //将发送缓存指向待发送的数组地址
SPI_Tx_Size = size-1; //待发送的数据个数
SPI_Interrupt_Sel(SPI_Rx_Or_Tx); //SPI中断开启选择
_enable_interrupts(); //开总中断
UCB1TXBUF=*SPI_Tx_Buffer; //先发送第一个字节人工触发第一次“发送”中断
// _bis_SR_register(LPM0_bits); //进入低功耗模式0
return(1);
}
//*****************中断服务子函数***********************
//提前声明事件处理函数
static void SPI_TxISR();
static void SPI_RxISR();
/***********************************************
*名 称:USCI0TX_ISR_HOOK()
*功 能:响应Tx中断服务
*入口参数:无
*出口参数:无
*说 明:包含唤醒主循环cpu的代码
*范 例:
***********************************************/
#pragma vector=USCIAB1TX_VECTOR
__interrupt void USCI1TX_ISR_HOOK(void)
{
//发送中断事件引擎函数
SPI_TxISR();
//判断此次操作是否完成,完成则退出低功耗
// if(SPI_Tx_Size==0)
// _bic_SR_register_on_exit(LPM0_bits);
}
/***********************************************
*名 称:USCI0RX_ISR_HOOK()
*功 能:响应Rx中断服务
*入口参数:无
*出口参数:无
*说 明:包含唤醒主循环cpu的代码
*范 例:
***********************************************/
#pragma vector=USCIAB1RX_VECTOR
__interrupt void USCI1RX_ISR_HOOK(void)
{
//接收中断事件引擎函数
SPI_RxISR();
//判断此次操作是否完成,完成则退出低功耗
// if(SPI_Rx_Size==0)
// _bic_SR_register_on_exit(LPM0_bits);
}
/***********************************************
*名 称:SPI_RxISR() 事件处理函数
*功 能:UART的Rx事件处理函数
*入口参数:无
*出口参数:无
*说 明:对接收到的数据,区别对待进行处理
*范 例:
***********************************************/
static void SPI_RxISR()
{
*SPI_Rx_Buffer=UCB1RXBUF;
//读取接收缓存,同时,用于清除“UCB1RXIFG”中断标志位
if(SPI_Rx_Size!=0)
{
SPI_Rx_Size--;//待发送的数据减一
SPI_Rx_Buffer++;//发送指针向下一字节偏移
UCB1TXBUF=0XFF;//纯粹为了提供CLK.UCB1TXIFG标志位同时被清除
}
UC1IFG &= ~UCB1TXIFG;//清除发送中断标志位
}
/***********************************************
*名 称:SPI_TxISR() 事件处理函数
*功 能:UART的Tx事件处理函数
*入口参数:无
*出口参数:无
*说 明:对接收到的数据,区别对待进行处理
*范 例:
***********************************************/
static void SPI_TxISR()
{
UCB1RXBUF;
//对UCB1RXBUF空操作,同时,用于清除“UCB1RXIFG”中断标志位
if(SPI_Tx_Size!=0)
{
SPI_Tx_Size--;//待发送的数据减一
SPI_Tx_Buffer++;//发送指针向下一字节偏移
UCB1TXBUF=*SPI_Tx_Buffer;//放入发送缓存.UCB1TXIFG标志位同时被清除
}
UC1IFG &= ~UCB1TXIFG;//最后一次不操作UCB1TXBUF,同时人为清除标志位
}
/***********************************************
*名 称:SPI_HighSpeed() 波特率函数
*功 能:设置SPI为高速
*入口参数:无
*出口参数:无
*说 明:有些SPI设备可工作在高速SPI状态
*范 例:
***********************************************/
void SPI_HighSpeed()
{
UCB1CTL1 |= UCSWRST;
UCB1BR0 = 2; //f_UCxCLK=12MHZ/2=6MHZ
UCB1BR1 = 0;
UCB1CTL1 &= ~UCSWRST;
}
/***********************************************
*名 称:SPI_LowSpeed() 波特率函数
*功 能:设置SPI为低速
*入口参数:无
*出口参数:无
*说 明:有些SPI设备可工作在低速SPI状态
*范 例:
***********************************************/
void SPI_LowSpeed()
{
UCB1CTL1 |= UCSWRST;
UCB1BR0 = 50; //f_UCxCLK=12MHZ/2=6MHZ
UCB1BR1 = 0;
UCB1CTL1 &= ~UCSWRST;
}
展开阅读全文