|
' 我的查表算法思路是这样的: 1、构造n个二维数组(n=你需要输入的最大频率值位数,例如你需要精确到10hz,最高30mhz,那么就有10m位、1m位、100k位、10k位、1k位、100hz位、10hz位,共7位,所以n=7)。 2、根据你所用的芯片型号,和晶振频率,计算出每个频率位0-9时的控制字。 3、使用时,把你频率的每一位控制字,查表读出,并相加(特别需要注意进位也需要处理)。 4、把加出的4字节控制字,送dds。 此方法,理论最大控制字误差为n。一般9851或9850dds,常用的晶振频率值条件下,此误差实际表现在频率上时,小于1hz的1到2个数量级。 查表部分具体程序(尚未进行硬件测试) - /*******************************************
- ad9850 dds控制子程序
- ********************************************
- 编写:bg4uvr
- 描述: mcs51单片机控制ad9850/ad9851子程序。
- 提供如下5个常用dds控制函数。例子中
- dds控制字表的dds型号为ad9850,晶振
- 为16mhz。
- 注意: 使用前请修改程序内相应硬件端口
- ********************************************/
- void dds_reset(void); //dds主复位程序
- void dds_serialmode(void); //dds串行方式设置
- void dds_set(void); //dds设置数据发送
- void fre2word(void); //dds控制字计算
- void freupdata(void); //dds频率输出更新
- /*******************************************/
- //其他函数此处省略,只留下了表的结构和控制字计算部分……
- /********************************************/
- //控制字表,dds=9850,晶振=16mhz
- //word=0x100000000*fre/16000000;
- /********************************************/
- unsigned char code dds_word_10mhz[2][4]={
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0xa0
- };
- unsigned char code dds_word_1mhz[10][4]={
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x10,
- 0x00,0x00,0x00,0x20,
- 0x00,0x00,0x00,0x30,
- 0x00,0x00,0x00,0x40,
- 0x00,0x00,0x00,0x50,
- 0x00,0x00,0x00,0x60,
- 0x00,0x00,0x00,0x70,
- 0x00,0x00,0x00,0x80,
- 0x00,0x00,0x00,0x90
- };
- unsigned char code dds_word_100khz[10][4]={
- 0x00,0x00,0x00,0x00, //0
- 0x99,0x99,0x99,0x01, //1
- 0x33,0x33,0x33,0x03, //2
- 0xcc,0xcc,0xcc,0x04, //3
- 0x66,0x66,0x66,0x06, //4
- 0x00,0x00,0x00,0x08, //5
- 0x99,0x99,0x99,0x09, //6
- 0x33,0x33,0x33,0x0b, //7
- 0xcc,0xcc,0xcc,0x0c, //8
- 0x66,0x66,0x66,0x0e //9
- };
- unsigned char code dds_word_10khz[10][4]={
- 0x00,0x00,0x00,0x00, //0
- 0xc2,0xf5,0x28,0x00, //1
- 0x85,0xeb,0x51,0x00, //2
- 0x47,0xe1,0x7a,0x00, //3
- 0x0a,0xd7,0xa3,0x00, //4
- 0xcc,0xcc,0xcc,0x00, //5
- 0x8f,0xc2,0xf5,0x00, //6
- 0x51,0xb8,0x1e,0x01, //7
- 0x14,0xae,0x47,0x01, //8
- 0xd7,0xa3,0x70,0x01, //9
- };
- unsigned char code dds_word_1khz[10][3]={
- 0x00,0x00,0x00, //0
- 0x93,0x18,0x04, //1
- 0x26,0x31,0x08, //2
- 0xba,0x49,0x0c, //3
- 0x4d,0x62,0x10, //4
- 0xe1,0x7a,0x14, //5
- 0x74,0x93,0x18, //6
- 0x08,0xac,0x1c, //7
- 0x9b,0xc4,0x20, //8
- 0x2f,0xdd,0x24, //9
- };
- unsigned char code dds_word_100hz[10][3]={
- 0x00,0x00,0x00, //0
- 0xdb,0x68,0x00, //1
- 0xb7,0xd1,0x00, //2
- 0x92,0x3a,0x01, //3
- 0x6e,0xa3,0x01, //4
- 0x49,0x0c,0x02, //5
- 0x25,0x75,0x02, //6
- 0x00,0xde,0x02, //7
- 0xdc,0x46,0x03, //8
- 0xb7,0xaf,0x03 //9
- };
- unsigned char code dds_word_10hz[10][2]={
- 0x00,0x00, //0
- 0x7c,0x0a, //1
- 0x14,0xf8, //2
- 0x75,0x1f, //3
- 0xf1,0x29, //4
- 0x6d,0x34, //5
- 0xea,0x3e, //6
- 0x66,0x49, //7
- 0xe2,0x53, //8
- 0x5f,0xfe //9
- };
- unsigned char code dds_word_1hz[10][2]={
- 0x00,0x00, //0
- 0x0c,0x01, //1
- 0x18,0x02, //2
- 0x25,0x03, //3
- 0x31,0x04, //4
- 0x3e,0x05, //5
- 0x4a,0x06, //6
- 0x57,0x07, //7
- 0x63,0x08, //8
- 0x6f,0x09 //9
- };
- /********************************************/
- //控制字计算
- void fre2word(void){
- unsigned int temp1,temp2;
- //计算w0的值。注意,本例dds工作在串行方式,这里w0是指控制字低8位,请区别于并行方式
- temp1=dds_word_1hz[fre[7]][0]+dds_word_10hz[fre[6]][0]+dds_word_100hz[fre[5]][0]+dds_word_1khz[fre[4]][0]+dds_word_10khz[fre[3]][0]+dds_word_100khz[fre[2]][0]+dds_word_1mhz[fre[1]][0]+dds_word_10mhz[fre[0]][0];
- w[0]=(unsigned char)temp1;
- //计算w0相加时的进位
- temp2=(unsigned char)(temp1>>8);
- //计算w1值
- temp1=dds_word_1hz[fre[7]][1]+dds_word_10hz[fre[6]][1]+dds_word_100hz[fre[5]][1]+dds_word_1khz[fre[4]][1]+dds_word_10khz[fre[3]][1]+dds_word_100khz[fre[2]][1]+dds_word_1mhz[fre[1]][1]+dds_word_10mhz[fre[0]][1]+temp2;
- w[1]=(unsigned char)temp1;
- temp2=(unsigned char)(temp1>>8);
- //计算w2值
- temp1=dds_word_100hz[fre[5]][2]+dds_word_1khz[fre[4]][2]+dds_word_10khz[fre[3]][2]+dds_word_100khz[fre[2]][2]+dds_word_1mhz[fre[1]][2]+dds_word_10mhz[fre[0]][2]+temp2;
- w[2]=(unsigned char)temp1;
- temp2=(unsigned char)(temp1>>8);
- //计算w3值
- temp1=dds_word_10khz[fre[3]][3]+dds_word_100khz[fre[2]][3]+dds_word_1mhz[fre[1]][3]+dds_word_10mhz[fre[0]][3]+temp2;
- w[3]=(unsigned char)temp1;
- }
' 学习了!非常感谢!
|