为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

13、U盘、IC卡、SD卡读写、时钟芯片应用

2018-08-23 31页 doc 61KB 12阅读

用户头像

is_624976

暂无简介

举报
13、U盘、IC卡、SD卡读写、时钟芯片应用13、U盘、IC卡、SD卡读写、时钟芯片应用 【实例94】读写U盘 1(变量定义和基本操作函数 (1)变量的定义 #include #define uchar unsigned char uchar volatile xdata CH372_CMD_PORT _at_ 0x7DFF; // CH372命令端口的I/O地址 uchar volatile xdata CH372_DAT_PORT _at_ 0x7CFE; //CH372数据端口的I/O地址 uchar Usb_Length; //USB数据缓冲区中数据...
13、U盘、IC卡、SD卡读写、时钟芯片应用
13、U盘、IC卡、SD卡读写、时钟芯片应用 【实例94】读写U盘 1(变量定义和基本操作函数 (1)变量的定义 #include #define uchar unsigned char uchar volatile xdata CH372_CMD_PORT _at_ 0x7DFF; // CH372命令端口的I/O地址 uchar volatile xdata CH372_DAT_PORT _at_ 0x7CFE; //CH372数据端口的I/O地址 uchar Usb_Length; //USB数据缓冲区中数据的长度 uchar Usb_Buffer[ CH372_MAX_DATA_LEN ]; // USB数据缓冲区 #define CH372_MAX_DATA_LEN 0x40 //最大数据包的长度,内部缓冲区的长度 //命令代码 #define CMD_RESET_ALL 0x05 //执行硬件复位 #define CMD_CHECK_EXIST 0x06 //测试工作状态 #define CMD_SET_USB_ID 0x12 // 设置USB厂商VID和产品PID #define CMD_SET_USB_ADDR 0x13 //设置USB地址 #define CMD_SET_USB_MODE 0x15 //设置USB工作模式 #define CMD_SET_ENDP2 0x18 //设置USB端点0的接收器 #define CMD_SET_ENDP3 0x19 //设置USB端点0的发送器 #define CMD_SET_ENDP4 0x1A //设置USB端点1的接收器 #define CMD_SET_ENDP5 0x1B //设置USB端点1的发送器 #define CMD_SET_ENDP6 0x1C //设置USB端点2/主机端点的接收器 #define CMD_SET_ENDP7 0x1D //设置USB端点2/主机端点的发送器 //命令CMD_SET_ENDP2~CMD_SET_ENDP7输入为:工作方式,位7为1则位6为同步触发位, 否则同步触发位不变,位3~位0为事务响应方: 0000~1000-就绪ACK,1101-忽略,1110-正忙NAK,1111-错误STALL #define CMD_GET_TOGGLE 0x0A //获取OUT事务的同步状态,输入:数据1AH, 输出:同步状态 #define CMD_GET_STATUS 0x22 // 获取中断状态并取消中断请求 #define CMD_UNLOCK_USB 0x23 //释放当前USB缓冲区 #define CMD_RD_USB_DATA 0x28 //从当前USB中断的端点缓冲区读取数据块, 并 释放缓冲区 #define CMD_WR_USB_DATA3 0x29 //向USB端点0的发送缓冲区写入数据块 #define CMD_WR_USB_DATA5 0x2A //向USB端点1的发送缓冲区写入数据块 #define CMD_WR_USB_DATA7 0x2B // 向USB端点2的发送缓冲区写入数据块 //操作状态 #define CMD_RET_SUCCESS 0x51 //命令操作成功 #define CMD_RET_ABORT 0x5F //命令操作失败 (2)基本操作函数 ?函数DelayMs:在CH372读写过程中需要用到毫秒延时,该函数可以满足要求,程 序代码如下。 void DelayMs(uchar n) { uchar i; unsigned int j; for(i=0; i 500) { break; //超时返回 } } return(tmp); //返回响应信息 } 2(SD卡的上电初始化 SD卡的上电初始化程序代码如下。 //预定义变量 sbit CS=P2^0; sbit CLK= P2^3; sbit DI=P2^1; sbit DO=P2^2; #define SD_Disable() CS=1 //片选关 #define SD_Enable() CS=0 //片选开 uchar SD_read_byte (void) //读出一字节 void SD_write_byte(uchar Byte) //写入一个字节 uchar SD_write_command (uchar *cmd)//发送SD命令 uchar SD_write_sector(ulong addr,uchar *Buffer)//写单块,512字节 void SD_read_block(uchar *cmd,uchar *Buffer,uint Bytes) //读N个字节数据放在缓冲区内 uchar SD_read_sector (ulong addr,uchar *Buffer)//读单块,512字节 uchar SD_init () //sd 初始化 void delay(uint n) //延时微秒 //SD初始化 uchar SD_init ( ) { uchar Timeout = 0; uchar b; uchar idata CMD[ ] = {0x40,0x00,0x00,0x00,0x00,0x95}; //CMD0 for (i=0;i<0x0f;i++) { SD_write_byte(0xff); //延迟74个以上的时钟 } SD_Enable( ); //开片选 //发送CMD0 while(SD_write_command (CMD) !=0x01) //等于1示复位成功 { if (Timeout++ > 5) { return(1); } } //发送 CMD1 Timeout = 0; CMD[0] = 0x41; CMD[5] = 0xFF; //CMD1 while( SD_write_command (CMD) !=0) { if (Timeout++ > 100) { return(2); } } SD_Disable(); return(0); //成功 } 2(对SD卡的读写操作 写SD卡的程序代码如下。 //写单块,512字节 uchar SD_write_sector (ulong addr,uchar *Buffer)//参数:写扇区的地址,数据的指针 { uchar tmp; uint a ; uchar idata cmd[] = {0x58,0x00,0x00,0x00,0x00,0xFF}; //CMD24 addr = addr << 9; //addr = addr * 512 cmd[1] = ((addr & 0xFF000000) >>24 ); cmd[2] = ((addr & 0x00FF0000) >>16 ); cmd[3] = ((addr & 0x0000FF00) >>8 ); tmp = SD_write_command (cmd); //发送命令cmd24,写单块512字节 if (tmp != 0) { return(tmp); } for (a=0;a<100;a++) { SD_read_byte(); } SD_write_byte(0xFE); //发送读、写命令后都要发送起始令牌FEH for ( a=0;a<512;a++) { SD_write_byte(*Buffer++); } //写入CRC字节 SD_write_byte(0xFF); SD_write_byte(0xFF); while (SD_read_byte() != 0xff) { }; SD_Disable(); return(0); } 读SD卡的程序代码如下。 //读N个字节数据放在缓冲区内 void SD_read_block(uchar *cmd,uchar *Buffer,uint N_Byte)//参数:命令、缓冲区指针、长度 { uint a; if (SD_write_command (cmd) != 0) { return; } while (SD_read_byte( )!= 0xfe) { }; for (a=0;a< N_Byte;a++) { *Buffer++ = SD_read_byte(); } //取走CRC字节 SD_read_byte(); SD_read_byte(); SD_Disable(); return; } //读一个扇区数据 uchar SD_read_sector (ulong addr,uchar *Buffer)//参数:扇区地址,缓冲区指针 { uchar idata cmd[] = {0x51,0x00,0x00,0x00,0x00,0xFF}; //读单块 addr = addr << 9; //addr = addr * 512 cmd[1] = ((addr & 0xFF000000) >>24 ); cmd[2] = ((addr & 0x00FF0000) >>16 ); cmd[3] = ((addr & 0x0000FF00) >>8 ); SD_read_block(cmd,Buffer,512); return(0); } 【实例97】高精度实时时钟芯片的应用 1(变量及SD2300A的相关定义 //变量定义 #define true 1 #define false 0 //SD2300A相关定义 sbit SDA=P2^0; sbit SCL=P2^1; uchar data1,data2,data3,data4; uchar date[7]; //日期数组 //date[6]=year,date[5]=month,date[4]=day,date[3]=week, // date[2]=hour,date[1]=minute,date[0]=second //SD2300A函数名 void I2C_delay(void); bit I2C_Start(void); void I2C_Stop(void); void I2C_Ack(void); void I2C_NoAck(void); bit I2C_Read_ACK(void); void I2C_Send_Byte(uchar demand); uchar I2C_Receive_Byte(void); void I2C_Read_Date(void); void Delay(uint nn); void I2C_Write_Date(void); 2(SD2300A的相关子程序 2(1)函数_delay的程序代码如下。 IC 2void Delay(void) IC { nop();nop();nop();nop(); } 2(2)函数_Start IC bit I2C_Start(void) { SDA=1; SCL=1; I2C_delay(); if(!SDA) return false;//SDA线为低电平则总线忙,退出 SDA=0; I2C_delay(); while(SDA) return false;//SDA线为高电平则总线出错,退出 SCL=0; I2C_delay(); 2 return true;//开启总线 IC } 2(3)函数_Stop IC void I2C_Stop(void) { SDA=0; SCL=0; I2C_delay(); SCL=1; I2C_delay(); SDA=1; } 2(4)函数_Ack IC void I2C_Ack(void) { SDA=0; SCL=0; I2C_delay(); SCL=1; I2C_delay(); SCL=0; } 2(5)函数_NoAck IC void I2CNoAck(void) { SDA=1; SCL=0; I2C_delay(); SCL=1; I2C_delay(); SCL=0; } 2_Read_Ack (6)函数IC bit I2C_Read_ACK(void) //返回true=1时有ACK, true=0时无ACK { uchar errtime=255; SCL=0; SDA=1; I2C_delay(); SCL=1; I2C_delay(); while(SDA) { errtime--; if(!errtime) SCL=0; return false; } SCL=0; return true; } 22(7)函数_Send_Byte和_Receive_Byte ICIC//向SD2300A发送一个字节 void I2C_Send_Byte(uchar demand) //数据从高位到低位发送 { uchar i=8; while(i--) { SCL=0; nop(); SDA=(bit)(demand&0x80); demand<<=1; I2C_delay(); SCL=1; I2C_delay(); } SCL=0; } //从SD2300A读入一字节 uchar I2C_Receive_Byte(void) //数据从高位到低位 { uchar i=8; uchar ddata=0; SDA=1; while(i--) { ddata<<=1; //数据从高位开始读取 SCL=0; I2C_delay(); SCL=1; I2C_delay(); //从高位开始 ddata|=SDA;ddata<<=1 if(SDA) { ddata|=0x01; } } SCL=0; return ddata; } 2(8)函数_Read_Date IC void I2C_Read_Date(void) { uchar n; I2C_Start(); I2C_Stop(); I2C_Start(); I2C_Send_Byte(0x64); //从年开始读取数据 I2C_Read_ACK(); I2C_Send_Byte(0x00); I2C_Read_ACK(); I2C_Start(); I2C_Send_Byte(0x65); I2C_Read_ACK(); for(n=0;n<7;n++) { date[n]= I2C_Receive_Byte(); if (n!=6) //最后一个数据不应答 { I2C_Ack(); } } I2CNoAck(); I2C_Stop(); } 2(9)函数_Write_Date IC void I2C_Write_Date(void) { I2C_Start(); I2C_Stop(); I2C_Start(); I2C_Send_Byte(0x64); I2C_Read_ACK(); I2C_Send_Byte(0xf0);//设置写起始地址 I2C_Read_ACK(); I2C_Send_Byte(0x20);//二十四小时制 I2C_Read_ACK(); I2C_Send_Byte(0x01);//秒 I2C_Read_ACK(); I2C_Send_Byte(0x01);//分 I2C_Read_ACK(); I2C_Send_Byte(0x08);//时 I2C_Read_ACK(); I2C_Send_Byte(0x01);//日 I2C_Read_ACK(); I2C_Send_Byte(0x01);//周 I2C_Read_ACK(); I2C_Send_Byte(0x07);//月 I2C_Read_ACK(); I2C_Send_Byte(0x04);//年 I2C_Read_ACK(); I2C_Send_Byte(0x00);//清零数字调整寄存器 I2C_Read_ACK(); I2C_Stop(); } (10)函数Delay void Delay(uint nn) { while(nn--); } 3(主程序 main() { P2=0xFF; I2C_Write_Date(); while(1) { I2C_Read_Date(); Delay(250); Delay(250); } }
/
本文档为【13、U盘、IC卡、SD卡读写、时钟芯片应用】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索