SI5338A - I2C - 配置程序

更新时间:2023-11-13 09:10:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

#include #include #include #include \

#include \ //clockbuilder产生寄存器值头文件

#define uchar unsigned char #define uint unsigned int

#define TRUE 1 #define FALSE 0

sbit SCL=P2^6; sbit SDA=P2^1; bit I2CErr = FALSE; bit LOCK_PLL = TRUE;

/*-------------------------------------------------------------------- 函数名称:延时

--------------------------------------------------------------------*/ void DELAY(void) {

_nop_(); _nop_(); _nop_(); _nop_(); }

/*-------------------------------------------------------------------- 函数名称:10us延时

--------------------------------------------------------------------*/ void DELAY_10(uchar n) {

do { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } while(--n);

}

/*-------------------------------------------------------------------- 函数名称:启动

--------------------------------------------------------------------*/ void I2C_Start(void) {

SDA=1; SCL=1;

DELAY(); SDA=0;

DELAY(); SCL=0; }

/*--------------------------------------------------------------------

函数名称:停止

--------------------------------------------------------------------*/ void I2C_Stop(void) {

SCL=0;

SDA=0; DELAY(); SCL=1; DELAY(); SDA=1; }

/*-------------------------------------------------------------------- 函数名称:测试应答

--------------------------------------------------------------------*/ bit I2C_WaitAck(void) {

uchar times=255; //避免故障,设定错误次数 SDA=1;

_nop_(); SCL=1; while(SDA)

{ times--; if(!times) //超时值为255 { I2C_Stop(); I2CErr=TRUE; return FALSE; } }

DELAY(); SCL=0;

I2CErr=FALSE; return TRUE; }

/*-------------------------------------------------------------------- 函数名称:发送应答

--------------------------------------------------------------------*/ void I2C_SendAck(void) {

SDA=0; DELAY(); SCL=1; DELAY(); SCL=0; }

/*-------------------------------------------------------------------- 函数名称:发送非应答

--------------------------------------------------------------------*/ void I2C_SendNoAck(void) { SDA=1; DELAY(); SCL=1; DELAY(); SCL=0; }

/*-------------------------------------------------------------------- 函数名称:发送1字节数据

--------------------------------------------------------------------*/

void I2C_SendByte(uchar dat) { uchar i; for(i=0;i<=7;i++) {

_nop_(); if((dat&0x80)==0x80) SDA=1; else SDA=0; dat<<=1; SCL=1; DELAY(); SCL=0; } }

/*--------------------------------------------------------------------

函数名称:接收1字节数据

--------------------------------------------------------------------*/ void I2C_RcvByte(uchar *pRdDat) { uchar i; SDA=1; for(i=0;i<=7;i++) { SCL=1; DELAY(); *pRdDat<<=1; *pRdDat|=SDA; SCL=0; DELAY(); } }

/*-------------------------------------------------------------------- 函数名称:写N字节数据

--------------------------------------------------------------------*/

void I2C_WrBytes(uchar wrDAdr1,uchar wordAdr1,uchar *pWrDat,uchar num1)

{

uchar i; I2C_Start(); I2C_SendByte(wrDAdr1); I2C_WaitAck(); I2C_SendByte(wordAdr1); I2C_WaitAck(); for(i=0;i

/*--------------------------------------------------------------------

函数名称:读N字节数据

--------------------------------------------------------------------*/

void I2C_RcvBytes(uchar wrDAdr2,uchar wordAdr2,uchar rdDAdr2,uchar *pRdDat,uchar num2) {

uchar i; I2C_Start(); I2C_SendByte(wrDAdr2);

I2C_WaitAck(); I2C_SendByte(wordAdr2);

I2C_WaitAck();

I2C_Stop(); I2C_Start(); I2C_SendByte(rdDAdr2);

I2C_WaitAck(); for(i=0;i

I2C_SendAck(); } I2C_RcvByte(pRdDat+i); I2C_SendNoAck(); I2C_Stop(); }

/*--------------------------------------------------------------------

函数名称:SI5338A写入register map

--------------------------------------------------------------------*/

void si5338_wrregmap(uchar addr,uchar reg,uint Reg_Num) {

uchar curr_val[1];

uchar clear_curr_val,clear_new_val,combined; // ignore registers with masks of 0x00

if(Reg_Store[Reg_Num].Reg_Mask != 0x00) {

if(Reg_Store[Reg_Num].Reg_Mask == 0xFF) {

// do a regular I2C write to the register // at addr with the desired data value

I2C_Start(); Outputs,set reg230[4]=1*/ I2C_SendByte(addr|0); I2C_WaitAck(); I2C_SendByte(reg); I2C_WaitAck();

I2C_SendByte(Reg_Store[Reg_Num].Reg_Val); I2C_WaitAck(); I2C_Stop(); }

else {

// do a read-modify-write using I2C and // bit-wise operations

// get the current value from the device at the // register located at addr

I2C_RcvBytes(addr|0,reg,addr|1,curr_val,1);

/*Disable

// clear the bits that are allowed to be

// accessed in the current value of the register

clear_curr_val = curr_val[0] & (~ Reg_Store[reg].Reg_Mask);

// clear the bits in the desired data that // are not allowed to be accessed

clear_new_val = Reg_Store[Reg_Num].Reg_Val & Reg_Store[reg].Reg_Mask;

// combine the cleared values to get the new // value to write to the desired register

combined = clear_curr_val | clear_new_val;

I2C_Start(); /*Disable Outputs,set reg230[4]=1*/ I2C_SendByte(addr|0); I2C_WaitAck(); I2C_SendByte(reg); I2C_WaitAck();

I2C_SendByte(combined); I2C_WaitAck(); I2C_Stop(); } } }

/*--------------------------------------------------------------------

函数名称:SI5338A写单寄存器

--------------------------------------------------------------------*/

void si5338_wrmask(uchar addr,uchar reg,uchar mask,uchar dat) {

uchar curr_val[1]; uchar clear_curr_val; uchar clear_new_val; uchar combined;

// ignore registers with masks of 0x00 if(mask != 0x00) {

if(mask == 0xFF)

{

// do a regular I2C write to the register // at addr with the desired data value

I2C_Start(); /*Disable

Outputs,set reg230[4]=1*/ I2C_SendByte(addr|0); I2C_WaitAck(); I2C_SendByte(reg); I2C_WaitAck();

I2C_SendByte(dat); I2C_WaitAck(); I2C_Stop();

}

else {

// do a read-modify-write using I2C and // bit-wise operations

// get the current value from the device at the // register located at addr

I2C_RcvBytes(addr|0,reg,addr|1,curr_val,1);

// clear the bits that are allowed to be

// accessed in the current value of the register clear_curr_val = curr_val[0] & (~ mask);

// clear the bits in the desired data that // are not allowed to be accessed

clear_new_val = dat & mask;

// combine the cleared values to get the new // value to write to the desired register

combined = clear_curr_val | clear_new_val;

I2C_Start(); reg230[4]=1*/ I2C_SendByte(addr|0);

/*Disable Outputs,set

I2C_WaitAck(); I2C_SendByte(reg); I2C_WaitAck();

I2C_SendByte(combined); I2C_WaitAck(); I2C_Stop();

} } }

/*--------------------------------------------------------------------

函数名称:配置第一片SI5338A

--------------------------------------------------------------------*/ void si5338_config1() {

uint i;

uchar reg1[1],reg2[1],reg3[1]; uchar time1=255; _nop_(); /*Disable Outputs,set reg230[4]=1*/ I2C_Start();

I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0xE6); I2C_WaitAck();

I2C_SendByte(0x1F); I2C_WaitAck(); I2C_Stop();

_nop_(); /*Pause LOL,set reg241[7]=1*/ I2C_Start();

I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0xF1); I2C_WaitAck();

I2C_SendByte(0x85); I2C_WaitAck(); I2C_Stop(); for(i=0;i<349;i++)

/*配置Register Map*/ {

si5338_wrregmap(si5338_addr1|0,Reg_Store[i].Reg_Addr,i); }

_nop_(); /*Configure PLL for locking,set reg49[7]=0*/ I2C_Start();

I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0x31); I2C_WaitAck();

I2C_SendByte(0x10); I2C_WaitAck(); I2C_Stop();

_nop_(); PLL,set reg246[1]=1*/

I2C_Start();

I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0xF6); I2C_WaitAck();

I2C_SendByte(0x02); I2C_WaitAck(); I2C_Stop();

_nop_(); /*Restart LOL,set reg241[7]=0*/ I2C_Start();

I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0xF1); I2C_WaitAck();

I2C_SendByte(0x05); I2C_WaitAck(); I2C_Stop();

DELAY_10(2500);

/*Initiate Locking of /*wait 25ms*/

I2C_Start(); //is PLL locked I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0xDA); I2C_WaitAck(); I2C_Stop(); I2C_Start(); I2C_SendByte(si5338_addr1|1); I2C_WaitAck(); I2C_RcvByte(reg1); I2C_SendNoAck(); I2C_Stop();

if((reg1[0]&0x11) != 0x00) { time1--; if(!time1) //超时值为255 { LOCK_PLL=FALSE; }

DELAY(); }

else {

LOCK_PLL=TRUE; }

_nop_(); /*copy 237[1:0] to 47[1:0]*/

I2C_RcvBytes(si5338_addr1|0,0xED,si5338_addr1|1,reg1,1); I2C_RcvBytes(si5338_addr1|0,0x2F,si5338_addr1|1,reg2,1); reg3[0]=(reg1[0]&0x03)|(reg2[0]&0xFC); I2C_Start();

I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0x2F);

I2C_WaitAck();

I2C_SendByte(reg3[0]); I2C_WaitAck(); I2C_Stop();

_nop_(); /*copy 236[7:0] to 46[7:0]*/

I2C_RcvBytes(si5338_addr1|0,0xEC,si5338_addr1|1,reg1,1); I2C_Start();

I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0x2E); I2C_WaitAck();

I2C_SendByte(reg1[0]); I2C_WaitAck(); I2C_Stop();

_nop_(); /*copy 235[7:0] to 45[7:0]*/

I2C_RcvBytes(si5338_addr1|0,0xEB,si5338_addr1|1,reg1,1); I2C_Start();

I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0x2D); I2C_WaitAck();

I2C_SendByte(reg1[0]); I2C_WaitAck(); I2C_Stop();

_nop_(); /*set 47[7:2] = 000101b*/

I2C_RcvBytes(si5338_addr1|0,0x2F,si5338_addr1|1,reg1,1); reg2[0]=(reg1[0]&0x03)|0x14; I2C_Start();

I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0x2F); I2C_WaitAck();

I2C_SendByte(reg2[0]); I2C_WaitAck(); I2C_Stop();

_nop_(); /*Set PLL to use FCAL values,set reg49[7]=1*/

I2C_Start();

I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0x31); I2C_WaitAck();

I2C_SendByte(0x90); I2C_WaitAck(); I2C_Stop();

_nop_(); /*Enable Outputs,set reg230[4]=0*/ I2C_Start();

I2C_SendByte(si5338_addr1|0); I2C_WaitAck(); I2C_SendByte(0xE6); I2C_WaitAck();

I2C_SendByte(0x00); I2C_WaitAck(); I2C_Stop(); }

void main(void) {

uchar data1[50];

DELAY_10(100);

si5338_config1();

I2C_RcvBytes(si5338_addr1|0,0x00,si5338_addr1|1,data1,50); I2C_RcvBytes(si5338_addr1|0,0x32,si5338_addr1|1,data1,50); I2C_RcvBytes(si5338_addr1|0,0x64,si5338_addr1|1,data1,50); I2C_RcvBytes(si5338_addr1|0,0x96,si5338_addr1|1,data1,50); I2C_RcvBytes(si5338_addr1|0,0xC8,si5338_addr1|1,data1,50);

DELAY(); DELAY(); DELAY(); }

本文来源:https://www.bwwdw.com/article/d9ev.html

Top