This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430FR2355:cs_getSMCLK ()函数、UART 问题

Guru**** 2482105 points
Other Parts Discussed in Thread: MSP430FR2355

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1257765/msp430fr2355-cs_getsmclk-function-problem-with-uart

器件型号:MSP430FR2355

大家好!

我有一个使用 MSP430FR2355的应用。

我的应用包括读取 ADC、从 I2C 器件读取一些信息并将它们发送到 UART。

我已经使用了 ADC 和 UART、但在尝试使用 I2C 函数时遇到了问题。

当我使用 CS_getSMCLK (); UART 不能工作时,似乎会自动更改 UART 波特率(因为数据发送到 UART 的格式不正确)。

当我删除  CS_getSMCLK()时,它会正常运行。

那么、任何人都可以告诉我、我如何解决该问题。

感谢你的帮助。

以下是我的所有代码。

#包含
#include "driverlib.h"
#include "board.h"
#include "stdarg.h"
/**
* main.c
*/
void putc (unsigned b);
void puts (char *s);
静态 void xtoa (unsigned long x、const unsigned long *dp);
静态空 puth (unsigned n);
void printf (char *格式、...);
void uart0Init (void);
void adcInit (void);
void i2cInit (void);
void i2cScanner (void);
uint8_t RXData = 0、TXData = 0;
uint8_t volatile uartFlag = 0、adcFlag=0;
uint16_t adcValue=0;
uint8_t addr=0;
uint32_t clock_val=0;
空主函数(空)
{
//停止看门狗计时器
WDT_A_HOLD (WDT_A_BASE);

//设置 ACLK = REFOCLK,时钟分频器为1
CS_initClockSignal (CS_ACLK、CS_REFOCLK_SELECT、CS_CLOCK_DIVIDER_1);
//设置 SMCLK = DCO、分频器为1
CS_initClockSignal (CS_SMCLK、CS_DCOCLKDIV_SELECT、CS_CLOCK_DIVIDER_1);
//设置 MCLK = DCO,分频器为1
CS_initClockSignal (CS_MCLK、CS_DCOCLKDIV_SELECT、CS_CLOCK_DIVIDER_1);
// CS_setupDCO (CS_BYPASS_MODE);

// clock_val=CS_getSMCLK ();

//将 LED1设置为输出引脚。
GPIO_setAsOutputPin (GPIO_PORT_LED1、GPIO_PIN_LED1);
//将 LED2设置为输出引脚。
GPIO_setAsOutputPin (GPIO_PORT_LED2、GPIO_PIN_LED2);
/*
*禁用 GPIO 上电默认高阻抗模式以激活
*先前配置的端口设置
*/
GPIO_setAPeripheralModuleFunctionInputPin (GPIO_PORT_UCA0TXD、GPIO_PIN_UCA0TXD、GPIO_FUNCTION_UCA0TXD);
GPIO_setAPeripheralModuleFunctionInputPin (GPIO_PORT_UCA0RXD、GPIO_PIN_UCA0RXD、GPIO_FUNCTION_UCA0RXD);

//将 A5设置为输入引脚。
GPIO_setAPeripheralModuleFunctionInputPin (GPIO_PORT_ADC5、GPIO_PIN_ADC5、GPIO_FUNCTION_ADC5);

GPIO_setAsPeripheralModuleFunctionInputPin (GPIO_PORT_UCB.S、GPIO_PIN_UCB.S、GPIO_FUNCTION_UCB.S);
GPIO_setAsPeripheralModuleFunctionInputPin (GPIO_PORT_UCB0SDA、GPIO_PIN_UCB0SDA、GPIO_FUNCTION_UCB0SDA);

PMM_unlockLPM5 ();
uart0Init ();
printf ("UART:%s\r\n "、"Done");
// adcInit ();
// i2cInit ();


// char * s ="NJC 的 MSP430 LaunchPad Blog";
// char c ='!';
// int i =-12345;
//无符号 u = 4321;
//长整型 l =-123456780;
// long unsigned n = 1098765432;
//无符号 x = 0xABCD;
//
// printf ("String %s\r\n",s);
// printf ("Char %c\r\n "、c);
// printf ("整数%I\r\n"、i);
// printf ("unsigned %u\r\n",u);
// printf ("long %l\r\n",l);
// printf ("unsigned long %n\r\n",n);
// printf ("hex %x\r\n"、x);


__enable_interrupt ();

用于(;;)
{
// if (adcFlag==1)
//{
// adcFlag=0;
// printf ("ADC 值:%u\r\n",adcValue);
//_delay_cycles (20000);
// adc_startConversion (adc_BASE、adc_sINGLECHANNEL);
//}
// if (uartFlag==1)
//{
// uartFlag=0;
// EUSCI_A_UART_translData (EUSCI_A0_BASE、RXData);
//}
i2cScanner ();

//ADC10中断服务例程
#if defined (__TI_Compiler_version__)|| defined (__IAR_SYSTEMS_ICC__)
#pragma vector=adc_vector
__中断
#Elif 已定义(_ GNU _)
__attribute__(interrupt (ADC_vector))
#endif
空 ADC_ISR (空)
{
开关(__ even_in_range (ADCIV、12)){
情形0:中断;//无中断
案例2:中断;//转换结果溢出
案例4:中断;//转换时间溢出
案例6:中断;//ADC10HI
案例8:中断;//ADC10LO
案例10:中断;//ADC10IN
案例12://ADC10IFG0
//(通过读取存储器缓冲器来自动清除 ADC10IFG0)
adcValue = ADC_getResults (ADC_BASE);
GPIO_toggleOutputOnPin (GPIO_PORT_LED1、GPIO_PIN_LED1);
__ bic_SR_register_on_exit (CPUOFF);
ADC_clearInterrupt (ADC_base、ADC_completed_interrupt);
adcFlag=1;
中断;
默认值:中断;

//这是 USCI_A0中断矢量服务例程。
//
//*****
#if defined (__TI_Compiler_version__)|| defined (__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_vector
__中断
#Elif 已定义(_ GNU _)
_attribute_(interrupt (USCI_A0_vector))
#endif
void EUSCI_A0_ISR (void)
{
switch (__even_in_range (UCA0IV、USCI_UART_UCTXCPTIFG))
{
USCI_NONE:中止;
案例 USCI_UART_UCRXIFG:
RXData = EUSCI_A_UART_receiveData (EUSCI_A0_BASE);
//检查值
uartFlag = 1;
// EUSCI_A_UART_translData (EUSCI_A0_BASE、RXData);
中断;
USCI_UART_UCTXIFG 情况:中断;
案例 USCI_UART_UCSTTIFG:中断;
案例 USCI_UART_UCTXCPTIFG:中断;

void putc (unsigned b)
{
EUSCI_A_UART_translData (EUSCI_A0_BASE、b);

void puts (字符*s)
{
字符;
//循环通过字符串"S"中的每个字符
while (c =* s++)
{
EUSCI_A_UART_translData (EUSCI_A0_BASE、c);


静态 const unsigned long dv[]=
{
// 4294967296 // 32位无符号最大值
1000000000、//+0
100000000、//+1
10000000、//+2
1000000、//+3
100000、//+4
// 65535 // 16位无符号最大值
10000、//+5
1000、//+6
100、//+7
10、//+8
1、//+9
};
静态 void xtoa (unsigned long x、const unsigned long * DP)
{
字符;
无符号长整型 d;
如果(x){
while (x <* DP)
++DP;
请执行{
D =*DP++;
C='0';
while (x >= d)
++c、x -= d;
putc (c);
} while (!(d&1));
}其他
putc ('0');

静态空 PUTH (无符号 n)
{
Static const char hex[16]={'0'、'1'、'2'、'3'、'4'、 '5'、'6'、'7'、'8'、
"9"、"A"、"B"、"C"、"D"、 'E'、'F'};
putc (hex[n & 15]);

void printf (char *格式、...)
{
字符;
INT I;
长 n;

va_list a;
va_start (a、格式);
while (c =*format++){
if (c ='%'){
switch (c =*format++){
案例's'://字符串
puts (va_arg (a、char*));
中断;
案例'c'://特性
putc (va_arg (a、char));
中断;
大小写为"i":// 16位整数
大小写'u':// 16位无符号
i = va_arg (a、int);
if (c =='I'&& i < 0) i =-I、putc ('-');
xtoa ((unsigned) i、dv+5);
中断;
case 'l':// 32位长
大小写为"n":// 32位无符号长整型
N = va_arg (a、long);
if (c =='l'&& n < 0) n =-n、putc ('-');
xtoa ((unsigned long) n、dv);
中断;
用例"x":// 16位十六进制
i = va_arg (a、int);
PUTH (i >> 12);
坑(i >> 8);
坑(i >> 4);
坑(i);
中断;
情形0:返回;
默认值:转至 bad_fmt;

}其他
bad_fmt:putc (c);

va_end (a);

void uart0Init (void)
{
//配置 UART 引脚

//配置 UART
//SMCLK = 1MHz、波特率= 115200
//UCBRx = 8、UCBRFx = 0、UCBRSx = 0xD6、UCOS16 = 0
EUSCI_A_UART_initParam 参数={0};
param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
param.clockPrescalar = 8;
param.firstModReg = 0;
param.secondModReg = 0xD6;
param.patch = EUSCI_A_UART_NO_奇 偶校验;
param.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
param.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT;
param.uartMode = EUSCI_A_UART_MODE;
param.oversample = EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_generation;

if (STATUS_FAIL == EUSCI_A_UART_init (EUSCI_A0_BASE、&param){
返回;

EUSCI_A_UART_ENABLE (EUSCI_A0_BASE);

EUSCI_A_UART_clearInterrupt (EUSCI_A0_BASE、EUSCI_A_UART_RECEIVE_INTERRUPT);

//启用 USCI_A0 RX 中断
EUSCI_A_UART_enableInterrupt (EUSCI_A0_BASE、EUSCI_A_UART_RECEIVE_INTERRUPT);

void adcInit (void)
{

//初始化 ADC 模块
/*
* ADC 模块的基地址
*使用内部 ADC 位作为采样/保持信号开始转换
*使用 MODOSC 5MHZ 数字振荡器作为时钟源
*使用默认值为1的时钟分频器
*/
ADC_init (ADC_base、ADC_SAMPLEHOLDSOURCE_SC、ADC_CLOCKSOURCE_ADCOSC、ADC_CLOCKDIVIDER_1);
ADC_ENABLE (ADC_BASE);

/*
* ADC 模块的基地址
* 16个时钟周期的采样/保持
*不启用多次采样
*/
ADC_setupSamplingTimer (ADC_base、ADC_CYCLEHOLD_16_CYCLES、ADC_MULTIPLESAMPLESDISABLE);
//配置内存缓冲区
/*
* ADC 模块的基地址
*使用输入 A7
*使用 AVcc 正基准
*使用 AVss 的负基准
*/
ADC_configureMemory (ADC_base、ADC_INPUT_A5、ADC_VREFPOS_AVCC、ADC_VREFNEG_AVSS);
//启用并启动转换
//在单通道中,一个通道的重复转换成单个内存缓冲区
ADC_clearInterrupt (ADC_base、ADC_completed_interrupt);

//启用存储器缓冲中断
ADC_enableInterrupt (ADC_base、ADC_Completed_interrupt);
adc_startConversion (adc_BASE、adc_sINGLECHANNEL);

空 i2cInit (void)
{
//为 I2C 配置引脚
/*
*选择端口4
*将引脚6、7设置为带功能的输入、(UCB0SIMO/UCB0SDA、UCB0SOMI/UCB.S)。
*/
printf ("String %s\r\n"、"InitI2C");
/*
*禁用 GPIO 上电默认高阻抗模式以激活
*先前配置的端口设置
*/
EUSCI_B_I2C_initMasterParam 参数={0};
param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
param.i2cClk = CS_getSMCLK ();
param.datarate = EUSCI_B_I2C_SET_DATA_RATE_400KBPS;
param.byteCounterThreshold = 1;
param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
// EUSCI_B_I2C_setSlaveAddress (EUSCI_B0_BASE、SLAVE_ADDRESS);
EUSCI_B_I2C_initMaster (EUSCI_B0_BASE、&param);
EUSCI_B_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_TRANSMIT_MODE);
EUSCI_B_I2C_ENABLE (EUSCI_B0_BASE);
EUSCI_B_I2C_clearInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);

EUSCI_B_I2C_enableInterrupt (EUSCI_B0_BASE、EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT);
//
printf ("String %s\r\n"、"InitI2C done");

空 i2cScanner (空)
{
// printf ("字符串%s\r\n "、"开始扫描");
EUSCI_B_I2C_setSlaveAddress (EUSCI_B0_BASE、addr);
EUSCI_B_I2C_setMode (EUSCI_B0_BASE、EUSCI_B_I2C_TRANSMIT_MODE);
if (EUSCI_B_I2C_masterSendSingleByteWithTimeout (EUSCI_B0_BASE、0x00、10))
{
printf("-------- 在%x\r\n"、addr 中找到开发;
GPIO_toggleOutputOnPin (GPIO_PORT_LED1、GPIO_PIN_LED1);

ADDR++;
如果(addr=0x8F)
{
Addr=0;
printf ("字符串%s\r\n "、"已完成");
GPIO_toggleOutputOnPin (GPIO_PORT_LED2、GPIO_PIN_LED2);
__delay_cycles (2000000);

__ delay_cycles (200000);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    有两个地方使用 CS_getSMCLK()。 您能告诉我哪个导致了问题吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好。

    感谢您的答复。

     问题已经解决。  

    下面的配置时钟解决了问题。

    CS_initClockSignal (CS_FLLREF、CS_REFOCLK_SELECT、CS_CLOCK_DIVIDER_1);

    //设置比率和所需的 MCLK 频率并初始化 DCO
    CS_initFLLSettle (CS_SMCLK_desired FREQUENCY_IN_kHz、CS_SMCLK_FLLREF_RATIO);

    //设置 ACLK = REFOCLK,时钟分频器为1
    CS_initClockSignal (CS_ACLK、CS_REFOCLK_SELECT、CS_CLOCK_DIVIDER_1);
    //设置 SMCLK = DCO、分频器为1
    CS_initClockSignal (CS_SMCLK、CS_DCOCLKDIV_SELECT、CS_CLOCK_DIVIDER_1);
    //设置 MCLK = DCO,分频器为1
    CS_initClockSignal (CS_MCLK、CS_DCOCLKDIV_SELECT、CS_CLOCK_DIVIDER_1);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这是真的很高兴听到,你解决了由你的雪橇。