MSP430程序库<五>SPI同步串行通信

2020-07-01来源: eefocus关键字:MSP430  程序库  SPI  同步串行通信

SPI总线系统是一种同步串行外设接口;是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。 许多的芯片都用这种协议通信:EEPROM、Flash、实时时钟、AD转换器、数字信号处理器等:MSP430的USART模块不仅能够实现异步模式(见:MSP430程序库<二>UART异步串口),而且支持同步串行通信(即SPI模式);其SPI支持3线、4线操作,支持主机模式和从机模式,字符长度可以7位或8位等。由于要用AD7708芯片完成AD采样,AD7708是通过SPI与其它设备通信的;本程序比较简化,只完成了主机模式的初始化。


硬件介绍:

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线模式,控制多主从系统中多个从机,避免发生冲突。具体方式如下(图截自 用户指南):

image

四线主机模式:STE为高电平,SIMO和UCLK操作正常;STE为低电平,SIMO和UCLK被置为输入方向,主机控制权让出。

四线从机模式:STE为高电平,从机的发送和接收无效,且把SOMI置为输入方向;STE为低电平,发送接收正常,SOMI也为正常输出。


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


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

image

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


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


程序实现:

程序和异步通信方式类似:首先是初始化函数,然后是读取数据、写入数据函数。此程序采用和我之前的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)

}

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


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


使用示例:

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


#include

[1] [2]
关键字:MSP430  程序库  SPI  同步串行通信 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic501799.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:MSP430G2553学习笔记 DAY1 知识储备及设备初始化
下一篇:基于MSP430之间的SPI通信

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

TI MSP430系列单片机串口通信波特率计算方法
TI MSP430系列单片机,usart模块的波特率值设定是通过以下三个寄存器决定的:UxBR0,UxBR1,UxMCTL 波特率=BRCLK/N ,主要是计算出N。BRCLK:时钟源,可以通过寄存器设定何为时钟源; 通过寄存器UCAxCTL1的SSEL两位选择,01:ACLK,02:SMCLKN:波特率产生的分频因子。N=UxBR1+UxBR0+UxMCTL,其中UxBR1+UxBR0为整数部分,UxMCTL为设定小数部分,其中 UxBR1为高位,UxBR0为低位,两者结合起来为一个16位的字。举例说明:波特率=115200,时钟源=8MHz ,为外部晶体振荡器N=8000000/115200=69.44 。很明显
发表于 2020-06-06
Tinyos之使用Msp430Counter32khz获取系统时间
使用平台:TelosB 操作系统:TinyOs最近要为论文写实验数据,需要读取系统的时间,进行一些运算。Tinyos有提供Msp430Counter32khz 组件,该组件提供接口 Counter<T32khz,uint16_t> .该接口有如下命令和事件:1、get()命令调用该命令,会返回计数值。计数动作是从系统启动的时候就开始了。(如果操作系统配置为低功耗模式会停止计数)2、isOverflowpending()命令 是否有溢出(true /false)3、clearoverflow()命令清除挂起状态4、overflow()事件给出当前系计数值已经溢出的信号量。继续分析,得知该组件是有以下
发表于 2020-06-06
TinyOS在MSP430F2618上移植(一)
最新版本的TinyOS2.1.1,虽然增加了更多的平台支持,比如epic、shimmer,但是这些平台都有一个共同的局限性:采用的微控制器都是低端的MSP430系列,如MSP430F149、MSP430F1611。在一些应用场合,这些处理器已经不能达到性能要求,而基于ZigBee的开发平台,如TI推出的开发套件已经开始使用高性能的处理器,并且国内一些公司,如成都无线龙也都纷纷推出基于MSP430F2618和CC2520无线收发模块,这个模块自从它诞生就很好的支持了ZigBee,因为有TI的全力支持,并且相关的演示代码TI都已经准备好了。但是,目前还没有把TinyOS移植到MSP430F2618上的先例。网上很多人说,这个移植很简单
发表于 2020-06-06
TinyOS在MSP430F2618上移植(一)
TinyOS在MSP430F2618上移植(三)之LCD
本节记录串口TFT LCD在TinyOS上的移植。1.8寸LCD显示屏采用ST7735控制器,使用SPI接口实现控制、显示数据的传输。总体架构:分为3层结构,最底层位于相应的platforms中chips目录下,实现在特定平台上控制引脚连接,SPI接口连接,以及SPI配置。中间层实现了LCD基本操作,LCD初始化,提供给上层模块连接的接口,以及资源管理。最上层提供应用层模块连接的接口。在本架构中,中间层和最高层提供相同的接口LCD16,该接口提供的实现方法有english_string,clear,single_color等,以及写完成事件writeDone。不同的是在最高层提供的接口LCD16中,并没有真正实现接口的功能,而仅仅是
发表于 2020-06-06
两种方式实现TinyOS对MSP430F26&54系列的支持
第一种方式在Ubuntu 下TinyOS msp430 Toolchain mspgcc升级一文中已经作了详细分析,下面说说另一种方式实现TinyOS对MSP430高端系列单片机的支持。我们已经知道TinyOS的编译过程,ncc编译器编译得到app.c文件,接着使用mspgcc编译工具对目标代码进行编译生成需要的.hex文件。但是,要注意的是在ncc编译过程中也会连接msp430库文件,所以就不可能在没有mspgcc的支持下得到app.c文件。那么,这里就出现了问题,如果没有按照上述所提到的第一种方式升级mspgcc,应该如何正确的编译得到所需的文件呢?答案就是使用挂羊头卖狗肉的方法,具体的就是.platform文件不用修改
发表于 2020-06-06
Ubuntu下MSP430开发环境搭建
阅读 以下文章可搞定Ubuntu下搭建MSP430开发环境(MSPGCC)(一) Programming the MSP430 Launchpad on Ubuntumsp430G2553程序烧写方法:#include <msp430g2553.h> int main (void){        volatile int i;         /* Stop watchdog timer */        WDTCTL = WDTPW | WDTHOLD; 
发表于 2020-06-06
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved