大家好!
我有一个使用 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、¶m){
返回;
}
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、¶m);
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);
}