/* 2002-07-08...07-9 */ /* 93C46 测试程序 */ /* WRITE BY 机灵小老鼠 */ #include #include #include #include #define uchar unsigned char #define uint unsigned int #define HIGH 1 /*高电平标识 */ #define LOW 0 /*低电平标识 */ #define TRUE 1 /*成功标识 */ #define FALSE 0 /*失败标识 */ /*定义指令头的低8位 文档中的指令凡指明为'X'的位被设为0 */ #define CMD_READ 0x80 /*读取一个字的内容 */ #define CMD_EWEN 0x30 /*擦除和写的允许 */ #define CMD_ERASE 0xc0 /*擦除一个字的内容 */ #define CMD_WRITE 0x40 /*写入一个字的数据 */ #define CMD_ERAL 0x20 /*芯片的擦除 */ #define CMD_WRAL 0x10 /*复制所有的字为统一内容*/ #define CMD_EWDS 0x00 /*擦除和写的禁止 */ /* 按照实际的连接更改此引脚的定义 */ sbit HD_CS =P1^0; /*片选信号线 */ sbit HD_SK =P1^1; /*时钟线 */ sbit HD_DI =P1^2; /*数据输入线 */ sbit HD_DO =P1^3; /*数据输出线 */ /******************************************************************** 93c46 的底层子程序部分(限于内部调用) ********************************************************************/ /* 指令起始头,用于任何一个指令的开始 */ void start_of_ins(void) { HD_CS =LOW; HD_SK =LOW; HD_DI =LOW; HD_DO =HIGH; HD_CS =HIGH; HD_SK =HIGH; } /* 输入一个字节(9位)的指令 */ void send_ins_byte(uchar ins) { uchar i; HD_SK = LOW; HD_DI = HIGH; /* 时钟为低时写数据SB=1 */ HD_SK = HIGH; for( i =0; i <8; i ++) { ins = ins <<1; /* 移位操作会将数据交给C */ HD_SK = LOW; HD_DI = CY; /* 时钟为低时写数据 */ HD_SK = HIGH; } } /* 输入一个字节(8位)的数据 */ void send_data_byte(uchar da) { uchar i; for( i =0; i <8; i ++) { da = da <<1; /* 移位操作会将数据交给C */ HD_SK = LOW; HD_DI = CY; /* 时钟为低时写数据 */ HD_SK = HIGH; } } /* erase/write 指令的结束判断 */ /* 返回: TRUE/FALSE */ bit end_of_erase_write(void) { int delay_tmp =1000; HD_SK =LOW; HD_DI =LOW; HD_SK =HIGH; HD_SK =LOW; HD_CS =LOW; HD_SK =HIGH; HD_SK =LOW; HD_CS =HIGH; do{ if(delay_tmp-- <0) return FALSE; HD_SK =HIGH; HD_SK =LOW; }while(!HD_DO); return TRUE; } /* erase/write disable 指令的结束*/ void end_of_erase_write_disable(void) { HD_SK =LOW; HD_CS =LOW; HD_DI =LOW; HD_DO =HIGH; } /******************************************************************** 93c46 的底层功能程序部分(限于接口程序的内部调用) ********************************************************************/ /* [READ]读取一个字(2字节) */ uint recv_data_word(void) { uchar i; uint da=0; HD_SK =LOW; HD_DI =LOW; for( i =0; i <16; i ++) { da *= 2; /* 传输的数据高位在前 */ HD_SK =HIGH; HD_SK =LOW; /* 时钟为高时读数据 */ if (HD_DO == HIGH) da++; } HD_CS =LOW; HD_SK =HIGH; HD_CS =HIGH; HD_SK =LOW; return da; } /* [EWEN]的实现 */ void erase_write_enable(void) { start_of_ins(); send_ins_byte(CMD_EWEN); } /* ERASE 擦除一个指定地址的数据字 */ /* 返回: TRUE/FALSE */ bit erase_word(uchar add) { start_of_ins(); send_ins_byte((add & 0x3f) | CMD_ERASE); return( end_of_erase_write() ); } /* [WRITE]写一个指定地址的数据字 */ /* 返回: TRUE/FALSE */ bit write_word_step(uchar add,uint wd) { start_of_ins(); send_ins_byte((add & 0x3f) | CMD_WRITE); send_data_byte((wd >>8) & 0xff); send_data_byte(wd & 0xff); return( end_of_erase_write() ); } /* EWDS 的实现 */ void erase_write_disable(void) { start_of_ins(); send_ins_byte(CMD_EWDS); end_of_erase_write_disable(); } /* [WRAL]将芯片的所有单元写成相同 */ /* 返回: TRUE/FALSE */ bit write_all_step(uint wd) { start_of_ins(); send_ins_byte( CMD_WRAL); send_data_byte((wd >>8) & 0xff); send_data_byte(wd & 0xff); return( end_of_erase_write() ); } /* [ERAL]芯片擦除(位值都为'1') */ /* 返回: TRUE/FALSE */ bit erase_all_step(void) { start_of_ins(); send_ins_byte( CMD_ERAL); return( end_of_erase_write() ); } /******************************************************************** 用户接口子程序部分,可以被应用调用 ********************************************************************/ /* 读取一个指定地址的字的内容 */ uint f_read_word(uchar add) { start_of_ins(); send_ins_byte((add & 0x3f) | CMD_READ); return( recv_data_word() ); } /* 将一个字写入一个指定地址 */ /* 解除保护,擦除,写入,保护允许 */ bit f_write_word(uchar add,uint wd) { bit ret_bit =FALSE; erase_write_enable(); ret_bit = erase_word(add); if(ret_bit){ ret_bit = write_word_step(add,wd); if(ret_bit) erase_write_disable(); } return (ret_bit); } /* 将芯片的所有单元写成相同 */ /* 解除保护,全写,保护允许 */ /* 具有自己内部执行擦除的功能 */ bit f_write_all(uint wd) { bit ret_bit =FALSE; erase_write_enable(); ret_bit = write_all_step(wd); if(ret_bit) erase_write_disable(); return (ret_bit); } /* 芯片擦除(位值都为'1') */ /* 解除保护,全部擦除,保护允许*/ bit f_erase_all(void) { bit ret_bit =FALSE; erase_write_enable(); ret_bit = erase_all_step(); if(ret_bit) erase_write_disable(); return (ret_bit); } /******************************************************************* 简单的调用测试程序部分 *******************************************************************/ void main(void) { uchar da[16]; uchar tmp; uint kk=0; bit retb; memset(da,0,16); retb = f_erase_all(); for(tmp =0; tmp <5; tmp++){ kk =f_read_word(tmp+8); da[tmp*2] = (kk >>8) & 0xff; da[tmp*2+1] = kk & 0xff; } retb = f_write_word(8, 0x0123); retb = f_write_word(9, 0x4567); retb = f_write_word(10, 0x89ab); retb = f_write_word(11, 0xcdef); for(tmp =0; tmp <5; tmp++){ kk =f_read_word(tmp+8); da[tmp*2] = (kk >>8) & 0xff; da[tmp*2+1] = kk & 0xff; } retb = f_write_all(0x55aa); for(tmp =0; tmp <5; tmp++){ kk =f_read_word(tmp+8); da[tmp*2] = (kk >>8) & 0xff; da[tmp*2+1] = kk & 0xff; } retb = f_erase_all(); for(tmp =0; tmp <5; tmp++){ kk =f_read_word(tmp+8); da[tmp*2] = (kk >>8) & 0xff; da[tmp*2+1] = kk & 0xff; } retb = f_write_all(0x6677); for(tmp =0; tmp <5; tmp++){ kk =f_read_word(tmp+8); da[tmp*2] = (kk >>8) & 0xff; da[tmp*2+1] = kk & 0xff; } while(1); } /*************END OF FILE **********************/