网站图片分辨率尺寸,网页界面设计调查问卷,信息流优化师是干什么的,cms 主题 wordpress目录硬知识USCI通信模块USCI的UART模式1. USCI初始化和复位2. 异步通信字符格式3. 异步多机通信模式4. 自动波特率检测5. IrDA编码和解码6. 自动错误检测7. USCI接收使能8. USCI发送使能9. UART波特率的产生10. UART波特率的设置#xff08;重要#xff09;#xff08;1重要1低频波特率设置2过采样波特率设置UART API机翻USCI_A_UART的配置和控制函数参数用于发送和接收数据的函数参数管理USCI_A_UART中断和状态的函数参数DMA相关参数通过DriverLib库和硬件知识编写UART初始化函数原理图的串口部分上机实战平台Code Composer Studio 10.3.1
MSP430F5529 LaunchPad™ Development Kit (MSP‑EXP430F5529LP)
硬知识
USCI通信模块 通用串行通信接口USCI模块支持多种串行通信模式不同的USCI模块支持不同的通信模式。每个不同的USCI模块以不同的字母命名如USCI_A、USCI_B等。如果在一个MSP430单片机上实现了不止一个相同的USCI模块那么这些模块将以递增的数字命名。例如当一个MSP430单片机支持两个USCI_A模块时这两个模块应该被命名为USCI_A0和USCI_A1。具体可查阅相关芯片的数据手册来确定该芯片具有哪些USCI通信模块。 USCI_Ax模块支持以下模式 UART通信模式 具有脉冲整形的IrDA通信模式 具有自动波特率检测的LIN通信模式 SPI通信模式。 USCI_Bx模块支持以下通信模式 I2C通信模式 SPI通信模式。
USCI的UART模式 异步串行通信UART的特点如下 传输7位或8位数据可采用奇校验、偶校验或者无校验 具有独立的发送和接收移位寄存器 具有独立的发送和接收缓冲寄存器 支持最低位优先或最高位优先的数据发送和接收方式 内置多处理器系统包括线路空闲和地址位通信协议 通过有效的起始位检测将MSP430单片机从低功耗模式下唤醒 可编程实现分频因子为整数或小数的波特率 具有用于检测错误或排除错误的状态标志位 具有用于地址检测的状态标志位 具有独立的发送和接收中断能力。 在UART模式下USCI_Ax的结构如图所示。
1. USCI初始化和复位 通过产生一个PUC复位信号或者置位UCSWRST控制位可以使USCI模块复位。在产生一个PUC复位信号之后系统可自动置位UCSWRST控制位保持USCI模块在复位状态。若UCSWRST控制位置位将重置UCRXIE、UCTXIE、UCRXIFG、UCRXERR、UCBRK、UCPE、UCOE、UCFE、UCSTOE和UCBTOE寄存器并置位UCTXIFG中断标志位。清除UCSWRST控制位USCI模块才可进行工作。 因此可按照以下步骤进行初始化或重新配置USCI模块 ① 置位UCSWRST控制位 ② 在UCSWRST1时初始化所有的USCI寄存器包括UCTxCTL1 ③ 将相应的引脚端口配置为UART通信功能 ④ 软件清除UCSWRST控制位 ⑤ 通过设置接收或发送中断使能控制寄存器UCRXIE和UCTXIE或两者之一使能中断。
2. 异步通信字符格式 如图所示异步通信字符格式由5个部分组成一个起始位、7位或8位数据位、一个奇/偶/无校验位、一个地址位和一个或两个停止位。其中用户可以通过软件设置数据位、停止位的位数还可以设置奇偶校验位的有无。通过选择时钟源和波特率寄存器的数据来确定传输速率。UCMSB控制位用来设置传输的方向和选择最低位还是最高位先发送。一般情况下对于UART通信选择先发送最低位。
3. 异步多机通信模式 当两个设备异步通信时不需要多机通信协议。当3个或更多的设备通信时USCI支持两种多机通信模式即线路空闲和地址位多机模式。信息以一个多帧数据块从一个指定的源传送到一个或多个目的位置。在同一个串行链路上多个处理机之间可以用这些格式来交换信息实现在多处理机通信系统间的有效数据传输。控制寄存器的UCMODEx控制位可用来确定这两种模式这两种模式具有唤醒发送、地址特征和激活等功能。在两种多处理机模式下USCI数据交换过程可以用数据查询方式也可以用中断方式来实现。 1线路空闲多机模式 当UCMODEx控制位被配置为01时USCI就选择了线路空闲多机模式如图7.1.3所示。在这种模式下发送和接收数据线上的数据块被空闲时间分割。图a为数据块传输的总体示意图b为每个数据块中字符的传输示意。在图a中在字符的一个或两个停止位之后若收到10个以上的1则表示检测到接收线路空闲。在识别到线路空闲后波特率发生器就会被关断直到检测到下一个起始位才会重新被启动。当检测到空闲线路后将置位UCIDLE标志位。在图b中每两个数据块之间的线路空闲时间应少于10个空闲周期这样数据才能正确、正常地传输。 2地址位多机模式 当UCMODEx控制位被配置为10时USCI就选择了地址位多机模式。在这种模式下字符包含一个附加的位作为地址标志。地址位多机模式的格式如图所示。数据块的第1个字符带有一个置位的地址位用以表明该字符是一个地址。当接收到的字符地址位置位且被传送到UCAxRXBUF接收缓冲寄存器中USCI模块将置位UCADDR标志位。
4. 自动波特率检测 当UCMODEx控制位被配置为11时就选择了带自动波特率选择的UART模式。对于UART自动波特率检测方式在数据帧前面会有一个包含打断和同步域的同步序列。当在总线上检测到11个或更多个0时被识别为总线打断。如果总线打断的长度超过21位时间长度则将置位打断超时错误标志UCBTOE。当接收打断或同步域时USCI不能发送数据。同步域在打断域之后示意图如左图所示。 在1个字节里同步域包含数据055h如右图所示。同步是基于这种模式的第一个下降沿和最后一个下降沿之间的时间测量如果通过置位UCABDEN控制位将使能自动波特率检测功能则发送波特率发生器通常用于时间的测量。否则在该模式下只接收并不测量。测量的结果将被移送到波特率控制寄存器UCAxBR0、UCAxBR1和UCAxMCTL中。如果同步域的长度超过了可测量的时间将置位同步超时错误标志位UCSTOE。
5. IrDA编码和解码 当置位UCIREN控制位时将会使能IrDA编码器和解码器并对IrDA通信提供硬件编码和解码。 1IrDA编码 IrDA编码器会在UART数据流的基础上对UART传输中遇到的每一位0发送一个脉冲进行编码编码方式如图所示脉冲的持续时间由UCIRTXPLx进行定义。
2IrDA解码 当UCIRRXPL0时解码器检测到高电平否则检测低电平。除了模拟抗尖峰脉冲滤波器USCI内部还包含可编程数字滤波器用户可通过置位UCIRRXFE控制位使能该内部可编程数字滤波器。当UCIRRXFE置位时只有超过编程过滤长度的脉冲可以通过短脉冲被丢弃。过滤器长度UCIRRXFLx的编程计算公式如下
6. 自动错误检测 USCI模块接收字符时能够自动进行校验错误、帧错误、溢出错误和打断状态检测。当检测到它们各自的状态时会置位相应的中断标志位UCFE、UCPE、UCOE和UCBRK。当这些错误标志位置位时UCRXERR也会被置位。各种错误的含义和标志如表所示。
7. USCI接收使能 通过清除UCSWRST控制位可以使能USCI模块此时接收端准备接收数据并处于空闲状态接收波特率发生器处于准备状态但并没有产生时钟。 起始位的下降沿可以使能波特率发生器。UART状态机可检测有效起始位如果未检测到有效起始位则UART状态机返回空闲状态同时停止波特率发生器如果检测到有效起始位则字符将会被接收。 当选择线路空闲多机模式时UCMODEx01在接收完一个字符之后UART状态机检测空闲线路。若检测到一个起始位则接收下一个字符。否则如果在线路上检测到10个1就会置位UCIDLE空闲标志位并且UART状态机返回空闲状态同时波特率发生器被禁止。 抑制接收数据脉冲干扰能够防止USCI模块意外启动任何在UCAxRXD的时间少于抗尖峰脉冲时间tt(近似150ns)的短时脉冲都将被USCI忽略紧接着进行初始化如左图所示若在UCAxRXD上的短时脉冲时间少于ttUSCI并没有开始接收数据。 当一个尖峰脉冲时间长于tt或者在UCAxRXD上发生一个有效的起始位USCI开始接收工作并采用多数表决方式如右图所示。如果多数表决没有检测到起始位则USCI停止接收字符。
8. USCI发送使能 通过清除UCSWRST控制位可以使能USCI模块此时发送端准备发送数据并处于空闲状态发送波特率发生器处于准备状态但是并没有产生时钟。 通过写数据到发送缓冲寄存器中USCI就可以开始发送数据。波特率发生器开始工作当发送移位寄存器为空时在下一个BITCLK上发送缓冲寄存器中的数据将被移送到发送移位寄存器中。 在前一字节发送完成之后只要发送缓冲寄存器UCAxTXBUF中有新数据发送即可继续。若前一字节发送完成之后发送缓冲寄存器UCAxTXBUF中并没有写入新的数据发送端将返回空闲状态同时停止波特率发生器。
9. UART波特率的产生 USCI波特率发生器可以从非标准的时钟源频率中产生标准的波特率可以通过UCOS16控制位选择系统提供的两种操作模式分别为产生低频波特率模式UCOS160和产生过采样波特率模式UCOS161。UART波特率的参考时钟来自于BRCLKBRCLK可以通过UCSSELx控制位配置为外部时钟UCAxCLK或内部时钟ACLK或SMCLK。 1产生低频波特率模式 当UCOS160时选择低频波特率模式。该模式允许从低频时钟源产生标准的波特率例如从32768Hz晶振产生9600bps的波特率。通过使用较低的输入频率可以降低系统的功耗。注意在高频输入或高分频设置下使用这种模式将导致在更小的窗口中采用多数表决方式因此会降低多数表决法的优势。 在低频模式下波特率发生器使用1个预分频器和1个调制器产生时钟时序。在这种组合下产生的波特率支持小数分频。在这种模式下最大的USCI波特率是UART源时钟频率BRCLK的1/3。 每一位的时序如图所示。对于接收的每一位为了确定该位的值采用多数表决法即3取2表决法。每次表决时采样3次最终该位的值至少在采样中出现两次。这些采样发生在(N/2-1/2)N/2和(N/21/2)个BRCLK周期处如图中的方框所示这里的N是每个BITCLK包含的BRCLKs的数值图中的m为调制设置具体请参见下表。 2产生过采样波特率模式 当UCOS161时选择过采样模式。该模式支持在较高的输入参考时钟频率下产生较高的UART波特率。该模式的参考时钟为经预分频器和调制器产生的BITCLK16时钟该时钟频率为BITCLK的1/16。因此在计算分频系数时需将波特率发生器的参考时钟频率除以16之后再进行计算。例如若波特率发生器的参考时钟BITCLK选择内部的SMCLK1048576Hz最终需要产生9600bps的波特率首先将BITCLK除以16为65536Hz作为该模式下的波特率参考时钟计算分频系数为n65536/96006.83。 这种组合方式支持BITCLK16和BITCLK产生不是整数倍的波特率在这种情况下最大的USCI波特率是UART源时钟频率的1/16。当UCBRx设置为0或1时将忽略第一级分频器和调制器BITCLK16等于BITCLK在这种情况下BITCLK16没有调制因此将忽略UCBRFx位。 BITCLK16的调制是建立在如下表所示的UCBRFx设置的基础之上的。表中的0和1表示m的值m1时所对应的BITCLK的周期比m0时所对应的BITCLK的周期要长具体原理请参考产生低频波特率模式下的调制原理。
10. UART波特率的设置重要 设置方法设置波特率时首先要选择合适的时钟源。对于较低的波特率(9600bps以下)可以选择ACLK作为时钟源这使得在LPM3模式下仍然能够使用串口。由于串口接收过程中有一个三取二表决逻辑这需要至少3个时钟周期因此要求分频系数必须大于3。所以在波特率高于9600bps的情况下应选择频率较高的SMCLK作为时钟源。在某些特殊应用中也可以使用外部的时钟输入作为波特率发生器的时钟源。 对于给定的BRCLK时钟源所使用的波特率将决定分频因子N计算公式为 分频因子N通常不是一个整数值 因此至少需要一个分频器和一个调制器来尽可能接近分频因子。如果N等于或大于16可以通过置位UCOS16选择过采样波特率产生模式。
1低频波特率设置
在低频模式下分频因子的整数部分通过预分频器实现配置方式为(其中INT为取整)
小数部分由调制器实现配置方式为(round为取附近整数) 【例1】 在MSP430单片机中使用ACLK作为串口时钟源波特率设为4800bps。 分析在ACLK32768Hz时产生4800bps波特率需要的分频系数是32768/48006.83。整数部分为6小数部分为0.83。将整数部分赋给UCA0BR寄存器调制器分频余数为0.83 × 8 6.64取最接近的整数7因此将7赋给UCBRS控制位。
2过采样波特率设置
在过采样模式下预分频设置为 调制器设置为 【例2】 在MSP430单片机中使用SMCLK作为串口时钟源波特率设置为9600bps。 分析在SMCLK1048576Hz时产生9600bps波特率需要的分频系数N1048576/ 9600109.23大于16分频因此应选择过采样波特率产生模式预分频UCBR应设置为INT(N/16)INT(6.83)6。调制器UCBRF应设置为0.83 × 16 13.28取最接近的整数13因此将13赋给UCBRF控制位。 波特率设置也可直接参考下表 也可以从MSP430 USCI/EUSCI UART Baud Rate Calculation中获取
UART API机翻
USCI_A_UART API被分为几组功能: USCI_A_UART模块的配置和控制的函数 用于发送和接收数据的函数 以及处理中断处理和处理DMA的函数。
USCI_A_UART的配置和控制函数
USCI_A_UART_init(uint16_t baseAddress, USCI_A_UART_initParam ∗param)
//初始化函数
USCI_A_UART_enable(uint16_t baseAddress)
//使能UART模块
USCI_A_UART_disable(uint16_t baseAddress)
//失能UART模块
USCI_A_UART_setDormant(uint16_t baseAddress)
//将UART模块设置为休眠模式
USCI_A_UART_resetDormant(uint16_t baseAddress)
//从休眠模式重新启用UART模块参数
baseAddress 是USCI_A_UART模块的基地址
USCI_A0_BASE
USCI_A1_BASEUSCI_A_UART_initParam 结构体
typedef struct USCI_A_UART_initParam {//! Selects Clock source.//! \n Valid values are://! - \b USCI_A_UART_CLOCKSOURCE_SMCLK//! - \b USCI_A_UART_CLOCKSOURCE_ACLKuint8_t selectClockSource;//! Is the value to be written into UCBRx bitsuint16_t clockPrescalar;//! Is First modulation stage register setting. This value is a pre-//! calculated value which can be obtained from the Device Users Guide.//! This value is written into UCBRFx bits of UCAxMCTLW.uint8_t firstModReg;//! Is Second modulation stage register setting. This value is a pre-//! calculated value which can be obtained from the Device Users Guide.//! This value is written into UCBRSx bits of UCAxMCTLW.uint8_t secondModReg;//! Is the desired parity.//! \n Valid values are://! - \b USCI_A_UART_NO_PARITY [Default]//! - \b USCI_A_UART_ODD_PARITY//! - \b USCI_A_UART_EVEN_PARITYuint8_t parity;//! Controls direction of receive and transmit shift register.//! \n Valid values are://! - \b USCI_A_UART_MSB_FIRST//! - \b USCI_A_UART_LSB_FIRST [Default]uint8_t msborLsbFirst;//! Indicates one/two STOP bits//! \n Valid values are://! - \b USCI_A_UART_ONE_STOP_BIT [Default]//! - \b USCI_A_UART_TWO_STOP_BITSuint8_t numberofStopBits;//! Selects the mode of operation//! \n Valid values are://! - \b USCI_A_UART_MODE [Default]//! - \b USCI_A_UART_IDLE_LINE_MULTI_PROCESSOR_MODE//! - \b USCI_A_UART_ADDRESS_BIT_MULTI_PROCESSOR_MODE//! - \b USCI_A_UART_AUTOMATIC_BAUDRATE_DETECTION_MODEuint8_t uartMode;//! Indicates low frequency or oversampling baud generation//! \n Valid values are://! - \b USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION//! - \b USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATIONuint8_t overSampling;
} USCI_A_UART_initParam;其中的clockPrescalarfirstModRegsecondModRegoverSampling 可在MSP430 USCI/EUSCI UART Baud Rate Calculation中获取
用于发送和接收数据的函数
USCI_A_UART_transmitData(uint16_t baseAddress, uint8_t transmitData)
//通过UART模块传输一个字节
USCI_A_UART_receiveData(uint16_t baseAddress)
//接收一个已发送到UART模块的字节。
USCI_A_UART_transmitAddress(uint16_t baseAddress, uint8_t transmitAddress)
//Transmits the next byte to be transmitted marked as address depending on selected multiprocessor mode
USCI_A_UART_transmitBreak(uint16_t baseAddress)
//传输中断参数
baseAddress 是USCI_A_UART模块的基地址
USCI_A0_BASE
USCI_A1_BASEtransmitData UART模块要传输的数据 transmitAddress is the next byte to be transmitted
管理USCI_A_UART中断和状态的函数
USCI_A_UART_enableInterrupt(uint16_t baseAddress, uint8_t mask)
//启用UART中断
USCI_A_UART_disableInterrupt(uint16_t baseAddress, uint8_t mask)
//失能UART中断
USCI_A_UART_getInterruptStatus(uint16_t baseAddress, uint8_t mask)
//获取当前UART中断状态。这将根据传递的标志返回UART模块的中断状态
USCI_A_UART_clearInterrupt(uint16_t baseAddress, uint8_t mask)
//清除UART中断源使其不再断言。当使用中断向量生成器时最高中断标志将自动清除
USCI_A_UART_queryStatusFlags(uint16_t baseAddress, uint8_t mask)
//获取当前UART状态标志。这将根据传递的标志返回UART模块的状态。参数
baseAddress 是USCI_A_UART模块的基地址
USCI_A0_BASE
USCI_A1_BASEmask USCI_A_UART_enableInterrupt、 USCI_A_UART_disableInterrupt
/*
is the bit mask of the interrupt sources to be enabled. Mask value is the logical
OR of any of the following:
*/
USCI_A_UART_RECEIVE_INTERRUPT // - Receive interrupt
USCI_A_UART_TRANSMIT_INTERRUPT // - Transmit interrupt
USCI_A_UART_RECEIVE_ERRONEOUSCHAR_INTERRUPT // - Receive erroneous-character interrupt enable
USCI_A_UART_BREAKCHAR_INTERRUPT // - Receive break character interrupt enableUSCI_A_UART_getInterruptStatus、 USCI_A_UART_clearInterrupt:
/*
is the masked interrupt flag status to be returned. Mask value is the logical OR
of any of the following:
*/
USCI_A_UART_RECEIVE_INTERRUPT_FLAG // - Receive interrupt flag
USCI_A_UART_TRANSMIT_INTERRUPT_FLAG // - Transmit interrupt flagUSCI_A_UART_queryStatusFlags:
/*
is the masked interrupt flag status to be returned. Mask value is the logical OR
of any of the following:
*/
USCI_A_UART_LISTEN_ENABLE
USCI_A_UART_FRAMING_ERROR
USCI_A_UART_OVERRUN_ERROR
USCI_A_UART_PARITY_ERROR
USCI_A_UART_BREAK_DETECT
USCI_A_UART_RECEIVE_ERROR
USCI_A_UART_ADDRESS_RECEIVED
USCI_A_UART_IDLELINE
USCI_A_UART_BUSYDMA相关
USCI_A_UART_getReceiveBufferAddressForDMA(uint16_t baseAddress)
//返回UART DMA模块的RX缓冲区地址
USCI_A_UART_getTransmitBufferAddressForDMA(uint16_t baseAddress)
//返回UART DMA模块的TX缓冲区地址参数
baseAddress 是USCI_A_UART模块的基地址
USCI_A0_BASE
USCI_A1_BASE通过DriverLib库和硬件知识编写UART初始化函数
根据之前的知识我们可以写出如下初始化函数 baseAddress的参数可选为 USCI_A0_BASE、USCI_A1_BASE 分别对应P3.3、P3.4和P4.4、P4.5 Baudrate为目标波特率
bool UART_Init(uint16_t baseAddress, uint32_t Baudrate)
{float UART_Temp 0;USCI_A_UART_initParam huart {0};//将所用引脚复用为UART模式if(baseAddress USCI_A0_BASE) //P3.3, P3.4 USCI_A0 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN3);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN4);}else if(baseAddress USCI_A1_BASE) //P4.4, P4.5 USCI_A1 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5);}//当目标波特率较低时UART选用时钟源为ACLK反之选择SMCLK//调用UCS_getACLK/UCS_getSMCLK前需正确调用UCS_setExternalClockSource函数我已加到SystemClock_Init函数中if(Baudrate 9600){huart.selectClockSource USCI_A_UART_CLOCKSOURCE_ACLK;UART_Temp (float)UCS_getACLK()/Baudrate;}else{huart.selectClockSource USCI_A_UART_CLOCKSOURCE_SMCLK;UART_Temp (float)UCS_getSMCLK()/Baudrate;}if(UART_Temp 16) //当分频因子小于16时采用低频波特率设置huart.overSampling USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;else //反之采用过采样波特率设置{huart.overSampling USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;UART_Temp / 16;}huart.clockPrescalar (int)UART_Temp;if(huart.overSampling USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION){ //低频波特率设置 UCBRSxhuart.secondModReg (int)((UART_Temp - huart.clockPrescalar) * 8);}else{ //过采样波特率设置 UCBRFxhuart.firstModReg (int)((UART_Temp - huart.clockPrescalar) * 16);}huart.parity USCI_A_UART_NO_PARITY;huart.msborLsbFirst USCI_A_UART_LSB_FIRST;huart.numberofStopBits USCI_A_UART_ONE_STOP_BIT;huart.uartMode USCI_A_UART_MODE;if (STATUS_FAIL USCI_A_UART_init(baseAddress, huart)){ //初始化对应串口return STATUS_FAIL;}//Enable UART module for operation 使能对应串口USCI_A_UART_enable(baseAddress); //Enable Receive Interrupt 启用串口中断USCI_A_UART_clearInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT); USCI_A_UART_enableInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT); return STATUS_SUCCESS;
}串口中断服务函数 接收一个字符就回发一个
//******************************************************************************
//
//This is the USCI_A0 interrupt vector service routine.
//
//******************************************************************************
#pragma vectorUSCI_A0_VECTOR
__interrupt void USCI_A0_ISR (void)
{uint8_t receivedData 0;switch (__even_in_range(UCA0IV,4)){//Vector 2 - RXIFGcase 2:receivedData USCI_A_UART_receiveData(USCI_A0_BASE);USCI_A_UART_transmitData(USCI_A0_BASE,receivedData);break;default:break;}
}//******************************************************************************
//
//This is the USCI_A1 interrupt vector service routine.
//
//******************************************************************************
#pragma vectorUSCI_A1_VECTOR
__interrupt void USCI_A1_ISR (void)
{uint8_t receivedData 0;switch (__even_in_range(UCA1IV,4)){//Vector 2 - RXIFGcase 2:receivedData USCI_A_UART_receiveData(USCI_A1_BASE);USCI_A_UART_transmitData(USCI_A1_BASE,receivedData);break;default:break;}
}原理图的串口部分
USCI_A0 UART对应P3.3、P3.4 USCI_A1 UART对应P4.4、P4.5 如图所示MSP430F5529的USCI_A1 UART 通过 eZ-FET 与USB通讯 换句话说插上microUSB后识别到的串口应为USCI_A1 UART
上机实战
整个源文件如下
#include driverlib.h#define MCLK_IN_HZ 25000000#define delay_us(x) __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x) __delay_cycles((MCLK_IN_HZ/1000*(x)))void SystemClock_Init(void)
{PMM_setVCore(PMM_CORE_LEVEL_3); //高主频工作需要较高的核心电压//XT1引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN5);//起振XT1UCS_turnOnLFXT1(UCS_XT1_DRIVE_3,UCS_XCAP_3);//XT2引脚复用GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN2);GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, GPIO_PIN3);//起振XT2UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ);//XT2作为FLL参考时钟先8分频再50倍频 4MHz / 8 * 50 25MHzUCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_8);UCS_initFLLSettle(25000, 50);//XT1作为ACLK时钟源 32768HzUCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为MCLK时钟源 25MHzUCS_initClockSignal(UCS_MCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//DCOCLK作为SMCLK时钟源 25MHzUCS_initClockSignal(UCS_SMCLK, UCS_DCOCLK_SELECT, UCS_CLOCK_DIVIDER_1);//设置外部时钟源的频率使得在调用UCS_getMCLK, UCS_getSMCLK 或 UCS_getACLK时可得到正确值UCS_setExternalClockSource(32768, 4000000);
}bool UART_Init(uint16_t baseAddress, uint32_t Baudrate)
{float UART_Temp 0;USCI_A_UART_initParam huart {0};if(baseAddress USCI_A0_BASE) //P3.3, P3.4 USCI_A0 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P3, GPIO_PIN3);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P3, GPIO_PIN4);}else if(baseAddress USCI_A1_BASE) //P4.4, P4.5 USCI_A1 TXD/RXD{GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5);}if(Baudrate 9600){huart.selectClockSource USCI_A_UART_CLOCKSOURCE_ACLK;UART_Temp (float)UCS_getACLK()/Baudrate;}else{huart.selectClockSource USCI_A_UART_CLOCKSOURCE_SMCLK;UART_Temp (float)UCS_getSMCLK()/Baudrate;}if(UART_Temp 16)huart.overSampling USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;else{huart.overSampling USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;UART_Temp / 16;}huart.clockPrescalar (int)UART_Temp;if(huart.overSampling USCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION){huart.secondModReg (int)((UART_Temp - huart.clockPrescalar) * 8);}else{huart.firstModReg (int)((UART_Temp - huart.clockPrescalar) * 16);}huart.parity USCI_A_UART_NO_PARITY;huart.msborLsbFirst USCI_A_UART_LSB_FIRST;huart.numberofStopBits USCI_A_UART_ONE_STOP_BIT;huart.uartMode USCI_A_UART_MODE;if (STATUS_FAIL USCI_A_UART_init(baseAddress, huart)){return STATUS_FAIL;}//Enable UART module for operationUSCI_A_UART_enable(baseAddress);//Enable Receive InterruptUSCI_A_UART_clearInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);USCI_A_UART_enableInterrupt(baseAddress, USCI_A_UART_RECEIVE_INTERRUPT);return STATUS_SUCCESS;
}int main(void)
{WDT_A_hold(WDT_A_BASE);SystemClock_Init();UART_Init(USCI_A1_BASE, 115200);//interrupts enabled__bis_SR_register(GIE);while(1){}
}//******************************************************************************
//
//This is the USCI_A0 interrupt vector service routine.
//
//******************************************************************************
#pragma vectorUSCI_A0_VECTOR
__interrupt void USCI_A0_ISR (void)
{uint8_t receivedData 0;switch (__even_in_range(UCA0IV,4)){//Vector 2 - RXIFGcase 2:receivedData USCI_A_UART_receiveData(USCI_A0_BASE);USCI_A_UART_transmitData(USCI_A0_BASE,receivedData);break;default:break;}
}//******************************************************************************
//
//This is the USCI_A1 interrupt vector service routine.
//
//******************************************************************************
#pragma vectorUSCI_A1_VECTOR
__interrupt void USCI_A1_ISR (void)
{uint8_t receivedData 0;switch (__even_in_range(UCA1IV,4)){//Vector 2 - RXIFGcase 2:receivedData USCI_A_UART_receiveData(USCI_A1_BASE);USCI_A_UART_transmitData(USCI_A1_BASE,receivedData);break;default:break;}
}
在main函数中通过
UART_Init(USCI_A1_BASE, 115200); 初始化我们用到的串口 连上串口调试助手成功回显 修改波特率通讯仍能成功