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/MSP430G2553:随机数生成器

Guru**** 2540720 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/567374/ccs-msp430g2553-random-number-generator

器件型号:MSP430G2553

工具/软件:Code Composer Studio

您好!

我希望生成随机二进制数、以便每次在不同频率下打开 P1.0。 同时、我希望在 P1.6上生成 PWM。  

为了生成随机数、我使用 DCO 和 VLO 之间的时序差。 我使用 TA0设置 DCO、使用 TA1设置 VLO。 然后、我使用中断矢量暂停 TA0和 TA1、并在 SMCLK 中保存节拍数。 然后、我使用 IF 环路根据每次记录的节拍数 LSB 来切换 P1.0。  

TA0和 TA1暂停会导致 PWM 停止工作。 此外、P1.0始终处于高电平。 您能帮我找出我所犯的错误吗?

请参阅以下代码:  

//RNG

#include "msp430G2553.h"
#include 

void main( void ){

WDTCTL =(WDTPW | WDTHOLD);//停止看门狗定时器

BCSCTL1 = CALBC1_16MHz;//将范围设置为16MHz
DCOCTL = CALDCO_16MHz;//将 DCO 阶跃和调制设置为16MHz

P1SEL |= 0x40;//将 P1.6的特殊功能设置为计时器模块
P1DIR |= 0x41;//将 P1.6、P1.0设置为输出方向
P1OUT |= 0x00;//将 P1设置为关

//设置 DCO
TA0CCR0 = 400;///PWM 频率40kHz
TA0CCR1 = 65;//PWM 占空比
TA0CCTL0 = CAP | CM_1 | CCIS_1 | OUTMOD_7;
TA0CTL =(TASSEL_2 | ID_0 | MC_1 | TACLR | TAIE);// SMCLK、分频器1、上数模式、清零、 启用中断

//设置 VLO
TA1CCR0 = 1200;
TA1CCTL0 = CCIE | OUTMOD_3;
TA1CTL = tassel_1 | MC_1;

_BIS_SR (GIE);//启用全局中断

while (1);//无限循环
}

// Timer0 A1中断服务例程
#pragma vector = TIMER0_A1_vector
__interrupt void Timer0_A1_ISR (void)
{
static uint8_t random = 0;//寄存器保存随机数

TA0CTL = MC_0;//暂停 TA0
TA1CTL = MC_0;//暂停 TA1
随机= TA0R;//保存节拍数 SMCLK

TA0CTL &&~TAIFG;

if (随机)
{
P1OUT = 0x01;
}
否则
{
P1OUT = 0x00;
}
} 


  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您不使用 LSB、而是测试所有16位。

    如果您不想停止计时器、则不要停止计时器。 要读取两个定时器值、请将一个定时器的 CCR 配置为在指定时间输出脉冲、配置第二个定时器的 CCR 以进行捕获、并将第一个 CCR 的输出连接到第二个 CCR 的输入。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您可能会发现 slaa388应用手册 很有用。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的建议。 很抱歉听起来很天真、我还在学习计时器。

    您是否提出以下建议:
    // DCCO
    TA0CCR0 = 400;///PWM 频率40kHz
    TA0CCR1 = 65;//PWM 占空比
    TA0CCTL0 = OUTMOD_7;

    //VCO
    TA1CCR0 = TA0CCR0;
    TA1CCTL0 = CAP | CCIE | OUTMOD_3;

    在中断循环内、我可以直接读取计时器 A 寄存器(random = TA0R & 1)而不暂停时间?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    要捕获事件,您需要设置捕获模式(CM*),因为默认值(0)是“无捕获”,输出模式并不有趣。 事件发生时、TA1R 会复制到 TA1CCR0中、因此您无需设置后者。 然后、在中断处理程序中、您可以读取 TA1CCR0。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    非常感谢! 这对我们有很大帮助、现在 PWM 和 RNG 都能正常工作。 但是、RNG 仅在调试模式下工作。 一旦我退出调试模式、P1.0变为高电平(3V)、而不是以随机间隔输出脉冲。

    有什么建议吗?

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

    经过一些研究后、我认为该程序只在调试模式下工作的问题可能是因为 launchpad 没有附带外部晶振、并且使用内部晶振有一些限制、例如程序只在调试模式下工作。  

    我在 C21和 C22上安装了 Launchpad 随附的32KHz 晶振以及两个12pF 电容器。 我运行了以下代码、在调试和编辑模式下都能正常工作。 我现在遇到的问题是随机数生成器不是很随机。 当我查看示波器上的 P1.0时、它看起来非常可预测。 我没有安装晶体、但程序仅在调试模式下工作时、情况并非如此。  

    我还意识 到我没有告诉 MSP430使用哪种晶体(内部或外部)。 因此、我参考了用户指南、其中建议我设置 LFXT1Sx = 11、并且 XCAPx = 00来使用外部晶振。 我是通过添加以下行来实现的:  BCSCTL3 |= LFXT1S_3 + XCAP_0。 这使得 RGN 完全停止工作。  

    以下是我的问题:

    1.在现有调试模式下、我需要使用外部晶体来防止程序崩溃是否正确?

    2.如果是这样、我需要设置哪些寄存器来使用外部晶振、而不是内部晶振?

    3.内部晶振的精度是否可能比使用外部晶振时低、因此产生的随机数更多?

    非常感谢!

    以下是我的代码:  

    //RGN 测试
    
    #include "msp430G2553.h"
    #include 
    
    
    
    void main( void ){
    
    
    
    WDTCTL =(WDTPW | WDTHOLD);//停止看门狗定时器
    
    BCSCTL1 = CALBC1_16MHz;//将范围设置为8MHz
    DCOCTL = CALDCO_16MHz;//将 DCO 阶跃和调制设置为8MHz
    
    
    P1SEL |= 0x40;//将 P1.6的特殊功能设置为计时器模块
    P1DIR |= 0x41;//将 P1.6、P1.0、P1.1设置为输出方向
    P1OUT |= 0x00;//将 P1.0打开、P1.1关闭
    
    // PWM
    TA0CCR0 = 400;//频率40kHz、25us
    TA0CCR1 = 60;//占空比
    TA0CCTL1 = OUTMOD_7;//复位/设置
    TA0CTL =(tassel_2 | ID_0 | MC_1 | TACLR | TAIE);// SMCLK、分频器1、上数模式、清零、 启用中断
    
    
    
    //设置 VLO
    TA1CCTL0 = CAP | CM_1 | CCIS_1;
    TA1CTL = tassel_1 | MC_2;
    
    
    _BIS_SR (GIE);//启用全局中断
    
    while (1);//无限循环
    }
    
    
    
    // Timer0 A1中断服务例程
    #pragma vector = TIMER0_A1_vector
    __interrupt void Timer0_A1_ISR (void)
    {
    volatile unsigned char random = 0;//注册以保存随机数
    
    = TA1R & 1;//保存节拍数 TASMCLK
    
    TA0CTL &=~TAIFG;
    TA1IFG ~TAIFG;
    
    如果(随机)
    {
    P1OUT = 0x01;
    }
    否则
    {
    P1OUT = 0x00;
    }
    
    

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

    [引用用户="Sahar Elyahoodayan]1. 在现有调试模式下、我是否需要使用外部晶体来防止程序崩溃?[/quot]

    不可以、您的"不运行不带调试器"问题就在于:您在微控制器从复位状态释放后立即设置16MHz DCO -此时、对于16MHz 运行、VCC 尚未达到标称电平(>=3.3VDC)、因此会导致芯片崩溃。 这是典型的 MSP430新手错误:)外部晶振设置代码很可能等待振荡器启动、在此期间 VCC 良好、不会发生崩溃、它在16MHz 时与调试器一起工作异常。

    为了安全设置高 DCO 频率、您应添加延迟、该延迟考虑了上电后的 VCC 斜升:

    WDTCTL =(WDTPW | WDTHOLD);
    __DELAY_CYCLS (100000);// 100ms 延迟@ 1MHz CPU 频率
    BCSCTL1 = CALBC1_16MHz;
    DCOCTL = CALDCO_16MHz;
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    谢谢 Ilmars、但这没有解决问题。 它仍然不是在没有调试器的情况下运行。
    我想知道如何使用外部晶体来生成随机数。 当我尝试使用外部晶体时、生成的数字看起来非常可预测。
    这是因为外部晶振更精确、所以 DCO 和晶振之间的时间差会更小吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Sahar Elyahoodaya"]是因为外部晶振更准确,所以 DCO 和晶振之间的时间差会更小?

    最有可能。 您没有从 MSP430构建 RNG 的经验。 您是否查看了我建议的文档? 您可以使用外部晶振、但仍然可以使用 VLO 来实现 ACLK。 此外、您还应找到"无调试器"配置的问题所在。 可能是重置问题。 请注意、此论坛包含有关您所遇到问题的所有问题和答案-建议您使用搜索。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我做了很多研究、但仍然无法解决问题。 我最终使用了一个浮动 ADC 引脚并将 LSB 用作随机位。 它工作得非常好。
    感谢你的帮助。