当前位置:首页 > 单片机 > 单片机
[导读] 硬件介绍:SPI:SPI是Motorola首先在其MC68HCXX系列处理器上定义的,它是一种同步的高速串行通信协议,有关SPI协议的详细内容,参考:SPI_互动百科。MSP430对SPI的支持:当msp430USART模块控制器UxCTL的

  1. 硬件介绍:

    SPI:SPI是Motorola首先在其MC68HCXX系列处理器上定义的,它是一种同步的高速串行通信协议,有关SPI协议的详细内容,参考:SPI_互动百科。

    MSP430对SPI的支持:当msp430USART模块控制器UxCTL的位SYNC置位时,USART模块工作于同步模式,对于149即工作于SPI模式,若是169,USART0可以支持I2C,可以通过另一控制位I2C控制,I2C位0则工作于SPI。在SPI模式下,允许单片机以确定的速率发送和接收7位或8位数据。

    同步通信与异步通信类似;同步通信和异步通信寄存器资源一致,具体寄存器的不同位之间的功能存在差异;具体寄存器内容参见TI提供的用户指南。

    USART模块的SPI操作可以是3线和4线,其信号如下:
    SIMO:从进主出,主机模式下,数据输出;从机模式下,数据输入。
    SOMI:从出主进,主机模式下,数据输入;从机模式下,数据输出。
    UCLK:USART SPI模式时钟,信号有主机输出,从机输入。
    STE:从机模式发送接收允许控制脚,用于4线模式,控制多主从系统中多个从机,避免发生冲突。具体方式如下(图截自 用户指南):

    四线主机模式:STE为高电平,SIMO和UCLK操作正常;STE为低电平,SIMO和UCLK被置为输入方向,主机控制权让出。
    四线从机模式:STE为高电平,从机的发送和接收无效,且把SOMI置为输入方向;STE为低电平,发送接收正常,SOMI也为正常输出。

    USART模块串行时钟极性和相位设置:

    USART的时钟UCLK的极性和相位由位于UxTCTL寄存器的CKPH和CKPL位控制,具体如下图:在程序中,我分别称之为,时钟模式0、时钟模式1、时钟模式2、时钟模式3。


    USART的波特率产生,SPI不同于异步通信:异步通信由UxBR1UxBR0UxMCTL三个寄存器控制,以产生标准频率;而同步模式,主从设备用同一个时钟,不再需要产生标准时钟,故而不再用UxMCTL寄存器,设其值为0.

    其他的,与异步通信基本一致,这里不再细说。具体参考用户指南。

  2. 程序实现:

    程序和异步通信方式类似:首先是初始化函数,然后是读取数据、写入数据函数。此程序采用和我之前的UART程序库类似的结构,写入数据后进入低功耗等待中断,判断标志位进行写入数据和读取数据。

    这里函数只实现430的主机模式,如需从机模式可以仿照我的程序,进行简化实现。

    由于,我即将使用的SPI设备(AD7708)不是字符型设备,这里不再实现写入字符串函数,也不再移植printf和scanf函数,如若需要可以自己添加,printf和scanf的移植参考:MSP430程序库<四>printf和scanf函数移植

    初始化函数:SpiMasterInit,实现主机模式的初始化工作,函数内容如下:

char SpiMasterInit(long baud,char dataBits,char mode,char clkMode)

{

long int brclk; //波特率发生器时钟频率

UxCTL |= SWRST; //初始

//反馈选择位,为1,发送的数被自己接收,用于测试,正常使用时注释掉

//UxCTL |= LISTEN;

UxCTL |= SYNC + MM; //SPI 主机模式

//时钟源设置

UxTCTL &=~ (SSEL0+SSEL1); //清除之前的时钟设置

if(baud<=16364) //

{

UxTCTL |= SSEL0; //ACLK,降低功耗

brclk = 32768; //波特率发生器时钟频率=ACLK(32768)

}

else

{

UxTCTL |= SSEL1; //SMCLK,保证速度

brclk = 1000000; //波特率发生器时钟频率=SMCLK(1MHz)

}

//------------------------设置波特率-------------------------

if(baud < 300||baud > 115200) //波特率超出范围

{

return 0;

}

//设置波特率寄存器

int fen = brclk / baud; //分频系数

if(fen<2)return (0); //分频系数必须大于2

else

{

UxBR0 = fen / 256;

UxBR1 = fen % 256;

}

//------------------------设置数据位-------------------------

switch(dataBits)

{

case 7:case'7': UxCTL &=~ CHAR; break; //7位数据

case 8:case'8': UxCTL |= CHAR; break; //8位数据

default : return(0); //参数错误

}

//------------------------设置模式---------------------------

switch(mode)

{

case 3:case'3': UxTCTL |= STC; USPI3ON; break; //三线模式

case 4:case'4': UxTCTL &=~ STC; USPI4ON; break; //四线模式

default : return(0); //参数错误

}

//------------------------设置UCLK模式-----------------------

switch(clkMode)

{

case 0:case'0': UxTCTL &=~ CKPH; UxTCTL &=~ CKPL; break; //模式0

case 1:case'1': UxTCTL &=~ CKPH; UxTCTL |= CKPL; break; //模式1

case 2:case'2': UxTCTL |= CKPH; UxTCTL &=~ CKPL; break; //模式2

case 3:case'3': UxTCTL |= CKPH; UxTCTL |= CKPL; break; //模式3

default : return(0); //参数错误

}

UxME |= USPIEx; //模块使能

UCTL0 &= ~SWRST; // Initialize USART state machine

UxIE |= URXIEx + UTXIEx; // Enable USART0 RX interrupt

return(1); //设置成功

}

程序注释已经比较详细,这里不再细说;如果要改为从机模式,把时钟设置和波特率设置去掉应该就可以了。

发送函数和接收函数:

void SpiWriteDat(char c)

{

while (TxFlag==0) SpiLpm(); // 等待上一字节发完,并休眠

TxFlag=0; //

UxTXBUF=c;

}

char SpiReadDat()

{

while (RxFlag==0) SpiLpm(); // 收到一字节?

RxFlag=0;

return(UxRXBUF);

}

发送和接收函数和异步通信里面的几乎一样,如果标志位为0,则等待改变为1,然后写入或读出;标志位在中断函数里被更改;中断函数如下:

#pragma vector=USARTxRX_VECTOR

__interrupt void UartRx()

{

RxFlag=1;

__low_power_mode_off_on_exit();

}

#pragma vector=USARTxTX_VECTOR

__interrupt void UartTx ()

{

TxFlag=1;

__low_power_mode_off_on_exit();

}

中断里面仅仅置标志位后,就退出低功耗;退出后即写入或者读取数据。

读取或写入函数调用的SpiLpm函数:

void SpiLpm()

{

if(UxTCTL&SSEL0) LPM3; //若以ACLK 作时钟,进入LPM3休眠(仅打开ACLK)

else LPM0; //若以SMCLK作时钟,进入LPM0休眠(不关闭SMCLK)

}


  1. 根据不同情况进入低功耗,如果单片机其他地方不允许进入低功耗,可以更改这个函数。

    程序部分就这么多了。需要的函数在头文件里面声明,方便使用。

  2. 使用示例:

    程序使用方式和之前的程序库相同,加入c文件,包含h文件,调用初始化函数后即可掉用程序库中的函数。


#include "msp430x16x.h" //430寄存器头文件

#include "Spi.h" //串口通讯程序库头文件


void main()

{

// Stop watchdog timer to prevent time out reset

WDTCTL = WDTPW + WDTHOLD;

ClkInit();

// 主机模式,波特率25000,8位数据位,三线模式,时钟模式0(具体见spi.c)

SpiMasterInit(25000,8,3,0);

_EINT();

while(1) //串口测试

{

SpiWriteDat(0X20);

char a = SpiReadDat();

}

}


  1. 这里只是一个简单的使用示例,详细的使用,将会在下一篇给出,下一篇:MSP430程序库<六>通过SPI操作AD7708;将会使

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

在这篇文章中,小编将对USB接口的相关内容和情况加以介绍以帮助大家增进对USB接口的了解程度,和小编一起来阅读以下内容吧。

关键字: USB 通用串行总线 总线

今天,小编将在这篇文章中为大家带来嵌入式总线技术的有关报道,通过阅读这篇文章,大家可以对嵌入式总线技术具备清晰的认识,主要内容如下。

关键字: 嵌入式 总线

汽车CAN/LIN总线系统测试的关键是测试流程、测试标准和测试工具,掌握专业的总线分析和测试工具的使用技术,开发测试软件并将它们应用到测试过程是对中国汽车厂家和汽车工程师的重大挑战汽车总线测试流程。概括的讲,汽车总线的测...

关键字: CAN 总线 汽车

现代电子技术的正处于一个飞速发展的时代,随着现代汽车整体性能的逐渐完善,单片机和集成电路不再是家电等电器产品的专属,也正愈来愈广泛的被在应用现代汽车上,电子控制单元部件及各种传感器数量在现代汽车的装配也越来越多。为方便这...

关键字: 汽车 总线 监控

现在CAN的高性能和可靠性已被认同,并被广泛地应用于工业自动化、船舶、医疗设备、工业设备等方面,现场总线是当今自动化领域技术发展的热点之一、被誉为自动化领域的计算机局域网。它的出现为分布式控制系统实现各节点之间实时、可靠...

关键字: CAN 总线 硬件

CAN(Controller Area Network)是一种多主方式的串行通讯总线。基本设计规范要求有高的位速率、高抗电磁干扰性,而且能够检测出产生的任何错误,当信号传输距离达到 10Km 时 CAN-bus 仍可提供...

关键字: CAN 串行通讯 总线

CAN(Controller Area Network)即控制器局域网络。是应用在现场、在微机化测量设备之间实现双向串行多节点数字通讯系统,是一种开放式、数字化、多点通信的底层控制网络。 CAN协议建立在ISO/OSI模...

关键字: CAN 数字通讯 总线

当前市场行业发展CAN总线虽然有强大的抗干扰和纠错重发机制,但目前CAN大量地运用于电动汽车、充电桩、电力电子、轨道交通等电磁环境比较恶劣的场合,因此对CAN总线的抗干扰能力也会存在挑战,所以对CAN总线的抗干扰能力需要...

关键字: CAN 通信 总线

CAN总线控制器实现网络协议ISO 11898–1的所有低级功能,同时收发器与物理层通信。不同的物理层需要不同的收发器,如高速can、低速容错can、高速可变数据速率can。在一个典型的实现中,CAN总线控制器和微处理器...

关键字: CAN 总线 控制器

CAN英文全称为(Controller Area Network)即局域网控制器,CAN能够实现分布式实时控制。能够将多种智能机器进行网络连接,并进行统一控制。CAN最初由罗伯特·博世公司所开发,1993年开始被广泛应用...

关键字: CAN 总线 汽车
关闭
关闭