程序如下:
//#include "main.h"
#include "HT49RA1.h"
/******************************************************************************************/
//定义宏
/******************************************************************************************/
//#define testbit(var,bitno) ((var)&(1<<(bitno)))
//#define bitset(var,bitno) ((var)|=(1<<(bitno)))
//#define bitclr(var,bitno) ((var)&=~(1<<(bitno)))
//***************表格区****************//
#pragma vector timer_base @0x14 //时基中断
#pragma vector timer_rtc @0x18 //RTC中断
#define done _pa5 //done = pa.5
#define mode _pb4
#define rst _pb3
#define left _pb2
#define dec _pb1
#define add _pb0
//#define SDA _pa4
#define IIC_SDA _pa1
#define IIC_SCL _pa3
#define WP _pa4 //
void ram_clr(void);
// void lcd_test(void);
// void lcd_clear(void);
void lcd_test_clear(unsigned char test);
void show_lock_on_auto_off(void);
void DisplayLcd(unsigned char addr,unsigned char data1);
void DisplayLcd_67(unsigned char addr,unsigned char data1);
//void showRTC(void);
//void showRTC_temp(void);
void Time_pd(void);
void Time_buchang(void);
void time_tz(void);
void time_realy(void);
// void time_basejs(void);
void wd_set_add(void);
void wd_set_dec(void);
void wd_set_left(void);
void wd_set(void);
void set_mode_add(void);
void set_rst(void);
void set_left(void);
void set_dec(void);
void set_add(void);
void set_on_off_show(void);
void month_pd(void);
void day_pd(void);
void set_wd_show(void);
void display(unsigned char addr1,unsigned char s_ram);
void display_67(unsigned char addr1,unsigned char s_ram);
void clearram23(void);
void clearram(unsigned char addr3);
void displayns(void);
unsigned char b16_10(unsigned char temp0);
unsigned char Read_Key(void);
void show_day_adjust(void);
void time_setjs(void);
void clr_lock_on_auto_off(void);
void time_run_adj_show(void);
void time_left(void);
void time_dec(void);
void time_add(void);
//void export_time_adj(void);
void export_mode_3s(void);
void Time_realy(void);
void displayweek(unsigned char week_show);
// void index_set_time(void);
void set_week_import(void);
void set_week_export(void);
void min_hour_set_import(void);
void min_hour_set_export(void);
//eeprom.c
// void WREPP(unsigned char *str,unsigned char count,unsigned char addr,unsigned char WR_RD);
void Byte_WR(void);
void eeprom_write(unsigned char WRITE_SJ);
void RDEPP(unsigned char ADDR);
// void RDEPP(unsigned char *str,unsigned char count);
void Byte_RD(void);
void BSTART(void);
void BSTOP(void);
unsigned char ACK_WR(void);
void ACK_RD(void);
// void I2C_busy(void);
// void nop_nop(void);
// void eeprom_write(void);
void eeprom_read_preset(void);
void delay(unsigned int t);
void delay_IIC(void);
void IIC_Init(void);
void IIC_start(void);
void IIC_stop(void);
bit IIC_Tack(void);
void IIC_single_byte_write(unsigned char Daddr,unsigned char Waddr,unsigned char Data);
unsigned char IIC_single_byte_read(unsigned char Daddr,unsigned char Waddr);
void IIC_write_byte(unsigned char Data);
unsigned char IIC_read_byte(void);
void IIC_BUSY(void);
/******************************************************************************************/
unsigned char LcdRam[18] @ 0x140; //Lcd Ram
/******************************************************************************************/
#pragma rambank0
unsigned char delay_keys;
unsigned char bcock @ 0xFF; //数据全部清零
unsigned char WRITE_SJ; //纬度,+为N维,-为S维
unsigned char READ_SJ; //纬度,+为N维,-为S维
unsigned char vol_left; //左移判断
unsigned char index;
unsigned char i;
unsigned char temp; //纬度时间调整用
unsigned char wr_rong;
unsigned char Data3;
unsigned char TXBUF,RXBUF,Bit_CT,Byte_CT;
bit bit_lock; //手/自动标志位
bit bit_on;
bit bit_auto;
bit bit_off;
bit bit_rtc; //0.5s判断标志位
//bit bit_runyear; //天加1标志位
bit bit_min; //动作点判断用
bit bit_work; //工作标志位
bit bit_set_on_off_menu;
bit bit_set_wd_menu;
bit bit_key_dec_1s;
bit bit_key_add_1s;
bit bit_mode_add;
bit bit_mode_flag;
bit bit_left_flag;
bit bit_mode_add_first;
bit bit_power_on;
bit bit_lcd_on;
bit bit_key_occur;
bit bit_time_set_to_base;
bit bit_eeprom;
bit bit_eeprom_finish;
//按键宏定义
#define key_left_3s 12
#define key_rst_3s 11
#define key_dec_1s 10
#define key_add_1s 9
#define key_mode_3s 8
#define key_mode_rst 7
#define key_mode_add 6
#define key_mode 5
#define key_rst 4
#define key_left 3
#define key_dec 2
#define key_add 1
#define key_no 0
#define k_set_num 24
#define array_index 48
#define array_1_index 24
//#define SDA_OUT 0X00 //SDA SCL均为输出
//#define SDA_IN 0X10 //SDA为输入 SCL为输出
//#define EE_WR 0XA0//1010 A2A1A00
//#define EE_RD 0XA1//1010 A2A1A01
#define EE_WR 0XA6//1010 A2A1A00 A1=1;A0=1
#define EE_RD 0XA7//1010 A2A1A01 A1=1;A0=1
#define READ 0X01
#define WRITE 0X00
#pragma norambank
//#pragma norambank
/***************************************************/
//写EEPROM函数WREPP
//A1=1;A0=1;WP=写保护
/***************************************************/
//void WREPP(unsigned char *str,unsigned char count,unsigned char addr,unsigned char WR_RD)
/*
void main(void)
{
_qosc = 0; //?????
_delay(10000);
ram_clr(); //CLR RAM
_lcdc=0x03; //LCD?? RTC??
for (i=0;i<18;i++)
LcdRam = 0xf; //lcd show test;
_delay(10000);
_emi = 1; //????
// _tbf = 0;
// while(sec<3)
// {
// _etbi = 1; //??????
_emi = 1; //????
_halt();
// }
// sec = 0;
_qosc = 1;
// lcd_clear();
for (i=0;i<18;i++)
LcdRam = 0;
while(1)
{
_pcc=1;
_nop();_nop();
SCL=1;
_nop();_nop();
if(SDA)//如SDA为0则总线忙
{
break;
}
else
{
SDA=1;//把SDA强制拉高
_pcc=0;
_nop();
}
done = 0;
//先测试写保护
WP = 1;
eeprom_write(0xaa);//地址固定写0
if(wr_wrong==1)
{
WP = 0; //close write protect
_pcc=1;
_nop();_nop();
SCL=1;
_nop();_nop();
if(SDA)//如SDA为0则总线忙
{
break;
}
else
{
SDA=1;//把SDA强制拉高
_pcc=0;
_nop();
}
eeprom_write(0xaa);
_pcc=1;
_nop();_nop();
SCL=1;
_nop();_nop();
if(SDA)//如SDA为0则总线忙
{
break;
}
else
{
SDA=1;//把SDA强制拉高
_pcc=0;
_nop();
}
eeprom_read_preset();
if(done)
{
// _emi = 1; //????
_halt();
}
done = 0;
wr_wrong = 0;
}
else
{
done = 0;
}
}
}
void ram_clr(void)
{
_rtcc=0x07; //????????
_intc0=0;
_tmr0c=0x08;
_tmr1c=0x08;
done=0; //???IO?
_pa=0; //初始化IO口
_pc=0;
_pcc=0x01;
_pd=0x0f;
_intc1=0;
_bp=0; //??????
_mp0=0x60;//???????????9????????????bug;
bcock=0x9F;
loop_ram_clr:
_iar0=0;
_mp0++;
bcock--;
if(bcock)
goto loop_ram_clr;
bit_auto = 1;
bit_off = 1;
}
/*
void WREPP(unsigned char temppp,unsigned char addr)
{
unsigned char i;
// while(bit_eeprom)
// {
BSTART();
// Byte_CT=count+2;
i=0;
// while(Byte_CT)
// {
WREPP_GOON:
switch(i)
{
case 0:TXBUF=EE_WR;break;
case 1:TXBUF=addr;break;
default:TXBUF=temppp;break;
}
Byte_WR();
while(ACK_WR()==0)
{
if(temp++>=10000) //超时无应答则退出
{
// wr_wrong = 1;
goto WREPP_ERR;
}
}
if(++i>=3)
{
// ++str;
// --Byte_CT;
// bit_eeprom=0;
BSTOP();
// bit_eeprom_finish=1; //eeprom操作完毕
goto WREPP_RIGHT;
}
else
goto WREPP_GOON; //未完成写操作,继续
WREPP_ERR:
done = 0;
wr_wrong = 1; //写操作错误
goto WREPP_END;
WREPP_RIGHT:
wr_wrong = 0; //写操作正确
WREPP_END:
_nop();
BSTOP();
}
/***************************************************/
//发送1字节数据子程序Byte_WR
/***************************************************/
/*
void Byte_WR(void)
{
// _pa=SDA_OUT;
_pcc=0;
Bit_CT=0x08; //设置字节长度
while(Bit_CT)
{
_nop();_nop();
SCL=0;
SDA=0;
_nop();_nop();
// if(testbit(TXBUF,7))
if(TXBUF & 0b10000000)
{SDA=1;}
_nop();_nop();
SCL=1;
TXBUF<<=1; //移位,准备发送下一位数据
Bit_CT--;
}
_nop();
SCL=0;
}
/***************************************************/
//读EEPROM函数RDEPP
/***************************************************/
//void RDEPP(unsigned char *str,unsigned char count)
/*
void RDEPP(unsigned char ADDR)
{
BSTART();
TXBUF=EE_WR;
Byte_WR();
while(ACK_WR()==0)
{
if(temp++>=10000) //超时无应答则退出
{
wr_wrong = 1;
goto RDEPP_END;
}
}
TXBUF=ADDR;//写地址再读出
Byte_WR();
while(ACK_WR()==0)
{
if(temp++>=10000)
{
wr_wrong = 1;
goto RDEPP_END;
}
}
TXBUF=EE_RD; //地址写完后接着送读指令
Byte_WR();
while(ACK_WR()==0)
{
if(temp++>=10000) //超时无应答则退出
{
wr_wrong = 1;
goto RDEPP_END;
}
}
Byte_RD();
READ_SJ=RXBUF;//读出数据放READ_SJ
// if(--count)
ACK_RD();
// }
// if(bit_eeprom)
// bit_eeprom_finish=1; //eeprom操作完毕
RDEPP_END:
_nop();
BSTOP();
}
/***************************************************/
//接收1字节数据子程序Byte_RD
/***************************************************/
/*
void Byte_RD(void)
{
SCL=0;
// _pa=SDA_IN;
_pcc=1;
RXBUF=0;
Bit_CT=0x08; //设置字节长度
while(Bit_CT)
{
_nop();_nop();
SCL=0;
_nop();_nop();
RXBUF<<=1;//移位,准备接收下一位数据
if(SDA)
// {bitset(RXBUF,0);}
{RXBUF |= 0b00000001;}
_nop();_nop();
SCL=1;
Bit_CT--;
}
}
/***************************************************/
//总线查询程序I2C_busy
/***************************************************/
/***************************************************/
//开始命令程序BSTART
/***************************************************/
/*
void BSTART(void)
{
SCL=1;
SDA=0;
// _pa=SDA_OUT;
_pcc=0;
}
/***************************************************/
//停止命令程序BSTOP
/***************************************************/
/*
void BSTOP(void)
{
SCL=0;
SDA=0;
// _pa=SDA_OUT;
_pcc=0;
_nop();_nop();
SCL=1;
_nop();_nop();
SDA=1; //发出停止命令
_nop();_nop();
SCL=0;
}
/***************************************************/
//应答程序ACK_WR
/***************************************************/
/*
unsigned char ACK_WR(void)
{
SCL=0;
// _pa=SDA_IN;
_pcc=1;
_nop();_nop();
SCL=1;
_nop();_nop();
if(!SDA)//如SDA为0则为有应答
{
SCL=0;
return 1;
}
else
{
return 0;
}
}
/***************************************************/
//应答程序ACK_RD
/***************************************************/
/*
void ACK_RD(void)
{
SCL=0;
// _pa=SDA_OUT;
_pcc=0;
SDA=0;
_nop();_nop();
SCL=1;
_nop();_nop();
}
/***************************************************/
//应答程序ACK_RD
/***************************************************/
/*void nop_nop(void)
{
_nop();_nop();
}
/***************************************************/
//应答程序ACK_RD
/***************************************************/
/*
void eeprom_write(unsigned char WRITE_SJ)
{
// bit_eeprom=1; //如无中断则eeprom操作继续
// bit_eeprom_finish=0; //eeprom操作开始
WREPP(WRITE_SJ,0);//地址放0
// bit_eeprom_finish=0;
}
/***************************************************/
//应答程序ACK_RD
/***************************************************/
/*
void eeprom_read_preset(void)
{
//修复eeprom不连接时会下载错误数据的bug;
// bit_eeprom=1; //如无中断则eeprom操作继续
// bit_eeprom_finish=0; //eeprom操作开始
READ_SJ = 0;
RDEPP(0);
WREPP(0xff,0); //clearmemory
if(wr_wrong)
{
done = 0;
goto read_end;
}
if(READ_SJ==0xaa) //读出结果与写入一致
done=1;
else
done = 0;
read_end:
_nop();
}
*/
void main(void)
{
_qosc = 0;
_emi = 0;
IIC_Init();//初始化IIC总线。
while(1)
{
_pa2 = 0;
_pa0 = 0;
_pa6 = 0;
_pa7 = 0;
done = 0;
WP = 0;
delay(5);//延时
IIC_BUSY();
IIC_single_byte_write(0xa6,0x02,0xaa);//xie状态
if(wr_rong == 0)
{
_pa6 = 1;
_delay(100);
IIC_BUSY();
Data3 = IIC_single_byte_read(0xa6,0x02);//读状态
if(wr_rong==0)
{
_pa0 = 1;
}
_delay(100);
IIC_BUSY();
IIC_single_byte_write(0xa6,0x02,0xff);//clear eeprom
if(wr_rong == 0)
{
_pa7 = 1;
if(Data3 == 0xaa)
{
done = 1;
_halt();
}
}
}
}
}
//==========================功能子函数===============================
void delay(unsigned int t)
{//延时函数
while(t){t--;}; //延时循环计数
}
//-------------------------------------------------------------------
/********
void delay_IIC(void)
{//IIC总线限速延时函数。
;;
}
************/
void IIC_BUSY(void)
{
IIC_SDA = 1;
_nop();
IIC_SCL = 1;
_nop();
IIC_SCL = 0;
while(IIC_SDA==0)
{
IIC_SDA = 1;
}
}
//-------------------------------------------------------------------
void IIC_Init(void)
{//IIC总线初始化函数
// _pcc = 1;
IIC_SDA=1;//释放IIC总线的数据线。
IIC_SCL=1;//释放IIC总线的时钟线。
// _pcc = 0;
}
//-------------------------------------------------------------------
void IIC_start(void)
{//IIC总线产生起始信号函数
IIC_SDA=1;//拉高数据线
_nop();
IIC_SCL=1;//拉高时钟线
_nop();
IIC_SDA=0;//在时钟线为高电平时,拉低数据线,产生起始信号。
_nop();
IIC_SCL=0;//拉低时钟线
}
//-------------------------------------------------------------------
void IIC_stop(void)
{//IIC总线产生停止信号函数
IIC_SDA=0;//拉低数据线
_nop();
IIC_SCL=1;//拉高时钟线。
_nop();
IIC_SDA=1;//时钟时线为高电平时,拉高数据线,产生停止信号。
_nop();
IIC_SCL=0;//拉低时钟线。
}
//-------------------------------------------------------------------
bit IIC_Tack(void)
{//接收应答信号函数
bit ack;//定义一个位变量,来暂存应答状态。
IIC_SDA=1;//释放数据总线,准备接收应答信号。
_nop();
IIC_SCL=1;//拉高时钟线。
_nop();
IIC_SCL = 0;//...................
ack = 1;
for(temp=255;temp>0;temp--)
{
if(IIC_SDA==0)
{
ack = 0;
break;
}
}
_nop();
return ack;//返回应答信号的状态,0表示应答,1表示非应答。
}
//-------------------------------------------------------------------
void IIC_write_byte(unsigned char Data)
{//向IIC总线写入一个字节的数据函数
unsigned char i;
for(i=0;i<8;i++)//有8位数据
{
IIC_SDA=Data&0x80;//写最高位的数据
_nop();
IIC_SCL=1; //拉高时钟线,将数写入到设备中。
_nop();
IIC_SCL=0;//拉低时钟线,允许改变数据线的状态
_nop();
Data=Data<<1;//数据左移一位,把次高位放在最高位,为写入次高位做准备
}
}
//-------------------------------------------------------------------
unsigned char IIC_read_byte()
{//从IIC总线读取一个字节的数据函数
unsigned char i;
unsigned char Data; //定义一个缓冲寄存器。
for(i=0;i<8;i++)//有8位数据
{
IIC_SCL=1;//拉高时钟线,为读取下一位数据做准备。
_nop();
Data=Data<<1;//将缓冲字节的数据左移一位,准备读取数据。
_nop();
if(IIC_SDA)//如果数据线为高平电平。
Data=Data|0x1;//则给缓冲字节的最低位写1。
IIC_SCL=0;//拉低时钟线,为读取下一位数据做准备。
_nop();
}
return Data;//返回读取的一个字节数据。
}
//-------------------------------------------------------------------
void IIC_single_byte_write(unsigned char Daddr,unsigned char Waddr,unsigned char Data)
{//向任意地址写入一个字节数据函数
IIC_start();//产生起始信号
IIC_write_byte(Daddr);//写入设备地址(写)
if(IIC_Tack()!=0){wr_rong=1;goto iic_write_out;}//等待设备的应答
IIC_write_byte(Waddr);//写入要操作的单元地址。
if(IIC_Tack()!=0){wr_rong=1;goto iic_write_out;}//等待设备的应答
IIC_write_byte(Data);//写入数据。
if(IIC_Tack()!=0){wr_rong=1;goto iic_write_out;}//等待设备的应答
wr_rong = 0;
iic_write_out:
IIC_stop();//产生停止符号。
}
//-------------------------------------------------------------------
unsigned char IIC_single_byte_read(unsigned char Daddr,unsigned char Waddr)
{//从任意地址读取一个字节数据函数
unsigned char Data;//定义一个缓冲寄存器。
IIC_start();//产生起始信号
IIC_write_byte(Daddr);//写入设备地址(写)
if(IIC_Tack()!=0){wr_rong=1;goto iic_read_out;}//等待设备的应答
_pa2 = 1;
IIC_write_byte(Waddr);//写入要操作的单元地址。
if(IIC_Tack()!=0){wr_rong=1;goto iic_read_out;}//等待设备的应答
IIC_start();//产生起始信号
IIC_write_byte(Daddr+1);//写入设备地址(读)。
if(IIC_Tack()!=0){wr_rong=1;goto iic_read_out;}//等待设备的应答
Data=IIC_read_byte();//写入数据。
IIC_SDA = 1; //stop read
IIC_stop();//产生停止符号。
wr_rong = 0;
//-------------------返回读取的数据--------------------
return Data;//返回读取的一个字节数据。
iic_read_out:
IIC_stop();//产生停止符号。
return 0;
}
|