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.

[参考译文] CCS/MSP430FR2311:FR2000多时基示例移植到2311

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/929321/ccs-msp430fr2311-fr2000-multiple-timebases-example-porting-to-2311

器件型号:MSP430FR2311

工具/软件:Code Composer Studio

我正在尝试将 SLAA766移植到 MSP430FR2000 示例、以便通过 UART 控制 RGB LED、并将其移植到 MSP430FR2311。 我在 SLAA812中提出了以下更改建议

1.将定时器更改为 Timer1_B  

2.将 PWM 的引脚更改为 P1.0、P2.0、P2.1

现在、当我执行以下代码时、它始终将我抛出为未处理的中断/ISR 陷阱。 问题是什么?

#include 
#include 

//包含每个颜色选择
的 RGB LED 的低(开启)周期、其中 uint8_t colorsLow[12][3]={
//{R、G、B}
{134、1、1}、//红色
{134、15、1}、//橙色
{134、20、1}、//橙色
{134、30、1}、//橙色-黄色
{134、55、1}、//黄色
{67、80、1}、//黄色-绿色
{1、134、1}、//绿色
{1、134、134}、//绿色-蓝色
{1、1、134}、//蓝色
{67、1、134}、//蓝色-紫色
{134、1、134}、//紫色
{134、1、80}//紫色
红色};
//包含每个颜色选择
的 RGB LED 的高(关闭)周期 uint8_t colorsHigh[12][3]={
//{R、G、B}
{1、134、134}、//红色
{1、120、134}、//橙色
{1、115、134}、//橙色
{1、100、134}、//橙色-黄色
{1、80、134}、//黄色
{68、55、134}、//黄色-绿色
{134、1、134}、//绿色
{134、1、1}、//绿色-蓝色
{134、134、1}、//蓝色
{68、134、1}、//蓝色-紫色
{1、134、1}、//紫色
{1、134、55}//紫色红色
};

选择 uint8_t;//用于跟踪当前颜色选择

//*
main.c
*/
void main (void)
{
WDTCTL = WDTPW | WDTHOLD; //停止看门狗计时器

选中= 0; //默认为红色

//配置 UART
//从用户指南波特率表中,BRCLK = 32768时为9600波特
// UCOS16 = 0
// UCBRx = 3
// UCBRFx = 0
// UCBRSx = 0x92
UCA0CTLW0 = UCSWRST | UCSSEL_ACLK;
UCA0BRW = 3;
UCA0MCTLW = 0x9200;
UCA0CTLW0 &=~UCSWRST; //初始化 eUSCI
UCA0IE = UCRXIE; //启用 USCI_A0 RX 中断

//配置 GPIO
// PASEL0 = BIT6 | BIT7 | BIT8 | BIT9;// TB0.1和0.2、UCA0 RXD 和 TXD
// PADIR = BIT8 | BIT9 | BIT0; // TB0.1、0.2、0.0 (在 P1.0上)
// PAOUT = 0;

P1SEL0 = BIT6 + BIT7;//在 p1.6和1.7上启用 UART 功能

P1DIR = BIT0; //将 P1.0设置为输出
P2SEL0 = BIT0 + BIT1;//在给定引脚上启用 TB1输出的次级功能
P2DIR = BIT0 + BIT1;//使能 p2.0和2.1上的输出
PAOUT = 0;//关闭所有内容

PM5CTL0 &=~LOCKLPM5; //禁用 GPIO 上电默认值
//要激活的高阻抗模式
//先前配置的端口设置

//将 Timer B 设置为连续模式,用于多时基 PWM。
//请参阅应用手册 SLAA513了解理论。
TB1CCTL0 = CCIS_0 + OUTMOD_4 + CCIE;// CCR0切换、中断被启用
TB1CCTL1 = CCIS_0 + OUTMOD_4 + CCIE;// CCR1切换、中断被启用
TB1CCTL2 = CCIS_0 + OUTMOD_4 + CCIE;// CCR2切换、中断被启用

// REF0CLK/4 = 8192用于 TBCLK、这样60Hz 的周期就可以了
//在60Hz 周期内、TB0CCRx 值总共只有135个生成
// PWM。 这小于255、因此查找表可以由8位组成
//值、从而节省小型器件上的额外 FRAM 空间。
TB1CTL = TBSSEL_ACLK + ID_4 + MC_2 + TBCLR;// ACLK、contmode、clear TAR


_bis_SR_register (LPM3_bits | GIE); //使用中断转到 LPM3
_NO_OPERATION ();
}

// UART 中断服务例程
#pragma vector=USCI_A0_VECTOR
__INTERRUPT void USCI_A0_ISR (void)
{
选中= UCA0RXBUF;//为所选颜色获取新值

if (已选择> 11) //如果值超出范围,则设置默认值0 (红色)
{
已选择= 0;
}
}

// Timer_B0中断服务例程
#pragma vector=Timer1_B0_vector
__interrupt void Timer1_B0_ISR (void)
{
IF (P1OUT & BIT0) //检查电流输出电平
{
TB1CCR0 +=色低[选定][2];//低周期(蓝色 LED 亮起)
P1OUT = 0; //未在引脚上输出 TB0.0,因此手动设置
}
其他
{
TB1CCR0 +=色高[已选择][2];//高周期(蓝色 LED 熄灭)
P1OUT = BIT0;// TB0.0未在引脚上输出、因此手动设置
}
}

// Timer_B1中断矢量(TBIV)处理程序
#pragma vector=Timer1_B1_vector
__interrupt void Timer1_B1_ISR (void)
{
switch (__evo_in_range (TB1IV、14))
{
情况0:中断;
案例2:IF (TB1CCTL1和 CCI) //检查当前计时器引脚状态
{
TB1CCR1 +=色高[已选择][0];//高周期(红色关闭)
}
其他
{
TB1CCR1 +=色低[选定][0];//低周期(红色打开)
}
中断;
案例4:IF (TB1CCTL2和 CCI) //检查当前计时器引脚状态
{
TB1CCR2 +=色高[选定][1];//高(绿色关闭)
}
其他
{
TB1CCR2 +=色低[选定][1];//低周期(绿色亮起)
}
中断;
默认值:break;
}
}

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

    我看不到您在我的 Launchpad 上描述的行为。 我只会在设置 ISR 中的断点时看到 LED 发生变化、这表明 LED 的变化速度太快、无法看到。

    这是您第一次使用 Launchpad 吗? 一些 LaunchPad 附带使用 RTC 的演示程序。 如果您在其中加载另一个程序、则 RTC 不会复位、并且 RTC 中断会在程序运行时关闭。 您应该能够在下电上电时清除此问题、但在必要时添加"RTCCTL=0;"作为程序的第一行。

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

    感谢 Bruce 的帮助! 这确实是个问题! 当然、在尝试此代码之前、我一直在对 RTC 进行 fiddling、但我没有在这两者之间循环通电。  

    不过,一个快速跟进的问题--为什么 LED 每次显示第一种颜色需要大约5秒钟?  

    我现在已经初始化了 RTC、并添加了一个函数来计算秒数并每1秒递增"选定"值。 每次运行程序大约5秒后、我才会看到 LED 亮起。

    #include 
    #include 
    
    //包含每个颜色选择
    的 RGB LED 的低(开启)周期、其中 uint8_t colorsLow[12][3]={
    //{R、G、B}
    {134、1、1}、//红色
    {134、15、1}、//橙色
    {134、20、1}、//橙色
    {134、30、1}、//橙色-黄色
    {134、55、1}、//黄色
    {67、80、1}、//黄色-绿色
    {1、134、1}、//绿色
    {1、134、134}、//绿色-蓝色
    {1、1、134}、//蓝色
    {67、1、134}、//蓝色-紫色
    {134、1、134}、//紫色
    {134、1、80}//紫色
    红色};
    //包含每个颜色选择
    的 RGB LED 的高(关闭)周期 uint8_t colorsHigh[12][3]={
    //{R、G、B}
    {1、134、134}、//红色
    {1、120、134}、//橙色
    {1、115、134}、//橙色
    {1、100、134}、//橙色-黄色
    {1、80、134}、//黄色
    {68、55、134}、//黄色-绿色
    {134、1、134}、//绿色
    {134、1、1}、//绿色-蓝色
    {134、134、1}、//蓝色
    {68、134、1}、//蓝色-紫色
    {1、134、1}、//紫色
    {1、134、55}//紫色红色
    };
    
    选择 uint8_t;//用于跟踪当前颜色选择
    
    //*
    main.c
    */
    void main (void)
    {
    WDTCTL = WDTPW | WDTHOLD; //停止看门狗计时器
    
    选中= 0; //默认为红色
    RTCCTL=0;
    
    //配置 UART
    //从用户指南波特率表中,BRCLK = 32768时为9600波特
    // UCOS16 = 0
    // UCBRx = 3
    // UCBRFx = 0
    // UCBRSx = 0x92
    UCA0CTLW0 = UCSWRST | UCSSEL_ACLK;
    UCA0BRW = 3;
    UCA0MCTLW = 0x9200;
    UCA0CTLW0 &=~UCSWRST; //初始化 eUSCI
    UCA0IE = UCRXIE; //启用 USCI_A0 RX 中断
    
    //配置 GPIO
    // PASEL0 = BIT6 | BIT7 | BIT8 | BIT9;// TB0.1和0.2、UCA0 RXD 和 TXD
    // PADIR = BIT8 | BIT9 | BIT0; // TB0.1、0.2、0.0 (在 P1.0上)
    // PAOUT = 0;
    
    P1SEL0 = BIT6 + BIT7;//在 p1.6和1.7上启用 UART 功能
    
    P1DIR = BIT0; //将 P1.0设置为输出
    P2SEL0 = BIT0 + BIT1;//在给定引脚上启用 TB1输出的次级功能
    P2DIR = BIT0 + BIT1;//使能 p2.0和2.1上的输出
    PAOUT = 0;//关闭所有内容
    
    PM5CTL0 &=~LOCKLPM5; //禁用 GPIO 上电默认值
    //要激活的高阻抗模式
    //先前配置的端口设置
    // RTC 计数重载比较值为32。
    // 1024/32768 * 32 = 1秒
    RTCMOD = 32-1;
    // RTCMOD = 4 - 1;
    //初始化 RTC
    //源= ACLK = REFO,除以1024
    SYSCFG2 |= RTCCKSEL; //选择 ACLK 作为 RTC 时钟
    RTCCTL = RTCSS_1 | RTCSR | RTCPS__1024 | RTCIE;
    
    //将 Timer B 设置为连续模式,用于多时基 PWM。
    //请参阅应用手册 SLAA513了解理论。
    TB1CCTL0 = CCIS_0 + OUTMOD_4 + CCIE;// CCR0切换、中断被启用
    TB1CCTL1 = CCIS_0 + OUTMOD_4 + CCIE;// CCR1切换、中断被启用
    TB1CCTL2 = CCIS_0 + OUTMOD_4 + CCIE;// CCR2切换、中断被启用
    
    // REF0CLK/4 = 8192用于 TBCLK、这样60Hz 的周期就可以了
    //在60Hz 周期内、TB0CCRx 值总共只有135个生成
    // PWM。 这小于255、因此查找表可以由8位组成
    //值、从而节省小型器件上的额外 FRAM 空间。
    TB1CTL = TBSSEL_ACLK + ID_4 + MC_2 + TBCLR;// ACLK、contmode、clear TAR
    
    
    _bis_SR_register (LPM3_bits | GIE); //使用中断转到 LPM3
    __no_operation();
    }
    
    void incidmentSeconds (){
    
    if (已选择> 11) //如果值超出范围,则设置默认值0 (红色)
    {
    已选择= 0;
    }
    否则选择++;
    }
    
    // UART 中断服务例程
    #pragma vector=USCI_A0_VECTOR
    __INTERRUPT void USCI_A0_ISR (void)
    {
    选中= UCA0RXBUF;//为所选颜色获取新值
    
    if (已选择> 11) //如果值超出范围,则设置默认值0 (红色)
    {
    已选择= 0;
    }
    }
    
    // RTC 中断服务例程
    #pragma vector=RTC_vector
    __interrupt void RTC_ISR (void)
    {
    开关(__evo_in_range (RTCIV、RTCIV_RTCIF))
    {
    案例 RTCIV_NONE:
    中断; //无中断
    案例 RTCIV_RTCIF: // RTC 溢出
    增量 Seconds ();
    中断;
    默认值:
    中断;
    }
    }
    
    // Timer_B0中断服务例程
    #pragma vector=Timer1_B0_vector
    __interrupt void Timer1_B0_ISR (void)
    {
    IF (P1OUT & BIT0) //检查电流输出电平
    {
    TB1CCR0 +=色低[选定][2];//低周期(蓝色 LED 亮起)
    P1OUT = 0; //未在引脚上输出 TB0.0,因此手动设置
    }
    其他
    {
    TB1CCR0 +=色高[已选择][2];//高周期(蓝色 LED 熄灭)
    P1OUT = BIT0;// TB0.0未在引脚上输出、因此手动设置
    }
    }
    
    // Timer_B1中断矢量(TBIV)处理程序
    #pragma vector=Timer1_B1_vector
    __interrupt void Timer1_B1_ISR (void)
    {
    switch (__evo_in_range (TB1IV、14))
    {
    情况0:中断;
    案例2:IF (TB1CCTL1和 CCI) //检查当前计时器引脚状态
    {
    TB1CCR1 +=色高[已选择][0];//高周期(红色关闭)
    }
    其他
    {
    TB1CCR1 +=色低[选定][0];//低周期(红色打开)
    }
    中断;
    案例4:IF (TB1CCTL2和 CCI) //检查当前计时器引脚状态
    {
    TB1CCR2 +=色高[选定][1];//高(绿色关闭)
    }
    其他
    {
    TB1CCR2 +=色低[选定][1];//低周期(绿色亮起)
    }
    中断;
    默认值:break;
    }
    }
    

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

    我在这里没有设备、但我认为问题是当您启动计时器时、CCR 全部为0、因此计数器必须在第一个比较匹配发生前循环(6556/8192=8秒)。

    最简单的修复方法可能是初始化 TB1R=0xFFFF、而不是使用 TACLR。

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

    这确实解决了延迟启动问题! 谢谢你,Bruce!

    我刚开始,希望我不会再遇到其他问题:)