打印

刚接触430,想问个时钟的问题,定时不准,搞不懂哪里不对

[复制链接]
1522|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yilfhch|  楼主 | 2014-7-25 20:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
小弟我一个产品为了低功耗,刚转用430芯片,一上手就被那混乱的时钟搞的晕头转向,定时不准,搞不懂问题在哪里,搞了好久了,上论坛问下高手,芯片用的是G2553

代码说明一下,
一开始设置了:
DCOCTL=CALDCO_1MHZ_;
BCSCTL1=CALBC1_1MHZ_;
这里应该是设置DCO 1MHZ,为了检测是不是出的1us,我下面取反P1.7

Delay_us(10);//想延时10us的取反的
P1OUT^=BIT7;  //在这里得到的不是20us周期的方波,而是2us
下面定时器定时50us,但CCR0必须等于1000出来的才是50us
TACTL=TASSEL_2+TACLR;  //选择计数时钟为SMCLK,将计数器TAR清零
CCR0=1000;            //CCR0
TACTL|=MC_1;          //选择Timer_A为增计数模式
CCTL0=CCIE;          //使能中断
是不是跟我下面写FLASH有关,写FLASH不是需要257KHZ---~476KHZ吗?
FCTL2=FWKEY+FSSEL_1+20;     //flash模块时钟源为MCLK 分频2

/******************************************
ChipType:msp430g2553
Software:IAR FOR MSP430 5.50
Description:  
Copyright: ver1.0
*******************************************/
#include"main.h"
#include "msp430g2553.h"

/******************************************
Description:函数声明
*******************************************/
void MCUFUNInit(void);
u16 ReadFlash(u16 Addr);
void flashErase(u16 address);
void Delayus(u8 cnt);

#define CPU_Frequency   (1) //1MHZ
#define Delay_us(n) __delay_cycles(n*CPU_Frequency)
#define Delay_ms(n) __delay_cycles(n*(1000L)*CPU_Frequency)

/******************************************
Function:主函数
*******************************************/
void main( void )
{
          WDTCTL = WDTPW + WDTHOLD;    // 关闭看门狗

          //DCOCTL=DCO0+DCO1;        //开启DCO,DCO=3,1MHZ
          //BCSCTL1|=RSEL2;         //RSEL=4
         
          DCOCTL=CALDCO_1MHZ_;
          BCSCTL1=CALBC1_1MHZ_;
          MCUFUNInit(); //IO口初始化

          _EINT();       //开总中断
          while(1)
                  {   
                    Delayus(100);
                  //LPM0; //开启低功耗模式0,进入低功耗模式,等待中断唤醒   
                }   
}

/******************************************
Function:延时函数10us
*******************************************/
void Delayus(u8 cnt)
{
    while(cnt--)
    {
      Delay_us(10);
      P1OUT^=BIT7;  //在这里得到的不是20us周期的方波,而是2us
    }
}


/******************************************
Function:IO初始化
*******************************************/
void MCUFUNInit(void)
{
/***************IO口初始化*******************/
        P1DIR = 0XFF;         //设定P1口为输出方式
        P1OUT = 0X00;         //给P1口赋初始值
        
/***************定时器初始化*******************/   
        TACTL=TASSEL_2+TACLR;  //选择计数时钟为SMCLK,将计数器TAR清零
        CCR0=1000;            //CCR0
        TACTL|=MC_1;          //选择Timer_A为增计数模式
        CCTL0=CCIE;          //使能中断

}

/******************************************
Function:写
*******************************************/
void WritePasswordFlash(u16 address)
{
       u16 *FlashAdd = (u16 *)address;
       //_DINT();                     //关闭中断
       while((FCTL3&BUSY)!=0x00);                  //检测busy位
       FCTL2=FWKEY+FSSEL_1+20;                    //flash模块时钟源为MCLK 分频2
       FCTL3=FWKEY;                                //解锁
       FCTL1=FWKEY+BLKWRT+WRT;                     //块写
       *FlashAdd=PasswordData[0];                    //写入
       while((FCTL3&WAIT)==0);                 //检测wait位 是否写入该字
       FCTL3=FWKEY;                                //解锁
       *(FlashAdd+1)=PasswordData[1];                    //写入
       while((FCTL3&WAIT)==0);                 //检测wait位 是否写入该字
       FCTL1=FWKEY;                                //BLKWRT WRT位复位
       while((FCTL3&BUSY)!=0x00);                  //检测BUSY位
       FCTL3=FWKEY+LOCK;                           //锁定
       //_EINT();                //开放中断
}

/******************************************
Function:读
*******************************************/
u16 ReadFlash(u16 Addr)
{
        u16 Data;
        u16 *FlashPtr = (u16 *) Addr;
        Data = *FlashPtr;
        return(Data);
}

/******************************************************
Function: 段擦除子程序                           
*******************************************************/
void flashErase(u16 address)
{
       u8 i;
       u16 *EraseAddress;
       EraseAddress=(u16*)address;
       FCTL2=FWKEY+FSSEL_1+20;   //flash模块时钟源位MCLK 分频2
       FCTL3=FWKEY;              //解锁
       FCTL1=FWKEY+ERASE;        //段擦除
       //_DINT();                     //关闭中断
       for(i=0;i<2;i++)
       {
         *EraseAddress++=0;               //在欲进行操作的段中空写,启动擦除操作
       }
       //FCTL3=FWKEY+LOCK;         //锁定  
}


/**************************************************
Function:定时器中断
***************************************************/
#pragma vector = TIMER0_A0_VECTOR
__interrupt void timeA(void)
{

        LPM0_EXIT;
}

相关帖子

沙发
yilfhch|  楼主 | 2014-7-25 20:50 | 只看该作者
Delay_us(10);
P1OUT^=BIT7;  //在这里得到的不是20us周期的方波,而是2us

在这里延时了得到的是1us取反一次,周期为2us,这样算的话频率是10Mhz了

但定时器那里没有分频CCR0=1000得到的是50us,问题在哪里呢

使用特权

评论回复
板凳
dirtwillfly| | 2014-7-25 21:30 | 只看该作者
又是改错题,好长的代码

使用特权

评论回复
地板
yilfhch|  楼主 | 2014-7-25 23:23 | 只看该作者
我觉得是有错误,但我不明白为什么,程序是可以正常跑的,只是和我设想的不一样。当我想要的是1us,出来的是0.1us。
好吧,既然觉得代码太长,那我精简一下

#include"main.h"
#include "msp430g2553.h"
#define CPU_Frequency   (1) //1MHZ
#define Delay_us(n) __delay_cycles(n*CPU_Frequency)
#define Delay_ms(n) __delay_cycles(n*(1000L)*CPU_Frequency)
/******************************************
Function:主函数
*******************************************/
void main( void )
{
          WDTCTL = WDTPW + WDTHOLD;    // 关闭看门狗
          //DCOCTL=DCO0+DCO1;        //开启DCO,DCO=3,1MHZ
          //BCSCTL1|=RSEL2;         //RSEL=4
          DCOCTL=CALDCO_1MHZ_;
          BCSCTL1=CALBC1_1MHZ_;
          MCUFUNInit(); //IO口初始化
          _EINT();       //开总中断
          while(1)
                  {   
                    Delayus(100);
                  //LPM0; //开启低功耗模式0,进入低功耗模式,等待中断唤醒   
                }   
}
/******************************************
Function:延时函数10us
*******************************************/
void Delayus(u8 cnt)
{
    while(cnt--)
    {
      Delay_us(10);
      P1OUT^=BIT7;  //在这里得到的不是20us周期的方波,而是2us
    }
}
/******************************************
Function:IO初始化
*******************************************/
void MCUFUNInit(void)
{
/***************IO口初始化*******************/
        P1DIR = 0XFF;         //设定P1口为输出方式
        P1OUT = 0X00;         //给P1口赋初始值
/***************定时器初始化*******************/   
        TACTL=TASSEL_2+TACLR;  //选择计数时钟为SMCLK,将计数器TAR清零
        CCR0=1000;            //CCR0
        TACTL|=MC_1;          //选择Timer_A为增计数模式
        CCTL0=CCIE;          //使能中断
}

使用特权

评论回复
5
yilfhch|  楼主 | 2014-7-25 23:26 | 只看该作者
这就剩下一点代码了,版主大人可否指教一下。使用的是内部DCO。

使用特权

评论回复
6
firstblood| | 2014-7-26 18:23 | 只看该作者
内部DCO用的是多大的,我怎没看到的啊,海哥看下这个准不准的啦。

使用特权

评论回复
7
yilfhch|  楼主 | 2014-7-27 21:01 | 只看该作者
DCOCTL=CALDCO_1MHZ_;
BCSCTL1=CALBC1_1MHZ_;

这里啊,设置1MHZ的啊,实际仿真时候读出的DCOCTL=0XBF,BCSCTL1=0XFE,说明TI给的这个语句是错的。

使用特权

评论回复
8
wugenhui| | 2014-8-12 14:09 | 只看该作者
我初学430之前尝试使用配置内部时钟,后来放弃了改用外部手表晶振定时

使用特权

评论回复
9
qq756512897| | 2014-8-12 16:28 | 只看该作者
表示不懂                     

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

9

帖子

1

粉丝