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/MSP430F5438A:定时器A的困难-捕获模式

Guru**** 2610165 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/662537/ccs-msp430f5438a-difficulty-with-timer-a---capture-mode

部件号:MSP430F5438A

工具/软件:Code Composer Studio

您好,

我正在使用 MSP430F5438A 微控制器和Code Composer Studio v7完成课件工作。

我的任务是测量温度并将其写在液晶屏上。 我有一个数字温度传感器,它具有PWM (提供占空比)输出,可连接 到一个8.0 ,0.0。

液晶屏的所有功能均正常工作,但液晶屏上未写入温度,即使中断功能也正常工作。

我不确定我是否已将所有寄存器设置正确。 我已经做到了:

TA0CTL = TALCLR;//设置此位将清除TAR,时钟分频器逻辑和计数方向
TA0CTL = tassel__SMCLK | MC_2;// SMCLK,模式控制:连续

TA0CCTL0 = CCIE | CM_1 | SCS | CAP | CCIS_1;// CCR0,在上升沿捕获

在中断功能中,我根据我测量的半个周期中的哪个周期(正或负)更改捕获模式。 我以这种方式改变它:

IF (TA0CCTL0 & CCIFG){// CCP0中断

如果((TA0CCTL0 & CM_1)&&(pp_done == 0)){//上升边

TA0CTL = TALCLR;//设置此位将清除TAR,时钟分频器逻辑和计数方向
TA0CTL = tassel__SMCLK | MC_2;// SMCLK,模式控制:连续

TA0CCTL0 &=~CM0;
TA0CCTL0 |= CM1;//在下降边缘设置CCP0模块中断
TA0CCTL0 &=~CCIFG;//重置中断标志

}

...

}

数据表位于 http://www.ti.com/lit/ds/symlink/msp430f5438a.pdf链接上
用户指南 http://www.ti.com/lit/ug/slau208p/slau208p.pdf

您是否看到任何不正确的设置?

提前感谢您的帮助。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    解决此类问题的最佳方法是在CCS中使用断点,并真正使用电线(可能在输入处使用RC来平滑过渡)来创建上升或下降的边缘。 我建议您首先确认上升沿的中断触发器。 然后,确认它在下降边缘触发。 如果您的代码可以用非常慢的信号来执行此操作,则没有理由不使用PWMed信号(假设PMWed信号比MCU的频率慢)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我使用了断点和调试器,但我的代码从未来自中断,我不理解为什么,因为传感器在1-4 kHz工作,我的计时器的频率要快得多- SMCLK。 我给您提供代码,让您一目了然,并告诉我您是否看到任何不合逻辑的部件... 液晶屏的代码工作正常,因此您不必检查。

    #include <MSP4S.h>
    #include <stdio.h>
    #include <stdlib.h>

    // UC端口定义
    #define lcd_port P8OUT
    #define lcd_port_dir P8DIR

    // LCD根据其连接的引脚寄存掩码
    #define LCD_EN BIT3.
    #define LCD_RS 位2

    #define标题1"温度:"
    #define title2"超出范围!"

    /*SMT 1.603万温度传感器
    DC= 0.320 + 0.0.047万 *t (t =°C)
    直流电的范围为0,1至1
    T=(DC - 0.320)/ 0.0.047万
    适用于0.1 t=-46
    对于1 T=144
    */

    unsigned long int result = 0;//温度,单位为摄氏度
    unsigned long int pom =0;
    unsigned long int temp =0;
    无符号长整型占空比=0;
    unsigned int pp_done = 0;
    unsigned int np_done = 0;
    字符缓冲区[20];
    字符n[4];
    unsigned long int count_pp_1=0;
    unsigned long int count_np_1=0;

    void lcd_reset()

    lcd_port_dir = 0xff;//输出模式
    lcd_port = 0xff;
    __DELAY周期(2万);
    LCD_port = 0x30+LCD_EN;
    LCD_port = 0x30;
    __DELAY周期(1万);
    LCD_port = 0x30+LCD_EN;
    LCD_port = 0x30;
    __DELAY周期(1000);
    LCD_port = 0x30+LCD_EN;
    LCD_port = 0x30;
    __DELAY周期(1000);
    LCD_port = 0x20+LCD_EN;
    LCD_port = 0x20;
    __DELAY周期(1000);
    }

    void lcd_cmd (char cmd)

    //发送上半字节
    LCD_port =(CMD和0xF0)|LCD_EN;
    lcd_port =(cmd和0xF0);

    //发送下半字节
    LCD_port =((cmd << 4)和0xF0)|LCD_EN;
    LCD_port =((cmd << 4)和0xF0);

    __DELAY周期(4000);
    }

    void lcd_init (无效lcd_init)

    lcd_reset(); //调用LCD重置
    LCD_cmd(0x28); // 4位模式- 2行- 5x7字体。
    LCD_cmd(0x0C); //不显示光标-不闪烁。
    LCD命令(0x06); //自动增量-无显示偏移。
    LCD_cmd(0x80); //地址DDRAM,0偏移80h。
    LCD_cmd(0x01); //清除屏幕
    }


    void lcd_data (无符号字符数据)

    //发送上半字节
    LCD_port =(dat & 0xF0)|LCD_EN|LCD_RS);
    LCD_port =(dat & 0xF0)|LCD_RS);

    //发送下半字节
    LCD_port =((dat << 4)& 0xF0)|LCD_EN|LCD_RS);
    LCD_port =((dat << 4)& 0xF0)|LCD_RS);

    __delay_cycles(4000);//小延迟可能导致缺少字符显示
    }

    void display_line(car *line)

    while (*行)
    lcd_data(*line+);
    }

    /**
    主要c
    */
    内部主(无效)

    WDTCTL = WDTPW | WDTHOLD; //停止监视计时器

    //初始化LCD
    lcd_init();
    //在LCD上写入
    lcd_cmd(0x80);//选择第一行(0x80 + addr)-此处addr = 0x00
    显示行(标题1);

    //设置PWM传感器
    P8SEL || BIT0;//为TA0选择端口WFP 8.0
    P8DIR &=~BIT0;//将WFP 8.0 配置为输入

    TA0CTL = TALCLR;//设置此位将清除TAR,时钟分频器逻辑和计数方向
    TA0CTL = tassel__SMCLK | MC_2;// ACLK,模式控制:连续

    TA0CCTL0 = CCIE | CM_1 | SCS | CAP | CCIS_1;// CCR0,在上升沿捕获
    int i;

    __enable_interrupit(); // GIE

    而(1){
    如果(np_done){

    占空比= 1万 *(COUNT_pp_1 /(COUNT_pp_1 + COUNT_NP_1));
    结果=(负荷- 3200)/ 47;


    如果(结果<=100)&&(结果>=0){//software debceboning
    TEMP =结果;
    (i = 3;i >= 0;i --){
    n[i]=(temp % 10)+'0');
    温度/= 10;
    }

    lcd_cmd(0xc0);
    显示行(niz);
    }
    否则{
    lcd_cmd(0xc0);
    显示行(标题2);
    }

    __DELAY周期(4000);


    COUNT_pp_1 = 0;
    COUNT_NP_1 = 0;
    pp_zavrseno = 0;
    np_zavrseno = 0;

    TA0CTL = TALCLR;//设置此位将清除TAR,时钟分频器逻辑和计数方向
    TA0CTL = tassel__SMCLK | MC_2;// ACLK,模式控制:连续

    //下一个CCP0中断一个上升沿
    TA0CCTL0 &=~CM1;
    TA0CCTL0 |= CM0;
    TA0CCTL0 |= CCIE;
    TA0CCTL0 &=~CCIFG;

    }
    }

    返回0;
    }

    void __attribute__((interrupt (TIMER0_A0_vector))) timerA0Isr (void)

    IF (TA0CCTL0 & CCIFG){//CCP0 中断

    如果((TA0CCTL0 & CM_1)&&(pp_done == 0))为{//上升边

    TA0CTL = TALCLR;//设置此位将清除TAR,时钟分频器逻辑和计数方向
    TA0CTL = tassel__SMCLK | MC_2;// ACLK,模式控制:连续

    TA0CCTL0 &=~CM0;
    TA0CCTL0 |= CM1;//在下降沿上设置CCP0模块中断
    TA0CCTL0 &=~CCIFG;//重置中断标志

    }

    否则IF (((TA0CCTL0 & CM_2)&&(pp_done == 0)){//Falling edge

    COUNT_pp_1 = TA0CCR0;// TA0R

    TA0CTL = TALCLR;//设置此位将清除TAR,时钟分频器逻辑和计数方向
    TA0CTL = tassel__SMCLK | MC_2;// ACLK,模式控制:连续

    TA0CCTL0 &=~CM0;
    TA0CCTL0 |= CM1;//在下降沿上设置CCP0模块中断
    TA0CCTL0 &=~CCIFG;//重置中断标志

    PP_done = 1;
    }

    否则IF ((TA0CCTL0 & CM_2)&&(pp_done == 1)&&(np_done == 0){

    TA0CTL = TALCLR;//设置此位将清除TAR,时钟分频器逻辑和计数方向
    TA0CTL = tassel__SMCLK | MC_2;// ACLK,模式控制:连续

    TA0CCTL0 &=~CM1;
    TA0CCTL0 || CM0;//在上升沿上设置CCP0模块中断
    TA0CCTL0 &=~CCIFG;//重置中断标志

    }

    否则IF ((TA0CCTL0 & CM_1)&&(pp_done == 1)&&(np_done == 0){

    COUNT_NP_1 = TA0CCR0;// TA0R

    TA0CTL = TALCLR;//设置此位将清除TAR,时钟分频器逻辑和计数方向
    TA0CTL = tassel__SMCLK | MC_2;// ACLK,模式控制:连续

    TA0CCTL0 &=~CCIFG; //重置中断标志
    TA0CCTL0 &=~CCIE;//禁用CCP0 interap

    np_done = 1;//已完成
    }
    }
    }
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    > IF (TA0CCTL0 & CCIFG){///CCP0 中断

    CCIFG将在您到达此处时被清除(请参阅SLAU208P sec 17.2 .6.1),因此您不应检查它。 CCR0在这方面是特别的。