单片机DCO时钟频率校准
在前段时间的一个项目中,因为项目需求我们修安排使用单片机中非标准频率即非1MHz、8MHz、12MHz、16MHz这几个已经在出厂的时候即校准好的频率,因此采用了通过外部时钟校准单片机DCO时钟频率的方法。
校准流程如下图所示:
对于单片机通过Timer定时器的捕获模式来测量外界方波频率的例子相信大家都很熟悉,本次时钟校准方法与之类似,只不过这次是外部时钟已经确定,通过每次外界时钟输入上升沿的捕获时Timer计数器的数值大小来修改于DCO频率相关的DCOCTL以及BCSCTL1这两个寄存器的值。
所用代码如下所示:
//******************************************************************************
// MSP430F22x4 Demo - DCO Calibration Constants Programmer
//
// NOTE: THIS CODE REPLACES THE TI FACTORY-PROGRAMMED DCO CALIBRATION
// CONSTANTS LOCATED IN INFOA WITH NEW VALUES. USE ONLY IF THE ORIGINAL
// CONSTANTS ACCIDENTALLY GOT CORRUPTED OR ERASED.
//
// Description: This code re-programs the F2xx DCO calibration constants.
// A software FLL mechanism is used to set the DCO based on an external
// 32kHz reference clock. After each calibration, the values from the
// clock system are read out and stored in a temporary variable. The final
// frequency the DCO is set to is 1MHz, and this frequency is also used
// during Flash programming of the constants. The program end is indicated
// by the blinking LED.
// ACLK = LFXT1/8 = 32768/8, MCLK = SMCLK = target DCO
// //* External watch crystal installed on XIN XOUT is required for ACLK *//
//
// MSP430F22x4
// ---------------
// /|\| XIN|-
// | | | 32kHz
// --|RST XOUT|-
// | |
// | P1.0|--> LED
// | P2.1|--> SMLCK = target DCO
//
// A. Dannenberg
// Texas Instruments Inc.
// April 2006
// Built with IAR Embedded Workbench Version: 3.41A
//******************************************************************************
#include "msp430x21x1.h"#define DELTA_1MHZ 244 // 244 x 4096Hz = 999.4Hz
#define DELTA_8MHZ 2205 // 2205 x 4096Hz = 9.03MHz
#define DELTA_12MHZ 2894 // 2894 x 4096Hz = 11.85MHz
#define DELTA_16MHZ 3906 // 3906 x 4096Hz = 15.99MHzunsigned char CAL_DATA[8]; // Temp. storage for constants
volatile unsigned int i;
int j;
char *Flash_ptrA; // Segment A pointer
void Set_DCO(unsigned int Delta);void main(void)
{WDTCTL = WDTPW + WDTHOLD; // Stop WDTfor (i = 0; i < 0xfffe; i++); // Delay for XTAL stabilizationP1OUT = 0x10; // Clear P1 output latchesP1DIR = 0x11; // P1.0 outputP1SEL = 0X10; //P1.4 SMCLK//P2SEL |= 0x02; // P2.1 SMCLK output//P2DIR |= 0x02; // P2.1 outputj = 0; // Reset pointerSet_DCO(DELTA_16MHZ); // Set DCO and obtain constantsCAL_DATA[j++] = DCOCTL;CAL_DATA[j++] = BCSCTL1;Set_DCO(DELTA_12MHZ); // Set DCO and obtain constantsCAL_DATA[j++] = DCOCTL;CAL_DATA[j++] = BCSCTL1;Set_DCO(DELTA_8MHZ); // Set DCO and obtain constantsCAL_DATA[j++] = DCOCTL;CAL_DATA[j++] = BCSCTL1;Set_DCO(DELTA_1MHZ); // Set DCO and obtain constantsCAL_DATA[j++] = DCOCTL;CAL_DATA[j++] = BCSCTL1;Flash_ptrA = (char *)0x10C0; // Point to beginning of seg AFCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing GeneratorFCTL1 = FWKEY + ERASE; // Set Erase bitFCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits*Flash_ptrA = 0x00; // Dummy write to erase Flash seg AFCTL1 = FWKEY + WRT; // Set WRT bit for write operationFlash_ptrA = (char *)0x10F8; // Point to beginning of cal constsfor (j = 0; j < 8; j++)*Flash_ptrA++ = CAL_DATA[j]; // re-flash DCO calibration dataFCTL1 = FWKEY; // Clear WRT bitFCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bitDCOCTL = CALDCO_8MHZ;BCSCTL1 = CALBC1_8MHZ;BCSCTL2 = 0;//P1DIR |= 0X10;//P1SEL |= 0X10;while (1){P1OUT ^= 0x01; // Toggle LEDfor (i = 0; i < 0x4000; i++); // SW Delay}
}void Set_DCO(unsigned int Delta) // Set DCO to selected frequency
{unsigned int Compare, Oldcapture = 0,Totalcapture = 0;unsigned int CaptureTime = 0;BCSCTL1 |= DIVA_3; // ACLK = LFXT1CLK/8TACCTL2 = CM_1 + CCIS_1 + CAP; // CAP, ACLKTACTL = TASSEL_2 + MC_2 + TACLR; // SMCLK, cont-mode, clearwhile (1){Totalcapture = 0;for(CaptureTime=0;CaptureTime<8;CaptureTime++){while (!(CCIFG & TACCTL2)); // Wait until capture occuredTACCTL2 &= ~CCIFG; // Capture occured, clear flagCompare = TACCR2; // Get current captured SMCLKCompare = Compare - Oldcapture; // SMCLK differenceOldcapture = TACCR2; // Save current captured SMCLKTotalcapture +=Compare; // Save the total capture SMCLK}Totalcapture = Totalcapture>>3; // Get average captured SMCLKif (Delta == Compare)break; // If equal, leave "while(1)"else if (Delta < Compare){DCOCTL--; // DCO is too fast, slow it downif (DCOCTL == 0xFF) // Did DCO roll under?if (BCSCTL1 & 0x0f)BCSCTL1--; // Select lower RSEL}else{DCOCTL++; // DCO is too slow, speed it upif (DCOCTL == 0x00) // Did DCO roll over?if ((BCSCTL1 & 0x0f) != 0x0f)BCSCTL1++; // Sel higher RSEL}}TACCTL2 = 0; // Stop TACCR2TACTL = 0; // Stop Timer_ABCSCTL1 &= ~DIVA_3; // ACLK = LFXT1CLK
}
在本程序中我们通过Timer定时器去捕获外部32768/8=4096Hz时钟,并计数,通过该数值与正确的数值进行比较,然后修改DCO参数继续捕获,直到Timer计数与正确数值一致。一共需要校准出9.032MHz以及11.85MHz的时钟频率并将数据存储在FLASH中。(注:每片MSP430在FLASH中均会存储DCO频率设置为1MHz,8MHz,12MHz,16MHz等四个频率时所用的参数。)
单片机DCO时钟频率校准相关推荐
- pic单片机内部时钟校准c语言,实例讲解PIC单片机的时钟设置
什么时钟? 首先我们先讲讲什么是时钟.时钟就是单片机的心脏.每跳动一下.整个单片机的各个电路就同步的动作一下.就好像我们做广播体操的时候 广播上喊的节拍1234 2234 3234....然后我们全部 ...
- 51单片机,时钟频率,机器周期,与执行指令的时间
前言 单片机在执行语句时,需要特定的频率或者说"节奏",提供节奏的单元一般有两种:外部晶振以及内部RC震荡.晶振很在开发板上很常见,一般都是8Mhz或者12Mhz的.RC震荡单元我 ...
- 应广单片机使用IHRC校准ILRC--附带产物随机数产生器
应广单片机内部有两个时钟源分别是IHRC和ILRC,IHRC频率在16M附近,ILRC一般为几十K,IHRC在烧录的时候可以进行校准,IHRC校准之后,频率还比较稳定.ILRC没有校准这个功能. IH ...
- pic单片机内部时钟校准c语言,pic单片机时钟配置
pic单片机时钟配置 已有 1687 次阅读2016-1-2 18:38 |个人分类:发现 还是PIC12F1572,某个io 输出脉冲信号.io置高,置低都是立即数给寄存器,电平竟然要16us才变化 ...
- pic单片机内部时钟校准c语言,PIC系列单片机片内定时器实时时钟的实现(转)
PIC系列单片机片内定时器实时时钟的实现(转) (2008-08-11 14:24:59) 标签: 杂谈 1. 1 振荡频率的考虑 工作频率为4MHz 的单片机, 选择32. 768kHz 的晶振显然 ...
- PIC单片机RC振荡器的使用及校准方法
在PIC的单片机--MSP430F1611IPM中有多种型号有内部RC振荡器的功能,从而省去了晶振,不但节省了成本,并且我们还多了两个IO端口可以使用. 但是,由于RC振荡器中电阻.电容的离散性很大, ...
- 单片机系统的低功耗设计策略
http://blog.21ic.com/user1/349/archives/2006/20396.html 0 推荐 单片机系统的低功耗设计策略 作 者:清华大学 陈萌萌 邵贝贝 摘要:嵌入式系统 ...
- (九)单片机串行口 内部结构的讲解 01
1. 基本概念 常用于数据通信的传输方式有单工.半双工.全双工和多工方式. 单工方式:数据仅按一个固定方向传送.因而这种传输方式的用途有限,常用于串行口的打印数据传输与简单系统间的数据采集. 半双工方 ...
- c51矩形波输出汇编语言,51单片机汇编语言编程:用定时器控制输出矩形波
80C51单片机的时钟频率为12MHz,利用定时器T1和P1.0输出矩形脉冲. 波形只画出了2段:一段为100us 另一段为50us. 要完全的.完整的.详细的编写此程序的过程!谢谢 -------- ...
最新文章
- 接收服务器显示帧控制错误,Websocket连接关闭,出现错误“接收到意外的继续帧”...
- CSS 定位 (Positioning)
- 011_fastdfs-client-java模块
- 向量场可视化matlab,Matlab向量场可视化
- Python 爬虫利器三之 Xpath 语法与 lxml 库的用法
- java memorystream 包_存储在MemoryStream中的裁剪图像中心
- 树和二叉树2——输出广义表形式(带括号)二叉树
- 软件工程---gjb438b 质量规范体系
- 电商平台-会员积分系统的设计与架构
- 计算机盘0字节可用,本地磁盘显示0字节可用数据恢复方法教程
- 华硕天选如何改变屏幕亮度,以及键盘灯的效果
- electron-vue 添加右下角通知图标
- 你还有“不撞南墙不回头”之心吗?
- FX5U 结构体编程
- namenode无法启动,There appears to be a gap in the edit log. We expected txid 10323, but got txid 10324.
- SwiftUI放在Section中的进度条(ProgressView)首次刷新时不显示的解决
- 【网络工程】9、实操-万达酒店综合项目(三)
- ONEROOT获得Bithumb大股东BXA战略投资,成为区块链行业准独角兽
- Spring 5 + Spring MVC 5 + MyBatis 3 的 Maven 项目集成
- 魔兽世界私服trinitycore2的数据库TDB(1)