MSP430G2平台4 自校验DCO频率_第1页
MSP430G2平台4 自校验DCO频率_第2页
MSP430G2平台4 自校验DCO频率_第3页
MSP430G2平台4 自校验DCO频率_第4页
MSP430G2平台4 自校验DCO频率_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、LaunchPad 口袋实验平台口袋实验平台 MSP-EXP430G2篇篇1第第4讲讲 自校验自校验DCO频率频率24.1 普林斯顿结构普林斯顿结构 普林斯顿结构处理器的RAM和ROM统一编址,共用地址总线和数据总线。34.2 Flash4存储器FLASH NAND读一个扇区擦写一个扇区NOR随便读擦写一段SRAM随便读随便写4.3 Flash 控制器控制器 对Flash进行读操作无需任何硬件支持,就是读普通ROM。 对Flash写操作需要MSP430内部集成了Flash控制器。 Flash编程时钟:写太快不可靠,写太慢寿命低。5 Flash编程高压发生器 擦鞋Flash需要比读取Flash更

2、高的电压。 如图是Flash按字节写入时序过程。64.4 利用利用Flash进行掉电不失存储进行掉电不失存储7备份原数据段擦除全段数据写入目标数据还原其他数据 整段擦除为“1” 擦前备份擦 按字节写为“0” 重复写无效写4.5 Flash操作库函数操作库函数全局变量SegAddr,SegPre直接写字函数Flash_Direct_WriteWord()备份写字节函数Flash_Bak_WriteChar()初始化函数Flash_Init( )段擦除函数Flash_Erase()8初始化函数初始化函数Flash_Init( )/* 名 称:Flash_Init()* 功 能:对Flash时钟进行

3、初始化设置* 入口参数:Div:根据SMCLK频率计算的所需分频值,可设定为1-64* Seg:段号,可设为0-31或”A、B、C、D。* 出口参数:1:配置成功* 0:配置失败* 说 明:操作Flash其他函数前,需要调用该初始化函数设置时钟分频和待操作段首地址。* 其他函数中均不出现绝对地址,防止误操作。* 范 例: Flash_Init(3,B ) 3分频、对Info B段操作*/unsigned char Flash_Init(unsigned char Div,unsigned char Seg )/-设置Flash的时钟和分频,分频为恰好为最低位,直接用Div-1即可-if(Div

4、64) Div=64;FCTL2 = FWKEY + FSSEL_2 + Div-1; / 默认使用SMCLK,分频系数参数传入9初始化函数初始化函数Flash_Init( )/-操作对象为主Flash段的情况,可通过512的倍数设置段起始地址-SegPre = Seg;/获取当前段if (Seg = 31) /判断是否处于主Flash段SegAddr=0 xFFFF-(Seg+1)*512+1; /计算段起始地址 return(1);/赋值成功后即可退出并返回成功标志”1“/-操作对象为信息Flash段的情况,穷举即可-switch(Seg) /判断是否处于信息Flash段case A: c

5、asea: SegAddr=0 x10C0; break;case B: caseb: SegAddr=0 x1080; break;case C: casec: SegAddr=0 x1040; break;case D: cased: SegAddr=0 x1000; break;default: SegAddr=0 x20FF;return(0); /0 x20FF地址为空白区,保护Flashreturn(1);10擦除函数擦除函数Flash_Erase()* 名 称:Flash_Erase()* 功 能:擦除Flash的一个数据块,擦写段由初始化函数 Flash_Init()的SegA

6、ddr变量决定*/void Flash_Erase() unsigned char *Ptr_SegAddr; /Segment pointer Ptr_SegAddr = (unsigned char *)SegAddr; /Initialize Flash pointer FCTL1 = FWKEY + ERASE; /段擦除模式 FCTL3 = FWKEY; /解锁 /FCTL3 = FWKEY+LOCKA; /对InfoFlashA也解锁 _disable_interrupts(); *Ptr_SegAddr = 0; /擦除待操作段 while(FCTL3&BUSY); /B

7、usy _enable_interrupts(); FCTL1 = FWKEY; /取消擦模式 FCTL3 = FWKEY+LOCK; /上锁/ FCTL3 = FWKEY+LOCK+LOCKA; /对InfoFlashA也上锁11Flash_Direct_WriteWord()/* 名 称:Flash_Direct_WriteWord()* 功 能:强行向Flash中写入一个字型变量,而不管存储位置是否事先擦除* 入口参数:Addr:存放数据的偏移地址,仍按字节计算,需为偶数 Data:待写入的数据* 出口参数:返回出错信息 0:偏移溢出 ;1:正常工作* 范 例:Flash_Direct_

8、WriteWord(0,123);将常数123写入0单元 Flash_Direct_WriteWord(2,a);将整型变量a写入2单元*/char Flash_Direct_WriteWord (unsigned int Addr,unsigned int Data)unsigned int temp=0;unsigned int *Ptr_SegAddr; /Segment pointer /- 段范围限定。为了内存管理安全,只允许本段操作-if(SegPre=512) |(SegPre31&Addr=64) ) return 0;12Flash_Direct_WriteWord(

9、)13 return 0;temp=SegAddr+Addr;Ptr_SegAddr = (unsigned int *)temp; /Initialize Flash pointerFCTL1=FWKEY+WRT; /正常写状态FCTL3=FWKEY;/解除锁定/FCTL3=FWKEY+LOCKA; /解除锁定(包括A段)_disable_interrupts(); /关总中断*Ptr_SegAddr=Data;while(FCTL3&BUSY); /等待操作完成_enable_interrupts(); /开总中断FCTL1=FWKEY; /退出写状态FCTL3=FWKEY+LOC

10、K; /恢复锁定,保护数据/FCTL3=FWKEY+LOCK+LOCKA; /恢复锁定,保护数据(包括A段) return 1;备份擦写字节函数备份擦写字节函数Flash_Bak_WriteChar()/* 名 称:Flash_Bak_WriteChar()* 功 能:不破坏段内其他数据,向Flash中写入一个字节(Char型变量)* 入口参数:Addr:存放数据的地址 Data:待写入的数据* 出口参数:返回出错信息 0:偏移溢出 ;1:正常工作* 范 例:Flash_Bak_WriteChar(0,123);将常数123写入0单元 Flash_Bak_WriteChar(1,a);将变量a

11、写入1单元*/char Flash_Bak_WriteChar (unsigned char Addr,unsigned char Data)unsigned int temp=0;unsigned char *Ptr_SegAddr; /Segment pointerunsigned char BackupArray64;/开辟64字节的临时RAM备份Segunsigned char i = 0; /- 段范围限定。为了内存管理安全,只允许本段操作-if(SegPre=512) | (SegPre31&Addr64) ) return 0;14for(i=0;i64;i+) temp

12、=SegAddr+i; Ptr_SegAddr = (unsigned char *)temp; /Initialize Flash pointer BackupArrayi=*Ptr_SegAddr;/指针移位方法赋值Flash_Erase(); /擦除待操作段FCTL1 = FWKEY + WRT; /正常写入(非块写)FCTL3 = FWKEY ; /解锁/FCTL3 = FWKEY ; /解锁(含A段)for (i=0; i64; i+)_disable_interrupts(); /关总中断if(i=Addr) temp=SegAddr+Addr;15备份擦写字节函数备份擦写字节函数

13、Flash_Bak_WriteChar()16备份擦写字节函数备份擦写字节函数Flash_Bak_WriteChar()Ptr_SegAddr = (unsigned char *)temp; /Initialize Flash pointer *Ptr_SegAddr =Data; /写数据 while(FCTL3&BUSY); /等待写操作完成 else temp=SegAddr+i; Ptr_SegAddr = (unsigned char *)temp; /Initialize Flash pointer *Ptr_SegAddr = BackupArrayi; /恢复Flas

14、h内的其他数据 while(FCTL3&BUSY); /等待写操作完成_enable_interrupts();/开总中断FCTL1 = FWKEY; /清除写FCTL3 = FWKEY + LOCK; /上锁 / FCTL3 = FWKEY + LOCK; /上锁(含A段) return 1;4.6 DCO测频原理测频原理1725535/1615961.6DCOfmskHzMHz4.7 VLO测频原理测频原理 基于上次TAR值25535我们可以求得:1832.768(25535/ 45535)18.376VLOfkHzkHz4.8 自校验自校验DCO输出频率输出频率f 穷举DCO参数

15、设置,测出实际频率,即可完成校验。 4位RSELx:16个档位,每档频率步进约35%(不靠谱),可看成粗调。 3位DCOx:8个档位,每档频率步进约8%(不靠谱),可看成细调。 5位MODx:32个档位,每档步进 ,可看成微调。19321xxDCODCO确定确定RSELx与与DCOx20MODx=0 先不微调RSELx DCOx 共128种组合测出所有频率 WDT定时 TA计数存入Tempi 由i可反推出 RSELx DCOx 得到全部Temp数据后,找出最接近f但小于的f的tempi 比如是Temp35,这样我们就知道了RSELx=35/8=4,DCOx=35%8=3。确定确定MODx 固定

16、RSELx=4、DCOx=3,依次增加MODx的值,找到最接近f时的MODx值,比如说是12。 那么f对应的DCO参数就是RSELx=4、DCOx=3、 MODx=12。 仿照出厂校验的做法,将3个参数存在infoFLash中。21RSELx=4 DCOx=3递增MODx 共32种值测出所有频率 WDT定时 TA计数找到MODx 存入infoFlash4.9 自校验自校验DCO例程例程22 自校准1-16MHz共16个DCO配置参数(RSELx,DCOx,MODx),将参数写入InfoFlashB段中,调取校验参数,循环输出DCO的16个频率供观测。主函数主函数void main(void)W

17、DTCTL = WDTPW + WDTHOLD; /关狗/-在P1.4上输出SMCLK,这样可以全程用示波器和频率计观测DCO-P1SEL |= BIT4; P1DIR |= BIT4;/-初始化TA,开启WDT中断使能-TA0CTL = TASSEL_2+MC_2+TACLR; / SMCLK时钟源,连续计数开始IE1|=WDTIE; /开启WDT中断 _enable_interrupts(); /等同_ENT,开启总中断/-开始DCO频率校验,只运行一遍-Calibrate_Start(); /步骤1:红灯亮,表示正在校验DCOMeasure_Temp(); /步骤2:自动测量128个纯净

18、频率Find_RSELx_DCOx_Winer(); /步骤3:从128个纯净频率中,找出最接近预设频率的那几个Measure_MODx(); /步骤4:在最近接的纯净频率基础上,穷举找到最优的MODx设置Calculate_InfoFlash_Data();/步骤5:将最合适的频率设定参数组合成校验数组Write_InfoFlashB();/步骤6:将校验数组写入InfoFlahB段Calibrate_Finish();/步骤7:绿灯亮,表示完成校验DCO/-完成DCO校验,从Flash中定时取出校准值,从P1.4输出供测试-DCOTest(); /步骤8:循环输出DCO各个校验频率值,供观

19、测231、点亮红灯Calibrate_Start(); 2、测量128个“纯净”DCO频率Measure_Temp();3、找出最接近的16个“纯净”频率Find_RSELx_DCOx_Winer();4、找出最优MODxMeasure_MODx()5、合成校验数组Calculate_InfoFlash_Data()6、写入FlashWrite_InfoFlashB()7、点亮绿灯Calibrate_Finish();8、循环输出DCODCOTest()24流水账作业变量和宏定义变量和宏定义#include MSP430G2553.h#include Flash.h#define CALDCO

20、_MHz(x) * (unsigned char *)(0 x1080+(x-1)*2) /*读取InfoFlashB*/#define CALBC1_MHz(x) * (unsigned char *)(0 x1080+(x-1)*2+1)#define CAL_NUM 16 /*待校验频率点总数*/unsigned int Temp128=0; /*存放实测的128个不含小数分频MODx的“纯净”频率*/unsigned char RSELx_DCOx_WinerCAL_NUM=0; /*存放校验出的SELx和DCOx值*/unsigned char MODx_WinerCAL_NUM=0

21、; /*存放校验出的MODx值*/unsigned int InfoFlash_DataCAL_NUM=0; /*待写入infoB中的校验频率参数数组*/unsigned int Ture_FreqCAL_NUM=0; /*方便仿真时查看实测频率值*/ -待校正的频率,单位KHz-const unsigned int Calibrate_FrequenceCAL_NUM=1000,2000,3000,4000,5000,6000, 7000,8000,9000,10000,11000,12000,13000,14000,15000,16000;25 注意(x)的写法,实现宏定义“传参”操作。

22、Temp(不带MODx)和Ture_Freq(带MODx)存储的都是实际测量的频率值1、点亮红灯Calibrate_Start(); 2、测量128个“纯净”DCO频率Measure_Temp();3、找出最接近的16个“纯净”频率Find_RSELx_DCOx_Winer();4、找出最优MODxMeasure_MODx()5、合成校验数组Calculate_InfoFlash_Data()6、写入FlashWrite_InfoFlashB()7、点亮绿灯Calibrate_Finish();循环输出DCODCOTest()26流水账作业开始指示函数开始指示函数Calibrate_Start

23、()/* * 名 称:Calibrate_Start() * 功 能:红色LED亮,表明正在校验中 * 说 明:DCO校验的时间比较长,利用红灯指示可以方便调试程序*/void Calibrate_Start() /步骤1:红灯亮,表示正在校验DCOP1DIR |=BIT0+BIT6;P1OUT |= BIT0; /红亮绿灭表示正在校验P1OUT &=BIT6;27 在很多时候,一个小小的LED可以给程序调试乃至设备维护,故障排查带来很大方便。 本例中,红色LED亮表示校验正在进行。1、点亮红灯Calibrate_Start(); 2、测量128个“纯净”DCO频率Measure_Te

24、mp();3、找出最接近的16个“纯净”频率Find_RSELx_DCOx_Winer();4、找出最优MODxMeasure_MODx()5、合成校验数组Calculate_InfoFlash_Data()6、写入FlashWrite_InfoFlashB()7、点亮绿灯Calibrate_Finish();循环输出DCODCOTest()28流水账作业测频函数测频函数Measure_Temp() * 名 称:Measure_Temp() * 功 能:自动依次测定128种纯净DCO的频率,并存入Temp数组* 说 明:纯净频率是指MOD=0时的非混频 */void Measure_Temp(

25、) /步骤2:自动测量128个纯净频率unsigned long Freq_Temp=0;unsigned char RSELx_DCOx_Num=0;for(RSELx_DCOx_Num=0;RSELx_DCOx_Num128;RSELx_DCOx_Num+) DCO_Set_Freq(RSELx_DCOx_Num,0);/-定时测频代码开始-TA0CTL |=TACLR; /计数开始WDTCTL=WDT_ADLY_1_9;/WDT定时长度为精心选择过的,20MHz计数到39063 _bis_SR_register(LPM0_bits); /CPU精确休眠1.9ms(1/512秒)WDTCT

26、L=WDTPW+WDTHOLD;Freq_Temp = TA0R; /读取计数,这个值就是DCO在1/512秒中断区间的脉冲数/-定时测频代码结束-TempRSELx_DCOx_Num=(Freq_Temp)*512)/1000; /计算DCO准确频率29配置配置DCO的函数的函数DCO_Set_Freq()/* * 名 称:DCO_Set_Freq() * 功 能:根据传入参数,设定DCO频率 * 入口参数:Num:Num的02位表示DCOx,36位表示RSELx modTemp:MODx参数* 说 明:Num参数身兼二职,包含DCOx和RSELx的信息 * 范 例:DCO_Set_Freq

27、(10,5),表示将DCO设定为RSELx=1,DCOx=2,MODx=5*/void DCO_Set_Freq(unsigned char Num,unsigned char modTemp) /参数设定DCO频率DCOCTL = (Num%8)5)+modTemp; /数据拆分BCSCTL1 &=0 x0F;BCSCTL1 |=Num/8;_delay_cycles(15000); /等待DCO频率稳定30WDT定时中断服务子函数定时中断服务子函数/* * 名 称:WDT_ISR() * 功 能:响应WDT定时中断服务* 说 明:程序内部只有1句唤醒CPU代码,这种写法即用到了WD

28、T的定时功能,同时避免将 * 大量代码写入中断服务函数中,影响程序的可读性。*/#pragma vector=WDT_VECTOR_interrupt void WDT_ISR(void) _bic_SR_register_on_exit(LPM0_bits ); /退出中断时,唤醒CPU31 WDT定时中断仅起到了延时唤醒的作用。1、点亮红灯Calibrate_Start(); 2、测量128个“纯净”DCO频率Measure_Temp();3、找出最接近的16个“纯净”频率Find_RSELx_DCOx_Winer();4、找出最优MODxMeasure_MODx()5、合成校验数组Cal

29、culate_InfoFlash_Data()6、写入FlashWrite_InfoFlashB()7、点亮绿灯Calibrate_Finish();循环输出DCODCOTest()32流水账作业比较函数比较函数Find_RSELx_DCOx_Winer()/* * 名 称:Find_RSELx_DCOx_Winer() * 功 能:从128个Temp中,找出与16个校验频率最接近的Temp的序号* 说 明:Temp的序号里包含了RSELx和DCOx的取值信息*/void Find_RSELx_DCOx_Winer() /步骤3:从128个纯净频率中,找出最接近d的预设频unsigned ch

30、ar i=0;unsigned int Delta_Min=0;unsigned int Delta_Now=0;unsigned char Calibrate_Num=0;for(Calibrate_Num=0;Calibrate_NumCAL_NUM;Calibrate_Num+) Delta_Min=65530; /第一次比较时,故意定一个大差值33比较函数比较函数Find_RSELx_DCOx_Winer() for(i=0;i128;i+) /-单方向取最小差值,一定要小于预设值- if(TempiCalibrate_FrequenceCalibrate_Num) Delta_Now

31、=Calibrate_FrequenceCalibrate_Num-Tempi; if (Delta_NowDelta_Min)/如果当前差值比“世界记录”还小时 RSELx_DCOx_WinerCalibrate_Num=i;/新Winner诞生 Delta_Min=Delta_Now; /取代前“世界记录” 341、点亮红灯Calibrate_Start(); 2、测量128个“纯净”DCO频率Measure_Temp();3、找出最接近的16个“纯净”频率Find_RSELx_DCOx_Winer();4、找出最优MODxMeasure_MODx()5、合成校验数组Calculate_I

32、nfoFlash_Data()6、写入FlashWrite_InfoFlashB()7、点亮绿灯Calibrate_Finish();循环输出DCODCOTest()35流水账作业测频比较函数测频比较函数Measure_MODx()/* * 名 称:Measure_MODx() * 功 能:基于已校验成功的RSELx和DCOx,进一步校验出最合适的MODx* 说 明:本函数将固定RSELx和DCOx,穷举32种MODx的取值,然后判断最优的MODx*/void Measure_MODx() /步骤4:在最近接的纯净频率基础上,穷举找到最优的MODx设置unsigned char mod_x =

33、 0;unsigned long Freq_Temp = 0;unsigned int Delta_Now=0;unsigned int Delta_Min=0;unsigned char Calibrate_Num=0;for(Calibrate_Num=0;Calibrate_NumCAL_NUM;Calibrate_Num+)Delta_Min=65530;/第一次比较时,故意定一个大差值36测频比较函数测频比较函数Measure_MODx()/-RSELx和DCOx一定时,测量mod_x改变时的系列频率-for(mod_x=0;mod_x 32;mod_x+)DCO_Set_Freq(

34、RSELx_DCOx_WinerCalibrate_Num,mod_x);/改变mod_x设置DCO/-定时测频代码开始-TA0CTL |=TACLR;WDTCTL=WDT_ADLY_1_9;_bis_SR_register(LPM0_bits ); /CPU精确休眠1.9ms(1/512秒)WDTCTL=WDTPW+WDTHOLD;Freq_Temp = TA0R;/读取测频值 /-定时测频代码结束-Freq_Temp=(Freq_Temp)*512)/1000; /计算DCO准确频率 /-与Find_RSELx_DCOx_Winer()不同,这里的要求是正负差值最小-if(Freq_Tem

35、pCalibrate_FrequenceCalibrate_Num)Delta_Now=Calibrate_FrequenceCalibrate_Num-(unsigned int) Freq_Temp; elseDelta_Now=(unsigned int ) Freq_Temp - Calibrate_FrequenceCalibrate_Num;if (Delta_NowDelta_Min) /如果当前差值比“世界记录”还小时MODx_WinerCalibrate_Num=mod_x;/新Winner诞生Ture_FreqCalibrate_Num=(unsigned int )Fre

36、q_Temp; /记录校验后的准确频率Delta_Min=Delta_Now; /取代前“世界记录”371、点亮红灯Calibrate_Start(); 2、测量128个“纯净”DCO频率Measure_Temp();3、找出最接近的16个“纯净”频率Find_RSELx_DCOx_Winer();4、找出最优MODxMeasure_MODx()5、合成校验数组Calculate_InfoFlash_Data()6、写入FlashWrite_InfoFlashB()7、点亮绿灯Calibrate_Finish();循环输出DCODCOTest()38流水账作业数据合成函数数据合成函数Calculate_InfoFlash_Data()/* * 名 称:Calculate_InfoFlash_Data() * 功 能:基于已校验成功的RSELx、DCOx和MODx封装待写入Flash的数据* 说 明:16位数据的格式完全仿照出厂校验参数,最高4位固定1000,然后依次为RSLEx、DCOx和MODx。*/void Calculate_InfoFlash_Data() /步骤5:将最合适的频率设定参数组合成校验数组unsigned char RSELx=0;unsigned char DCOx=0;unsigned char i=0;for

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论