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.

MSP430G2332更改频率问题;



版主好:

我在手册上看该芯片内部DCO频率可以设置为4.25M,再高的话,手册上只写的上线和下限,没有典型值。

我程序使用4.25M主频时,程序可以正常运行,但是我需要输出一个方波波形,频率不够;所以我参照另外的时钟配置,将时钟配置为16M,但是我主循环里面一旦有控制IO输出的控制,程序就会重启。但是在4.25M时,程序运行正常,没有重启现象。不知道为什么会出现这情况,P1,P2都没开中断。

频率在4.25M时,如果我波形在定时器中断中控制的话,延迟会很大很大,如果仅仅为了测试,IO做一个简单的反转,波形基本一致;到底MSP430的指令周期是多少啊?为何我一个简单的判断数组中某个字节中某一位是否为“1”这样一个简单的C语句,耗时为何那么大?即使变成汇编,貌似也不会超过20句吧!

另外请教下版主,我需要生产一个bit流数据,一个位也就250us,如何方便进行操作?内存太小,不能直接将数据放到一串数组里面,如果每次发送时进行查找判断,延时就太长了,波形出的不对。

  • 1、重启问题,不容易猜到原因,建议提供下代码。

    2、编译是可以查看产生的汇编代码,就知道具体都作了哪些操作。

    3、不清楚你的bit流数据数据构成,如果只是产生250us的方波,可以采用定时器+io的方式


  • #include <msp430.h>


    void Clock_Config(void);
    void IO_Config(void);
    void IO_State_Init(void);
    void TIMER_Config(void);
    void ADC10_Config(void);
    void Generate_Wave(void);
    void Trans_Code(unsigned char *s,unsigned char *d);
    #define MCLK 4250000
    #define IN_CLK (MCLK/28) //主频1.6M,需要除以28做系统模糊定时使用,指令周期
    #define ONE_S IN_CLK
    #define ONE_mS (IN_CLK/1000)
    #define TEN_mS (IN_CLK/100)
    #define PULSE_WIDTH 256
    #define DELTA (6*28)
    //#define PULSE_TIME ((MCLK*PULSE_WIDTH/1000000)-DELTA)//宽度256us,周期256*3us
    #define PULSE_TIME 1000//宽度256us,周期256*3us
    volatile unsigned char Flag_1S=0;
    volatile unsigned char Flag_1mS=0;
    volatile unsigned char Flag_Duty=0;
    volatile unsigned char Flag_Time=0;
    volatile unsigned char Flag_Signal=0;

    unsigned char Message[4]={0x3a,0xa3,0xaa,0x87};
    unsigned char BIT_FLOW[9]={0,0,0,0,0,0,0,0,0};
    //unsigned long long PWM_Message=0;
    unsigned long SYS_Time=0;


    int main(void)
    {
    unsigned char i=0;
    unsigned long Delay=0;
    WDTCTL = WDTPW +WDTHOLD; // Stop Watchdog Timer

    //16Mhz
    if (CALBC1_16MHZ==0xFF) // If calibration constants erased
    {
    while(1); // do not load, trap CPU!!
    }
    DCOCTL = 0; // Select lowest DCOx and MODx settings
    BCSCTL1 = CALBC1_16MHZ; // Set range
    DCOCTL = CALDCO_16MHZ; // Set DCO step + modulation

    P1DIR |= 0x10; // P1.0,1 and P1.4 outputs

    IO_Config();
    IO_State_Init();
    Trans_Code(Message,BIT_FLOW);
    __bis_SR_register(GIE);

    while(1)
    {
    i++;
    if(i&0x01)
    {
    P1OUT |= BIT4;
    }
    else
    {
    P1OUT &= ~BIT4;
    }
    if((P1IN&BIT0) == 0) //P1.0-KEY
    {
    for(Delay=0;Delay<TEN_mS;Delay++);
    if((P1IN&BIT0) == 0) //P1.0-KEY
    {
    if(Flag_Signal)
    {
    P1OUT &= ~BIT3;//P1.3-BELL
    }else
    {
    Flag_Signal=1;
    P1OUT |= BIT3;//P1.3-BELL
    P2OUT |= BIT6; //P2.6-LED WARNING BLINK
    }
    }
    //while((P1IN&BIT0) == 0);
    }
    // if(Flag_Signal)
    // {
    // Flag_Signal=0;
    // Generate_Wave();
    // }
    }
    }


    #define Debug
    void Generate_Wave(void)
    {
    unsigned char Msg_State=0;
    while(Msg_State <= (64*3)) //等于64*3时,发送的是最后的0,也就是结束标志
    {
    if((Msg_State%3)== 0)
    {
    #ifdef Debug
    if(BIT_FLOW[(Msg_State/3)/8] & (0x01 << ((Msg_State/3)%8)))
    {
    P1OUT |= BIT4; //P1.4--Module 315
    }else
    {
    P1OUT |= BIT4; //P1.4--Module 315
    }
    #else
    P1OUT |= BIT4; //P1.4--Module 315
    #endif
    }
    if((Msg_State%3)== 1)
    {
    if(BIT_FLOW[(Msg_State/3)/8] & (0x01 << ((Msg_State/3)%8)))
    {
    P1OUT |= BIT4; //P1.4--Module 315
    }else
    {
    P1OUT &= ~BIT4; //P1.4--Module 315
    }
    }
    if((Msg_State%3)== 2)
    {
    #ifdef Debug
    if(BIT_FLOW[(Msg_State/3)/8] & (0x01 << ((Msg_State/3)%8)))
    {
    P1OUT &= ~BIT4; //P1.4--Module 315
    }else
    {
    P1OUT &= ~BIT4; //P1.4--Module 315
    }
    #else
    P1OUT &= ~BIT4; //P1.4--Module 315
    #endif
    }
    Msg_State++;
    }

    {
    //Flag_Signal=0;
    Msg_State=0;
    P1OUT &= ~BIT4; //P1.4--Module 315
    P2OUT &= ~BIT6; //P2.6-LED WARNING BLINK
    P1OUT &= ~BIT3; //P1.3-BELL
    }
    }


    void IO_Config(void)
    {
    //P1.1,P1.3,P1.4,P1.6 OUT;
    //P1.0,P1.2 IN


    //P1.1-AMP POWER
    //P1.3-BELL
    //P1.4-Module 315
    //p1.6-LED SEND

    //P1.0-KEY
    //P1.2-AMP SIGNAL

    //P2.6-LED WARNING
    //P2.7-CHECK BATTERY CTRL
    //P1.7 AD输入
    P1SEL = 0;
    P1SEL2 = 0; //P1口作为普通IO
    P1DIR |= BIT1+BIT3+BIT4+BIT6+BIT7; //设置P1口方向为输出
    P1DIR |= BIT5; //未使用,做输出
    P1REN |= BIT0+BIT2;

    P2SEL = 0;
    P2DIR |= BIT6+BIT7;

    P1IE = 0; //中断失效
    P2IE = 0; //中断失效
    }


    void Trans_Code(unsigned char *s,unsigned char * d)
    {
    unsigned char i,j=0;
    for(j=0;j<4;j++)
    {
    for(i=0;i<8;i++)
    {
    if(s[j]&(0x01<<i))
    {
    d[(i/4)+2*j] |= ((0x01<<((i*2)%8))+(0x01<<(((i*2)+1)%8))); //数据发送时低bit为先发,d[0]在前,d[7]最后
    }
    }
    }
    }

    void IO_State_Init(void)
    {
    P1OUT |= BIT1; //P1.1-AMP POWER
    P1OUT &= ~BIT4; //P1.4--Module 315
    P2OUT &= ~BIT6; //P2.6-LED WARNING BLINK
    P1OUT &= ~BIT3; //P1.3-BELL
    P2OUT &= ~BIT7; //P2.7-BATTERY CHECK DISABLE
    }

    这是自己写的小代码,主循环中

    //while((P1IN&BIT0) == 0);
    或者
    // if(Flag_Signal)
    // {
    // Flag_Signal=0;
    // Generate_Wave();

    //    }

    不屏蔽的话,只要p1.0有按键,系统就会重启;把这几句都屏蔽后,系统就正常运行不会重启。(为了防止代码编写错误Generate_Wave();这个函数始终在屏蔽,未使用)。另外:这个程序如果主循环内容都不屏蔽,但是系统时钟设置为4.25M时,程序可以正常运行,不重启;时钟配置如下:

    void Clock_Config(void)
    {
    WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
    //DCOCTL = CALDCO_16MHZ; //DCO=8MHZ
    //BCSCTL1 = CALBC1_16MHZ;
    //BCSCTL2 &= ~(SELM0+SELM1+DIVM0+DIVM1+SELS+DIVS0+DIVS1); //MCLK,SMCLK=8MHZ

    DCOCTL = DCO1+DCO0;
    //DCOCTL |= DCO2;
    BCSCTL1 = XT2OFF+RSEL3+RSEL1+RSEL0;
    //BCSCTL1 |= RSEL2;
    BCSCTL2 = 0;
    //BCSCTL2 &= ~(SELM0+SELM1+DIVM0+DIVM1+SELS+DIVS0+DIVS1); //MCLK,SMCLK=8MHZ
    }

    初次接触MSP430,好些东西不懂,还希望版主多多指教和提醒。

  • 你的代码好乱,我竟然没看懂。。。

    有些注释和代码还不一致。。。

    你的代码也比较长,建议分模块进行调试。调试通一个模块,再增加另一段代码进行调试。

    重启一般都是寄存器配置的不合要求,或者操作越界等之类的问题。需要慢慢排查

  • 粘贴时默认把TAB给去除了,代码没几行,也没用什么数组啊,应该不会出现越界吧,你有邮箱么?

  • 没看出来你在哪里调用的clock_config,也没看出来哪里是你的中断子程序