?? 9852.c
字號:
//===================================================================================
// 基于單片機的DDS頻率綜合器
//
//===================================================================================
#include <AT89X52.h>
#define LCM_RW P3_0 //定義LCD引腳
#define LCM_RS P3_1
#define LCM_E P3_2
#define LCM_Data P0
#define Key_Data P3_4 //定義Keyboard引腳
#define Key_CLK P3_3
#define DDS_Word P1 //定義DDS控制字接口
#define RESET_9851 P2_2
#define W_CLK P2_1
#define FQ_UD P2_0
#define predefine 131 //2^32除以DDS晶振頻率(32.768MHz)
void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
void Decode(unsigned char ScanCode);
void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM);
void UpdateData(void);
void UpdateScale(void);
void UpdateLCM(void);
void UpdateDDS(void);
unsigned char code num[] = {"0123456789"};
unsigned char disp_freq[16];
static unsigned char IntNum = 0; //中斷次數計數
static unsigned char KeyV; //鍵值
static unsigned char BF=0; //標識是否有字符被收到
static unsigned long freq=0;
static unsigned long word=0;
int i;
/*----------------------------------主程序-------------------------------*/
void main()
{
Delay400Ms(); //啟動等待,等LCM講入工作狀態
LCMInit(); //LCM初始化
LCMInit();
LCMInit();
DisplayListChar(0,0,"Xiang Fei");
Delay5Ms(); //延時
// InitDDS(); //向DDS送入初設值
IT1 = 0; //設外部中斷1為低電平觸發
EA = 1;
EX1 = 1; //開中斷
i=0;
while(1)
{
do
{
if (BF)
{
if (i==0)
{
WriteCommandLCM(0x01); //清屏
break;
}
else break;
}
}while(1);
EA=0;
UpdateData();
if ((KeyV==0x42) || (KeyV==0x3A) || (KeyV==0x5A)) //按下"K","M","Enter"更新頻率
{
UpdateScale();
word=predefine*freq; //計算頻率控制字
UpdateDDS(); //更新DDS function to be completed
freq=0; //清空數據緩沖區
i=0;
}
else
{
i++;
UpdateLCM(); //更新LCD顯示
}
BF=0; //按鍵標志歸零
EA=1; //重新開中斷
}
}
/*---------------------------------函數-----------------------------------*/
//寫數據
void WriteDataLCM(unsigned char WDLCM)
{
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在這后加小的延時
Delay5Ms();
LCM_E = 0; //延時
LCM_E = 1;
}
//寫指令
void WriteCommandLCM(unsigned char WCLCM)
{
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
Delay5Ms();
LCM_E = 0;
LCM_E = 1;
}
void LCMInit(void) //LCM初始化
{
LCM_Data=0;
WriteCommandLCM(0x38); //三次顯示模式設置,不檢測忙信號
Delay5Ms();
WriteCommandLCM(0x38);
Delay5Ms();
WriteCommandLCM(0x38);
Delay5Ms();
WriteCommandLCM(0x38); //顯示模式設置,開始要求每次檢測忙信號
Delay5Ms();
WriteCommandLCM(0x08); //關閉顯示
Delay5Ms();
WriteCommandLCM(0x01); //顯示清屏
Delay5Ms();
WriteCommandLCM(0x06); // 顯示光標移動設置
Delay5Ms();
WriteCommandLCM(0x0C); // 顯示開及光標設置
Delay5Ms();
}
//按指定位置顯示一個字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
Y&=0x1;
X&=0xF; //限制X不能大于15,Y不能大于1
if (Y) X|=0x40; //當要顯示第二行時地址碼+0x40;
X|=0x80; //算出指令碼
WriteCommandLCM(X); //發命令字
WriteDataLCM(DData); //發數據
}
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
unsigned char ListLength;
ListLength = 0;
Y &= 0x1;
X &= 0xF; //限制X不能大于15,Y不能大于1
while (DData[ListLength]>0x19) //若到達字串尾則退出
{
if (X <= 0xF) //X坐標應小于0xF
{
DisplayOneChar(X, Y, DData[ListLength]); //顯示單個字符
ListLength++;
X++;
}
}
}
//5ms延時
void Delay5Ms(void)
{
unsigned int TempCyc = 5552;
while(TempCyc--);
}
//400ms延時
void Delay400Ms(void)
{
unsigned char TempCycA = 5;
unsigned int TempCycB;
while(TempCycA--)
{
TempCycB=7269;
while(TempCycB--);
}
}
void Keyboard_out(void) interrupt 2
{
if ((IntNum > 0) && (IntNum < 9))
{
KeyV = KeyV >> 1; //因鍵盤數據是低>>高,結合上一句所以右移一位
if (Key_Data) KeyV = KeyV | 0x80; //當鍵盤數據線為1時為1到最高位
}
IntNum++;
while (!Key_CLK); //等待PS/2CLK拉高
if (IntNum > 10)
{
IntNum = 0; //當中斷11次后表示一幀數據收完,清變量準備下一次接收
BF = 1; //標識有字符輸入完了
EA = 0; //關中斷等顯示完后再開中斷
}
}
void UpdateData(void)
{
switch (KeyV)
{
case 0x45: // 按下"0"
freq=freq*10+0;
disp_freq[i]='0';
break;
case 0x16: // 按下"1"
freq=freq*10+1;
disp_freq[i]='1';
break;
case 0x1E: // 按下"2"
freq=freq*10+2;
disp_freq[i]='2';
break;
case 0x26: // 按下"3"
freq=freq*10+3;
disp_freq[i]='3';
break;
case 0x25: // 按下"4"
freq=freq*10+4;
disp_freq[i]='4';
break;
case 0x2E: // 按下"5"
freq=freq*10+5;
disp_freq[i]='5';
break;
case 0x36: // 按下"6"
freq=freq*10+6;
disp_freq[i]='6';
break;
case 0x3D: // 按下"7"
freq=freq*10+7;
disp_freq[i]='7';
break;
case 0x3E: // 按下"8"
freq=freq*10+8;
disp_freq[i]='8';
break;
case 0x46: // 按下"9"
freq=freq*10+9;
disp_freq[i]='9';
break;
case 0x42: // 按下"K"
freq=freq*1000;
break;
case 0x3A: // 按下"M"
freq=freq*1000000;
break;
}
}
void UpdateScale(void)
{
DisplayOneChar(14,0,'H');
DisplayOneChar(15,0,'z');
switch (KeyV)
{
case 0x42:
DisplayOneChar(13,0,'K');
break;
case 0x3A:
DisplayOneChar(13,0,'M');
break;
case 0x5A:
break;
}
}
void UpdateLCM(void)
{
int j;
for(j=0;j<i;j++)
{
DisplayOneChar(16-i+j,1,disp_freq[j]);
}
}
void UpdateDDS(void)
{
int j;
unsigned char CON[5];
RESET_9851=0;
RESET_9851=1;
RESET_9851=0;
FQ_UD=0;
CON[0]=0x00;
for(j=4;j>0;j--)
{
CON[j]=word;
word=word>>8;
}
for(j=0;j<5;j++)
{
W_CLK=0;
DDS_Word=CON[j];
W_CLK=1;
}
FQ_UD=1;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -