📄 mad9850fap_test1.c
字号:
/*
名称:AD9850测试程序
功能描述:输出频率、频率步进值、幅值均可调
4个按键接在 P3.0 -- 调幅
P3.1 -- 调步进值
P3.2 -- 频率加
P3.3 -- 频率减
按键低电平有效。
程序中的显示部分 用的是4位数码管 显示步进值,用户可根据需要自行改用其他显示
P0 -- 段码输出口
P2 -- 位码输出口
P3.5 -- 573使能口
//备注:调试通过
*/
//**********************************************
#include<reg52.h>
#include<intrins.h> //包含右移
#include<math.h>
/*数码管送段码函数*/
#define Ledbit(temp) P3 &=0XDF; P2 =temp; P3 |=0X20;
/*数码管送段位函数*/
#define Ledseg(temp) P3 &=0XDF;P0 =temp; P3 |=0X20;
sbit UPDCLK = P2^0; //20 更新时钟,上升沿锁存数据到编程寄存器
sbit MRESET = P2^1; //71 主复位端,高电平有效复位
sbit PMODE = P2^2; //70 串并编程模式选择 0:串行 1:并行
sbit WRCLK = P2^3; //21 写端口数据 上升沿锁存数据
sbit RDCLK = P2^4; //22 读端口数据 高电平读
sbit F_B_H = P2^5; //29 低电平
sbit OSK = P2^6; //30
sbit DATACLK= P1^0; //高电平有效,选中数据锁存器,低电平锁存
sbit ADDRCLK= P1^1; //高电平有效,选中地址锁存器,低电平锁存
sbit CONCLK = P1^2; //高电平有效,选中外部控制端驱运器,低电平锁存
sbit PD = P1^4;
sbit EN = P1^5;
sbit SCLK = P1^6;
sbit SDATA = P1^7;
//unsigned char Address; //寄存器地址
//unsigned char PortReg; //控制端口寄存器
//unsigned char MultReg; //乘法寄存器
//unsigned char ModeReg; //工作模式寄存器
//unsigned char PowerReg; //功率寄存器
unsigned char AH,AL; // 振幅字
unsigned char PH,PL; // 相位字
unsigned char resulth[4],resultm[4],resultl[4];
unsigned long int fwh,fwm,fwl;
unsigned char FWord[6]; // 存放频率字
unsigned long int fbj; // 频率步进值
unsigned long int pref; //要输出的频率值
unsigned char code led_code[20]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80, //数码管显示段码
0x90,0x88,0x83,0xc6,0xa1,0x86,0x81,0x7f,0xff,0xb7,0xb6};
unsigned char data dis_data[4]={0x00,0x00,0x00,0x00}; //显示缓冲区
unsigned char idata dis_bit[4]={0x7f,0xbf,0xdf,0xef};//位码单元
void WriteData(unsigned char DataByte); //写字节数据
void WriteADDR(unsigned char DATAAddress); //写寄存器地址
void UpdataFWord(void); //频率字更新
void UpdataAWord(void); //振幅字更新
void UpdataPWord(void); //相位字更新
void fck_hz(unsigned long int mf); //频率计算
void convertdoub_long(void); //长整型转1字节
void coutFWord(void); // 频率字计算
void switchpowrd(void); // 计算 要写入的预设频率的频率字
void Get_key(void); // 按键
void switchdata(void); //步进值拆码
void display(unsigned char *p,unsigned char n); //显示步进值
delay(unsigned int n);
void Delayms(unsigned int ms);
//*********************************
void main()
{
unsigned char n;//,ku;
P3 = 0XFF;
AH = 0XFF; // 振幅初始值
AL = 0XFF;
// PH = 0XFF; // 相位初始值
// PL = 0XFF;
fbj = 1; // 频率步进 初始值 1hz
pref = 1; // 频率初始值 1hz
//MultReg = 0x46; //乘法器
//PortReg = 0x04; //控制端口
P2=0;
DATACLK=0;
ADDRCLK=0;
P2=0x06; //设置成并行模式,并复位
for(n=5;n>0;)
n--;
P2=0x04;
CONCLK =0; //锁存控制端口状态
//*************************
WriteADDR(0x1E); //写乘法器地址
WriteData(0x46); //初始化乘法器,打开倍速频器,倍频6x50=300Mhz
// 4*50=200Mhz
//WriteADDR(0x1f); //工作模式选择地址
//WriteData(0x03); //模式001,是 Unramped FSK模式 ,Ramped FSK (Mode 010)
WriteADDR(0x20); //反辛格函数滤波器地址
WriteData(0X60); //0X60 是关闭反辛格函数滤波,0X20是打开反辛格函数滤波
UpdataAWord(); // 写 幅值
switchpowrd(); // 计算 要写入的预设频率的频率字
UpdataFWord(); // 写频率字
while(1)
{
// for(ku=0;ku<5;ku++)
// {
// UpdataAWord();
// UpdataPWord();
//switchpowrd();
// UpdataFWord();
// }
while(P3==0xff) //等待按键按下
{
switchdata();
display(dis_data,4);
}
Get_key(); //读键并处理
}
}
//*********************************
//***振幅字更新
void UpdataAWord(void)
{
WriteADDR(0x21); //幅度字高字节地址
WriteData(AH); //幅度字高字节
WriteADDR(0x22); //幅度字低字节地址
WriteData(AL);
}
/*
//*********************************
//***相位字更新
void UpdataPWord(void)
{
WriteADDR(0x00); //相位字高字节地址
WriteData(PH); //幅度字高字节
WriteADDR(0x01); //幅度字低字节地址
WriteData(PL);
}
*/
//*********************************
// 入口参数 mf 表示 要输出的频率值
// 0x0e,0x51,0x0a 的由来是:2^48/300000000hz=938249.9 = 0x0E510a
void fck_hz(unsigned long int mf)
{
fwh = mf*0x0e;
fwm = mf*0x51;
fwl = mf*0x0a;
}
void convertdoub_long(void) //将长整型数 转化成字节
{
unsigned char c=0;
unsigned char i=0;
for(i=0;i<4;i++)
{
resultl[i]=0;
resultm[i]=0;
resulth[i]=0;
}
i=0;
while(fwl/256)
{
c=fwl%256;
resultl[i++]=c;
fwl=fwl/256;
}
c=fwl%256;
resultl[i++]=c;
i=0;
while(fwm/256)
{
c=fwm%256;
resultm[i++]=c;
fwm=fwm/256;
}
c=fwm%256;
resultm[i++]=c;
i=0;
while(fwh/256)
{
c=fwh%256;
resulth[i++]=c;
fwh=fwh/256;
}
c=fwh%256;
resulth[i++]=c;
}
void coutFWord(void) // 计算频率字码
{
unsigned int md1=0,md2=0,md3=0,md4=0;
unsigned char mh=0;
FWord[0]=resultl[0];
md1=resultm[0]+resultl[1];
FWord[1]=md1;
md1=md1&0xff00;
mh=md1>>8;
md2=resulth[0]+resultm[1]+resultl[2]+mh;
FWord[2]=md2;
md2=md2&0xff00;
mh=md2>>8;
md3=resulth[1]+resultm[2]+resultl[3]+mh;
FWord[3]=md3;
md3=md3&0xff00;
mh=md3>>8;
md4=resulth[2]+resultm[3]+mh;
FWord[4]=md4;
md4=md4&0xff00;
mh=md4>>8;
FWord[5]=resulth[3]+mh;
}
void switchpowrd(void) // 写入目标频率 并计算频率字
{
fck_hz(pref);
convertdoub_long();
coutFWord();
}
//***频率字更新
void UpdataFWord(void)
{
WriteADDR(0x04);
WriteData(FWord[5]); //频率字最高字节
WriteADDR(0x05);
WriteData(FWord[4]);
WriteADDR(0x06);
WriteData(FWord[3]);
WriteADDR(0x07);
WriteData(FWord[2]);
WriteADDR(0x08);
WriteData(FWord[1]);
WriteADDR(0x09);
WriteData(FWord[0]); //频率字最低字节
}
//*********************************
//***写入数据
void WriteData(unsigned char DataByte)
{
unsigned char bdata x,y;
x =DataByte;
y =0;
if(x&0x01) //数据格式旋转180
y=y|0x80; //由D7 D6 D5 D4 D3 D2 D1 D0
if(x&0x02) // D0 D1 D2 D3 D4 D5 D6 D7
y=y|0x40;
if(x&0x04)
y=y|0x20;
if(x&0x08)
y=y|0x10;
if(x&0x10)
y=y|0x08;
if(x&0x20)
y=y|0x04;
if(x&0x40)
y=y|0x02;
if(x&0x80)
y=y|0x01;
P2=y;
DATACLK=1; //锁存数据
DATACLK=0;
}
//*********************************
//***完整地址
void WriteADDR(unsigned char DATAAddress)
{
P2=DATAAddress;
ADDRCLK=1;
ADDRCLK=0;
P2=0x04;
CONCLK = 1;
WRCLK=1;
WRCLK=0;
CONCLK = 0;
}
//按键程序****************************************************************
void Get_key(void)
{
unsigned char temp;
Delayms(50); //延时消抖
if(P3==0xff)return;
temp=P3;
switch(temp)
{
case 0xfe: // 振幅调节 减 若 0xffff 对应800mv(实际情况并不一定是800mv)
{ // 则此处 的调节 振幅是
AL=AL-0X33; // 每 按键一次 减 10mv
if(AL<0X12)
{
AL = 0XFF;
AH=AH-0X01;
if(AH<0X01)
{AH = 0XFF;
AL = 0XFF;
}
}
UpdataAWord();
}
break;
case 0xfd: //频率步进 控制键
{
if(fbj<=10) // 步进值小于10hz时,每按键一次步进值+1hz
{fbj=fbj+1;}
if(fbj>10&&fbj<=100) // 步进值小于100hz,大于10hz时,每按键一次步进值+10hz
{fbj=fbj+10;}
if(fbj>100&&fbj<=1000) // 意思 同上
{fbj=fbj+100;}
if(fbj>1000&&fbj<=10000)
{fbj=fbj+1000;}
if(fbj>10000&&fbj<=100000)
{fbj=fbj+10000;}
if(fbj>100000&&fbj<=1000000)
{fbj=fbj+100000;}
if(fbj>999999) // 最大步进值 999999hz
{fbj=1;}
}
break;
case 0xfb: //频率加调整
{
pref = pref+fbj;
if(pref>200000000) // 200MHZ
{pref=1;}
switchpowrd();
UpdataFWord();
}
break;
case 0xf7: //频率减调整
{
if(pref>=fbj)
{
pref = pref-fbj;
if(pref<fbj)
{pref = 1;}
}
switchpowrd();
UpdataFWord();
}
/* { // 相移键
PL=PL-0X33;
if(PL<0X12)
{
PH=PH-0X01;
if(PH<0X01)
{PH = 0XFF;
PL = 0XFF;
}
}
}*/
break;
default: break;
}
//while(!(P3==0xff)); //等待按键释放
//Delayms(800);
}
void switchdata(void)
{
if(fbj<9999)
{
dis_data[0]=fbj/1000; //gao
dis_data[1]=fbj%1000/100;
dis_data[2]=fbj%100/10;
dis_data[3]=fbj%10; //di
}
if(fbj>9999&&fbj<99999)
{
dis_data[0]=18; //gao // 标志位
dis_data[1]=fbj/10000; // 有效位
dis_data[2]=fbj%10000/1000; // 有效位
dis_data[3]=3; //di //3 表示 有效位后 0 的个数
}
if(fbj>99999&&fbj<999999)
{
dis_data[0]=19; //gao // 标志位
dis_data[1]=fbj/100000; // 有效位
dis_data[2]=fbj%100000/10000; // 有效位
dis_data[3]=4; //di //4 表示 有效位后 0 的个数
}
}
void display(unsigned char *p,unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
{
Ledbit(dis_bit[i]); //送段码
Ledseg(led_code[p[i]]); //送位码
delay(40); //显示延时:小于20/i 秒
Ledseg(0Xff); //消隐
}
}
delay(unsigned int n)
{
while(n)
n--;
}
void Delayms(unsigned int ms)
{
unsigned char i;
while(ms--)
{
for(i=126;i>1;i--);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -