⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 yuanma.c

📁 键盘开发源码
💻 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 + -