当UCxCTL0的UCMST为0时,该设备工作与从机模式。下图7_17是一个主机与另一个SPI从机设备的连接。
主设备 SPI接收缓存器
从设备
发送缓存器UCxTXBUF
接收缓存器UCxRXBUF
数据移位寄存器 发送移位寄存器 接收移位寄存器
图7_17 从机模式工作状态连接图
在从机模式下,外部主机提供的UCxCLK信号作为从机的SPI时钟,该时钟决定从机的SPI数据传输率。从UCxTXBUF寄存器写入发送移位寄存器的数据在UCxCLK时钟到来之前,依次从UCxSOMI信号线上发送出去。UCxSIMO信号线上接收的数据写入接收移位寄存器中,当达到数据格式的位数(7bit或8bit)时,在UCxCLK时钟的上升沿时刻将其写入UCxRXBUF寄存器中,同时读取中断标志为UCxRXIFG被置位,表明接收到一组数据。
7.3.3 串行时钟的控制
主机的SPI总线的UCxCLK信号即为串行时钟。当UCMST=1时工作于主机模式,该时钟信号通过时钟生成器送达UCxCLK对应的管脚。时钟生成器的输入时钟有控制寄存器UCAxCTL0的UCSSELx来选择。当UCMST=0时工作于从机模式时,USCI的时钟由主机的UCxCLK信号提供,而与本机的内部时钟无关。SPI模式下的时钟生成器如图7_18所示。
位时钟生成器 分频系数 时钟的方向、相位和极性 图7_18 SPI模式下的时钟生成器 位码率控制寄存器UCxxBR1和UCxxBR0的16位UBCRx的值由USCI时钟源BRCLK分频实现。在主机模式下,最大的数据流时钟即为BRCLK。在SPI模式下不使用调制码段,如果实在USCI_A下使用SPI模式,则UCAxMCTL须清零。
UCAxCLK/UCBxCLK的SPI传输速率fBitClock=fBRCLK/UCBRx。
29
UCxCLK时钟的极性和相位由UCAxCTL0控制寄存器的UCCKPL和UCCKPH的组合值来控制。SPI主机模式下的时序如图7_19所示。
图7_19 SPI主机模式下的时序图
7.3.4 SPI的中断
SPI模式下,只有两个中断矢量:发送中断矢量和接收中断矢量。 (1)发送中断操作
当UCxTXBUF发送寄存器准备接收新的数据,发送中断标志位UCxTXIFG将会被置位,发生一次中断请求。当UCxTXIE和GIE均被置位时,也表示一次中断发生。当有新数据写入到UCxTXBUF发送寄存器时,发送中断标志位UCxTXIFG被自动清零。经过一个PUC或UCSWRST=1时, UCxTXIFG被置位,UCxTXIE被复位。 (2)接收中断操作
接收完一个新的数据且移入UCxRXBUF接收寄存器时,接收中断标志位UCxRXIFG将会被置位,发生一次中断请求。当UCxRXIE和GIE均被置位时,也表示一次中断发生。当从UCxRXBUF寄存器读出数据时, UCxRXIFG被自动清零。经过一个PUC或UCSWRST=1时, UCxRXIFG被置位,UCxRXIE被复位。
(3)中断的使用
USCI_Ax和USCI_Bx共用相同的中断矢量。接收中断矢量UCAxRXIFG和UCBxRXIFG被映射为同一个中断矢量,发送中断矢量UCAxTXIFG和UCBxTXIFG被映射为同一个中断矢量。应此在同一个MSP430F249系统上同时使用USCI_Ax和USCI_Bx是要注意其中断的应用。
实例7_6 SPI模式AD电压采集
任务要求:使用8bit串行ADC芯片TLC549实现对外部电压的采集,将其值在LCD上显示。
30
分析:TLC549是 TI公司生产的一种低价位、高性能的8位 A/D转换器,它以8位开关电容逐次逼近的方法实现 A/D转换,其转换速度小于 17us,最大转换速率为 40000HZ,4MHZ典型内部系统时钟,电源为 3V至 6V。它能方便地采用三线串行接口方式与各种微处理器连接,构成各种测控应用系统。其时序操作图如图7_20所示:
图7_20 TLC549时序图
该系统只需一个主机,且TLC549与控制MCU之间仅需3根线相连:使能端CS、时钟端CLK和数据输出端DATA。因此可以选用MSP430F249的SPI通信模式选用3线制对其进行控制即可。
1)硬件设计
其硬件电路连接如下图所示:TLC549的参考电压为2.048V,在实际应用中可由稳压芯片产生。TLC549的SDO数据输出端接MSP430F249的P3.2脚(UCB0SOMI),CS接P3.0脚(UCB0STE),SCLK接P3.3脚(UCB0CLK)。将P2口作为LCD的数据接口,P6.1和P6.2作为LCD的控制接口。如图7_21所示。
图7_21 实例7_6硬件仿真图
31
2)程序设计
#include \#include \#include \
const char table1[]=\olt:\long data1;
unsigned int data,num; char s[10];
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // 关闭看门狗 P2DIR |=0xff; //LCD 的数据输入
P6DIR=0x03; //LCD 的使能和控制信号
P3SEL |= 0x0c; // P3.3,2 SPI的时钟和数据输入
P3DIR |= 0x01; // P3.0 作为输出,控制TLC549的CS UCB0CTL0 |= UCMSB + UCMST + UCSYNC;
//将USCI_B0配置为 3线,最高位优先8位数据的SPI模式
UCB0CTL1 |= UCSSEL_2; //时钟为SMCLK UCB0BR0 = 0x0F; //fBITCLK=fSMCLK/15 UCB0BR1 = 0;
UCB0CTL1 &= ~UCSWRST; //取消复位
lcdinit(); //LCD显示的初始化 write_com(0x80); // 显示第一行字 for(num=0;num<5;num++) write_data(table1[num]); while(1) {
P3OUT &= ~0x01; // 使TLC549的/CS信号复位 UCB0TXBUF=0x00; //发送一个初始数据
while (!(IFG2 & UCB0RXIFG)); // 判断是否就收数据完毕 data=UCB0RXBUF; //将接收的数据读出
P3OUT |= 0x01; // Disable TLC549, /CS set
data1=(long)data*2048/255;
//因TLC549的参考电压为2.048V,将接收的数据转换毫伏值, sprintf(s,\使用见
//将长整型data1数据转化为8位长度的字符串类型并存于S字符串数组中 write_com(0x80+0x40); // 第二行显示电压值 for(num=0;num<10;num++) write_data(s[num]); } }
Lcd.c文件
#include
32
相关推荐: