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

📄 2402test.c

📁 《爱上单片机》配书光盘(书本的制作作品所要的程序)
💻 C
📖 第 1 页 / 共 3 页
字号:

/********************************************************************************************
//Dy-2402C 桌面控制钟
//应用程序 C 
//杜洋
//V1.0 2007-4-20
//MCS-51 12MHZ C语言
//LCM2402 89S52 DS18B20 DS1302 AT24C02 红外接收IC
*********************************************************************************************/

/********************************************************************************************/
#include <AT89X52.h>
#include <string.h>                               // 包含头文件    
/********************************************************************************************/
typedef unsigned char      uint8;                // 无符号8位整型变量
typedef unsigned short     uint16;               // 无符号16位整型变量
typedef signed   char      int8;                 // 有符号8位整型变量

sbit LED1   = P2 ^ 3;                      // 定义LCM2402的RS控制线

/********************************************************************************************/
//全局变量
static unsigned char data IRCode[3],IRCON,IRCON2;//遥控器中断专用
static unsigned char data DT,menu,rom,alarm_con;//遥控寄存值/菜单值/定时器组值/报警开关选择
/********************************************************************************************/


//=================================LCM2402模块驱动===========================================//

/********************************************************************************************/
#define      LCM2402_DB0_DB7      P0             // 定义LCM2402的数据总线

sbit LCM2402_RS   = P1 ^ 0;                      // 定义LCM2402的RS控制线
sbit LCM2402_RW   = P1 ^ 2;                      // 定义LCM2402的RW控制线
sbit LCM2402_E    = P1 ^ 1;                      // 定义LCM2402的E控制线
sbit LCM2402_Busy = P0 ^ 7;                      // 定义LCM2402的测忙线(与LCM2402_DB0_DB7关联)

/********************************************************************************************/
//定义LCM2402指令集//
#define			CMD_clear		0x01             // 清除屏幕
#define			CMD_back		0x02             // DDRAM回零位
#define			CMD_dec1		0x04             // 读入后AC(指针)减1,向左写
#define			CMD_add1		0x06             // 读入后AC(指针)加1,向右写
#define			CMD_dis_gb1		0x0f             // 开显示_开光标_开光标闪烁
#define			CMD_dis_gb2		0x0e             // 开显示_开光标_关光标闪烁
#define			CMD_dis_gb3		0x0c             // 开显示_关光标_关光标闪烁
#define			CMD_OFF_dis		0x08             // 关显示_关光标_关光标闪烁
#define			CMD_set82		0x38             // 8位总线_2行显示
#define			CMD_set81		0x30             // 8位总线_1行显示(上边行)
#define			CMD_set42		0x28             // 4位总线_2行显示
#define			CMD_set41		0x20             // 4位总线_1行显示(上边行)
#define			lin_1			0x80             // 4位总线_1行显示(上边行)
#define			lin_2			0xc0             // 4位总线_1行显示(上边行)


/********************************************************************************************[底层协议]
* 函数名称:DelayS()	
* 功    能:延时
*********************************************************************************************/
void DelayS(unsigned int a){
	unsigned char i;
	while( --a != 0){		
		for(i = 0; i < 125; i++);  	//一个 ; 表示空语句,CPU空转。
	}   				   			//i 从0加到125,CPU大概就耗时1毫秒
}
void DelayS250(void){
	DelayS(250);
}
/********************************************************************************************[底层协议]
* 函数名称:LCM2402_TestBusy()
* 功    能:LCM2402测忙,若LCM2402处于忙状态,本函数将继续测忙,直到LCM2402处于非忙状态。
*********************************************************************************************/
void LCM2402_TestBusy(void){
   LCM2402_DB0_DB7 = 0xff;//设备读状态
   LCM2402_RS = 0;
   LCM2402_RW = 1;
   LCM2402_E = 1;
   while(LCM2402_Busy);//等待LCM不忙
   LCM2402_E = 0;//
}
/********************************************************************************************[底层协议]
* 函数名称:LCM2402_WriteCMD()
* 功    能:向LCM2402写命令。
* 入口参数:LCM2402_command     要写入LCM2402的命令字节
* 出口参数:无
*********************************************************************************************/
void LCM2402_WriteCMD(uint8 LCM2402_command) { 
  LCM2402_TestBusy();
  LCM2402_DB0_DB7 = LCM2402_command;
  LCM2402_RS = 0;
  LCM2402_RW = 0;
  LCM2402_E = 1;
  LCM2402_E = 0;
}
/********************************************************************************************[底层协议]
* 函数名称:LCM2402_WriteData()
* 功    能:向LCM2402写数据。
* 入口参数:LCM2402_data     要写入LCM2402的数据字节
* 出口参数:无
*********************************************************************************************/
void LCM2402_WriteData(uint8 LCM2402_data){ 
    LCM2402_TestBusy();
	LCM2402_DB0_DB7 = LCM2402_data;
  LCM2402_RS = 1;
  LCM2402_RW = 0;
  LCM2402_E = 1;
  LCM2402_E = 0;
}
/********************************************************************************************
* 函数名称:LCM2402_Init()
* 功    能:LCM2402初始化
* 入口参数:无
* 出口参数:无
*********************************************************************************************/
void LCM2402_Init(void){
  LCM2402_WriteCMD(CMD_set82);// 显示模式设置:显示2行,每个字符为5*7个像素
  LCM2402_WriteCMD(CMD_clear);// 显示清屏
  LCM2402_WriteCMD(CMD_back);// 数据指针指向第1行第1个字符位置
  LCM2402_WriteCMD(CMD_add1);// 显示光标移动设置:文字不动,光标右移
  LCM2402_WriteCMD(CMD_dis_gb3); // 显示开及光标设置:显示开,光标开,闪烁开
}


/********************************************************************************************
* 函数名称:print()
* 功    能:向LCM发送一个字符串,长度48字符之内。//应用:print("doyoung.net");
* 入口参数:字符串
* 出口参数:无
*********************************************************************************************/
void print(uint8 a,uint8 *str){
		LCM2402_WriteCMD(a);
		while(*str != '\0'){
			LCM2402_WriteData(*str++);
        }
		*str = 0;
}
/********************************************************************************************
* 函数名称:print2()
* 功    能:向LCM发送一个字符串,长度48字符之内。//应用:print("doyoung.net");
* 入口参数:字符串
* 出口参数:无
*********************************************************************************************/
void print2(uint8 a,uint8 t){//设置写入地址和数据//
		LCM2402_WriteCMD(a);
		LCM2402_WriteData(t);
}



//=================================AT24C02模块驱动===========================================//
//应用举例//
//AT24C02_Write1Byte(0x02,0xaa);                 	// 向AT24C02的地址0x02写入0xaa
//i = AT24C02_Read1Byte(0x02);              		// 从AT24C02的地址0x02读出数据给变量i
/*********************************************************************************************/
#define AT24C02_WriteDeviceAddress 0xa0			 /* 定义器件在I2C总线中的地址 */
#define AT24C02_ReadDeviceAddress  0xa1
sbit SCL=P2^1;      /* 定义位变量 */             // I2C总线的时钟信号
sbit SDA=P2^2;                                   // I2C总线的数据信号
#define TRUE        1
#define FALSE       0
#define I2C_DelayTime 60                         // 不要小于50,否则可能造成时序混乱
/********************************************************************************************
* 函数名称:I2C_Delay()
* 功    能:I2C总线软件延时
* 入口参数:count    延时参数,值越大,延时越长
* 出口参数:无
*********************************************************************************************/
void I2C_Delay(uint16 count){
  while(count!=0) count--;
}
/********************************************************************************************
* 函数名称:I2C_Start()
* 功    能:启动I2C总线
* 入口参数:无
* 出口参数:无
*********************************************************************************************/
void I2C_Start(void){
  SDA=1; 
  SCL=1; 
  I2C_Delay(I2C_DelayTime);
  SDA=0; 
  I2C_Delay(I2C_DelayTime);
  SCL=0;
  I2C_Delay(I2C_DelayTime);
}
/********************************************************************************************
* 函数名称:I2C_Stop()
* 功    能:终止I2C总线
* 入口参数:无
* 出口参数:无
*********************************************************************************************/
void I2C_Stop(void){
  SDA=0;
  SCL=1;
  I2C_Delay(I2C_DelayTime);
  SDA=1;
  I2C_Delay(I2C_DelayTime);
  SCL=0;
  I2C_Delay(I2C_DelayTime);
}
/********************************************************************************************
* 函数名称:I2C_Send_Bit_0()
* 功    能:发送比特0
* 入口参数:无
* 出口参数:无
*********************************************************************************************/
void I2C_Send_Bit_0(void){
  SDA=0;
  SCL=1;
  I2C_Delay(I2C_DelayTime);
  SCL=0;
  I2C_Delay(I2C_DelayTime);
}
/********************************************************************************************
* 函数名称:I2C_Send_Bit_1()
* 功    能:发送比特1
* 入口参数:无
* 出口参数:无
*********************************************************************************************/
void I2C_Send_Bit_1(void){
  SDA=1;
  SCL=1;
  I2C_Delay(I2C_DelayTime);
  SCL=0;
  I2C_Delay(I2C_DelayTime);
}
/********************************************************************************************
* 函数名称:I2C_Check_Ack()
* 功    能:发送完一个字节后检验设备的应答信号
* 入口参数:无
* 出口参数:返回值为True,成功
*           返回值为False,失败
*********************************************************************************************/
bit I2C_Check_Ack(void){
  SDA=1;
  SCL=1;
  I2C_Delay(I2C_DelayTime/2);
  F0=SDA;
  I2C_Delay(I2C_DelayTime/2);
  SCL=0;
  I2C_Delay(I2C_DelayTime);
  if(F0==1) return FALSE;
  return TRUE;
}
/********************************************************************************************
* 函数名称:I2C_Write8Bit()
* 功    能:向I2C总线写入8bit数据
* 入口参数:I2C_data     将要写入I2C总线的8bit数据 
* 出口参数:无
*********************************************************************************************/
void I2C_Write8Bit(uint8 I2C_data)reentrant{
	uint8 i;
	for(i=0;i<8;i++){
		if((I2C_data<<i)&0x80){
			I2C_Send_Bit_1();
		}
		else{
			I2C_Send_Bit_0();
		}
	}
}
/********************************************************************************************
* 函数名称:I2C_Read8Bit()
* 功    能:从I2C总线接收8bit数据
* 入口参数:无
* 出口参数:返回值为从I2C总线上接收到的8bit数据
*********************************************************************************************/
uint8 I2C_Read8Bit(void)reentrant{
	uint8 I2C_data=0,i;  
	for(i=0;i<8;i++){   
		SDA=1;    
		SCL=1;    
		I2C_Delay(10);
		F0=SDA;
		I2C_Delay(10);
		SCL=0;
		if(F0==1){
			I2C_data=I2C_data<<1;
			I2C_data=I2C_data|0x01;
		}
		else{
			I2C_data=I2C_data<<1;
		}
	}
    return I2C_data;
}
/********************************************************************************************
* 函数名称:AT24C02_Write1Byte()
* 功    能:向AT24C02指定地址上写入1字节数据
* 入口参数:AT24C02_Address   AT24C02内的地址
*           AT24C02_1Byte     将要写入AT24C02的1字节数据
* 出口参数:无
*********************************************************************************************/
void AT24C02_Write1Byte(	uint8 AT24C02_Address,
							uint8 AT24C02_1Byte){
  bit AckTemp=1;  
  I2C_Start();
  I2C_Write8Bit(AT24C02_WriteDeviceAddress);
  AckTemp=I2C_Check_Ack();
  I2C_Write8Bit(AT24C02_Address);                   
  AckTemp=I2C_Check_Ack();
  I2C_Write8Bit(AT24C02_1Byte);                 
  AckTemp=I2C_Check_Ack();
  I2C_Stop();
}
/********************************************************************************************
* 函数名称:AT24C02_Read1Byte()
* 功    能:从AT24C02指定地址上读出1字节数据
* 入口参数:AT24C02_Address   AT24C02内的地址
* 出口参数:从AT24C02指定地址上读出的1字节数据
*********************************************************************************************/
uint8 AT24C02_Read1Byte(uint8 AT24C02_Address){    
	bit AckTemp=1;  
  	uint8 AT24C02_1Byte;
  	I2C_Start();
  	I2C_Write8Bit(AT24C02_WriteDeviceAddress);
  	AckTemp=I2C_Check_Ack();
  	I2C_Write8Bit(AT24C02_Address);
  	AckTemp=I2C_Check_Ack();
  	I2C_Start();
  	I2C_Write8Bit(AT24C02_ReadDeviceAddress);
  	AckTemp=I2C_Check_Ack();
  	AT24C02_1Byte=I2C_Read8Bit();
  	AckTemp=I2C_Check_Ack();
  	I2C_Stop();
  	return AT24C02_1Byte;
}
/********************************************************************************************/
//设置定时值程序
void Set_alarm(unsigned char m,unsigned char sel,bit a){ //根据选择调整的相应项目加1并写入DS1302
  signed char address,item,item2;
  signed char max,mini;
  if(sel==7)  {address=0x0B; max=59;mini=0;}     //秒7
  if(sel==6)  {address=0x0A; max=59;mini=0;}    //分钟6
  if(sel==5)  {address=0x09; max=23;mini=0;}    //小时5
  if(sel==4)  {address=0x08; max=7;mini=1;}    //星期4  
  if(sel==3)  {address=0x07; max=31;mini=0;}    //日3
  if(sel==2)  {address=0x06; max=12;mini=0;}    //月2
  if(sel==1)  {address=0x05; max=99; mini=0;}    //年1
  if(sel==8)  {address=0x04; max=99; mini=0;}    //键号值
  address=address+(m*10);//选择定时项组

  		
  if (a == 0){//如果a是0则表示现在键入的是 十位 数据
  	AT24C02_Write1Byte(address,0x00);//将 个位 的数据清0 防止数值范围计算有错
    item = DT;//键值数给 十位
	item2 = 0;// 个位 填入 0
  }
  else{//否则是 个位数据
  	if(sel == 4){
		item = 0;
	}
	else{
  		item = (AT24C02_Read1Byte(address))/16;//先读出 十位 数据
	}
    item2 = DT;//键值放入 个位
  }  
  item=(item)*10 + (item2);//将 十位 和 个位 数据合成	 
  if(item>max) item=mini;//查看数值有效范围   
  if(item<mini) item=max;           
  AT24C02_Write1Byte(address,(item/10)*16+item%10);//转换成16进制写入24C00
  if(DT == 0x12){
  	AT24C02_Write1Byte(address,0xff);
  }	
}
/*****************************************************************************/



//===================================DS18B20驱动===========================================//
sbit DQ   = P2 ^ 0;                      // 定义DS18B20数据线

/******************************************************************************/
void Delay(int num)//延时函数
{
	while(num--) ;
}	
/******************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -