MSP430F5xx / F6xx系列 DCO频率范围选择方法

本文介绍了MSP430F5xx / F6xx系列单片机中DCO(数控振荡器)的频率选择和配置方法,包括DCO的基本原理、频率范围选择、DCO频率调整以及FLL(频率锁定环)的工作机制。通过设置UCSCTL寄存器,可以实现DCO频率在不同范围内的精确控制,确保系统时钟的稳定性。

1. 数控振荡器(DCO)

DCO是一个集成的数字控制振荡器。DCO频率可以通过软件使用UCSCTL1.DCORSEL、UCSCTL0.DCO和UCSCTL0.MOD位进行调整。DCO频率可由FLL选择性地稳定到FLLREFCLK/n的多个倍频。FLL可以接受由UCSCTL3.SELREF位选择的不同参考时钟源。参考时钟源包括XT1CLK、REFOCLK或XT2CLK(如果可用)。n的值由UCSCTL3.FLLREFDIV位(n=1、2、4、8、12或16)定义。默认值为n=1。在某些情况下,可能不需要或不希望FLL操作;在这些情况下,不需要FLLREFCLK。这可以通过设置UCSCTL3.SELREF={7}来实现。

*******************************************************************

注:仅适用于MSP430F543x和MSP430F541x非A版本

MSP430F5529 LauchPad作为是实验板,IAR Embedded Workbench IDE-MSP430为工具,根据要求及下方部分代码完成实验二,给出完整代码。 实验二: 通过对MSP430F5529开发板编程,从IO口产生一个25Hz方波信号,并用AD模块测量该方波信号的峰值幅度值显示于OLED上,要求: 1、利用MSP430定时器和通用IO产生25Hz方波。 2、利用MSP430内部AD测量出该方波峰值幅度并显示在OLED上。 详细要求如下: 1.利用定时器和IO口产生方波 初始化IO口设置,初始化定时器设置并是能中断,编写中断函数内改变IO口的高低电平 2.利用AD测量方波的峰值幅度 设置ADC对应的IO口为复用输入模式,使能参考电压、打开AD转换功能;设置采样时钟源及参数、参考电压大小,使能中断、使能转换,编写ADC12中断函数,在中断函数中读取ADC采样值并对采样值进行转换得到电压实际值。 main.c #include <msp430.h> #include "IIC.h" /********************** PWM波输出端口定义 ***********************/ void init_IO(void) { //指定输出端口选择复用模式 //指定输出端口为输出模式 } /********************* PWM波输出定时器配置 (此代码使用TA0.1输出PWM 由P1.2输出 可自行修改为其他端口) ********************/ int Vpp=0; //幅值 int ccr0= //初始化频率(根据下面的定义自行计算) int ccr1= //初始化占空比 (根据下面定义自行计算) void timer_A0_1_init() //TA0.1输出PWM 由P1.2输出 { //ACLK,增计数 (也可以选择其他时钟源,自行选择) //输出模式7 TA0CCR0 = ccr0; //时钟频率为32768HZ(ACLK) TA0CCR1 = ccr1; //占空比为CCR1/CCR0 } /******************** ADC配置模块 (以下注释配置并不唯一,仅供参考,可以自行选择需要用的寄存器来进行配置) *******************/ void ADC_init() { //AD接入端口复用 //端口输出模式选择为输入 //配置ADC12CTLx使能参考电压 //配置ADC12CTLx打开AD,设置采样时钟 //配置ADC12CTLx配置采样保持、分频系数、时钟源、转换序列 //配置ADC12MCTLx设置参考电压源以及参考电压大小 //配置ADC12IE使能AD中断 //配置ADC12CTLx使能AD转换 } void delayms(int t) //延时t ms { while(t--) { int m=200; while(m--); } } /******************* 计算采样出来的电压值 (提供一种方法,仅供参考,可以自行写) ***************/ int get_Vpp() //得到Vpp { int n; int min=0,max=4095,temp; for(n=0;n<1000;n++) { temp=ADC12MEM0; if(temp<min) min=temp; if(temp>max) max=temp; } return //返回一个计算后的电压值(自行写出计算公式) } void LCD_Show() //LCD显示函数 { LCD_ShowString(8,8,"Vpp=",16); LCD_ShowString(72,8,"mV",16); LCD_ShowNum(40,8,Vpp,4,16); } void init() //初始化 { __enable_interrupt(); init_IO(); timer_A0_1_init(); ADC_init(); LCD_Init(); init_key(); } void main( void ) { WDTCTL = WDTPW + WDTHOLD; //关闭开门狗 init(); //初始化 while(1){ Vpp=get_Vpp(); LCD_Show(); } } 这里是附加的IIC.c代码 #include "msp430.h" #include "IIC.h" #include "font.h" //IIC延时函数 void IIC_delayus(unsigned int i) { unsigned int j,k; for(k=0;k<i;k++) for(j=0;j<4;i++); } //IIC初始化函数 void IIC_ioinit() { P6DIR|=BIT1|BIT5; //配置IIC IO口为输出方向 P6REN|=BIT1|BIT5; //配置IIC IO口使能上拉电阻 } //开始一个IIC通信 void IIC_start() { SCL_HIGH; SDA_HIGH; //IIC_delayus(2); SDA_LOW; //IIC_delayus(2); SCL_LOW; } //停止IIC通信 void IIC_stop() { SCL_LOW; SDA_LOW; //IIC_delayus(2); SCL_HIGH; SDA_HIGH; //IIC_delayus(2); } //IIC发送一个byte void IIC_writebyte(unsigned char IIC_byte) { unsigned char i; for(i=0;i<8;i++) { if(IIC_byte&0x80) SDA_HIGH; else SDA_LOW; SCL_HIGH; SCL_LOW; IIC_byte<<=1; //loop } SDA_HIGH; SCL_HIGH; SCL_LOW; } void IIC_writecmd(unsigned char IIC_command) { IIC_start(); IIC_writebyte(0x78); //Slave address,SA0=0 IIC_writebyte(0x00); //write command IIC_writebyte(IIC_command); IIC_stop(); } void IIC_writedata(unsigned char IIC_data) { IIC_start(); IIC_writebyte(0x78); IIC_writebyte(0x40); //write data IIC_writebyte(IIC_data); IIC_stop(); } /**************************LCD 设置坐标*******************************/ void LCD_Set_Pos(unsigned char x, unsigned char y) { IIC_writecmd(0xb0+y); IIC_writecmd(((x&0xf0)>>4)|0x10); IIC_writecmd((x&0x0f)|0x01); } /***************************LCD复位************************************/ void LCD_CLS(void) { unsigned char y,x; for(y=0;y<8;y++) { IIC_writecmd(0xb0+y); IIC_writecmd(0x01); IIC_writecmd(0x10); for(x=0;x<X_WIDTH;x++) IIC_writedata(0); } } /***************************LCD初始化************************************/ void LCD_Init(void) { IIC_ioinit(); IIC_writecmd(0xAE); //display off IIC_writecmd(0x20); //Set Memory Addressing Mode IIC_writecmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid IIC_writecmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7 IIC_writecmd(0xc8); //Set COM Output Scan Direction IIC_writecmd(0x00);//---set low column address IIC_writecmd(0x10);//---set high column address IIC_writecmd(0x40);//--set start line address IIC_writecmd(0x81);//--set contrast control register IIC_writecmd(0x7f); IIC_writecmd(0xa1);//--set segment re-map 0 to 127 IIC_writecmd(0xa6);//--set normal display IIC_writecmd(0xa8);//--set multiplex ratio(1 to 64) IIC_writecmd(0x3F);// IIC_writecmd(0xa4);//0xa4,Output follows RAM content;0xa5,Output ignores RAM content IIC_writecmd(0xd3);//-set display offset IIC_writecmd(0x00);//-not offset IIC_writecmd(0xd5);//--set display clock divide ratio/oscillator frequency IIC_writecmd(0xf0);//--set divide ratio IIC_writecmd(0xd9);//--set pre-charge period IIC_writecmd(0x22); // IIC_writecmd(0xda);//--set com pins hardware configuration IIC_writecmd(0x12); IIC_writecmd(0xdb);//--set vcomh IIC_writecmd(0x20);//0x20,0.77xVcc IIC_writecmd(0x8d);//--set DC-DC enable IIC_writecmd(0x14);// IIC_writecmd(0xaf);//--turn on oled panel LCD_CLS(); LCD_Set_Pos(0,0); } //在指定位置显示一个字符,包括部分字符 //x:0~127 //y:0~63 //mode:0,反白显示;1,正常显示 //size:选择字体 16/12 void LCD_ShowChar(unsigned char x,unsigned char y,unsigned char chr,unsigned char Char_Size) { unsigned char c=0,i=0; c=chr-' ';//得到偏移后的值 if(x>Max_Column-1) { x=0; y=y+2; } if(Char_Size ==16) { LCD_Set_Pos(x,y); for(i=0;i<8;i++) IIC_writedata(F8X16[c*16+i]); LCD_Set_Pos(x,y+1); for(i=0;i<8;i++) IIC_writedata(F8X16[c*16+i+8]); } else { LCD_Set_Pos(x,y); for(i=0;i<6;i++) IIC_writedata(F6x8[c][i]); } } //显示一个字符号串 void LCD_ShowString(unsigned char x,unsigned char y,unsigned char *chr,unsigned char Char_Size) { unsigned char j=0; while (chr[j]!='\0') { LCD_ShowChar(x,y,chr[j],Char_Size); x+=8; if(x>128) { x=0; y+=2; } j++; } } //m^n函数 unsigned long oled_pow(unsigned char m,unsigned char n) { unsigned long result=1; while(n--)result*=m; return result; } //显示一个数字 void LCD_ShowNum(unsigned char x,unsigned char y,unsigned long num,unsigned char len,unsigned char size2) { unsigned char t,temp; //unsigned char enshow=0; for(t=0;t<len;t++) { temp=(num/oled_pow(10,len-t-1))%10; /*if(enshow==0&&t<(len-1)) { if(temp==0) { LCD_ShowChar(x+(size2/2)*t,y,' ',size2); continue; }else enshow=1; }*/ LCD_ShowChar(x+(size2/2)*t,y,temp+'0',size2); } }
最新发布
05-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

btzhy

您的鼓励是我最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值