STM32F103RC驱动CH375B模块读写优盘扇区数据

发布者:星尘散落最新更新时间:2019-10-16 来源: eefocus关键字:STM32F103R  C驱动CH375B  读写优盘扇区数据 手机看文章 扫描二维码
随时随地手机看文章

之前做毕设买了CH375B模块,一直没好好用过。现在想把这个模块用起来。程序参考的振南的51例程《U盘扇区读写[IO方式]》 和正点原子的例程模板,只要把最底层的扇区读写测试通过,znFAT文件系统就可以用了。程序用的并口通信控制。先说端口配置:8位数据端口用的GPIOC的低8位,写选通WR、读选通RD、片选 CS、命令口和数据口地址选择A0和中断INT用的GPIOB端口。端口定义如下:


#define  GPIO_CH375_Data    GPIOC     //数据端口

#define  DATA_MODE_IN           GPIO_CH375_Data->CRL=0x44444444;   //  Floating IN

#define  DATA_MODE_OUT          GPIO_CH375_Data->CRL=0x33333333;   //  PP_OUT  50MHZ

 

#define  GPIO_CH375_CTL         GPIOB   //CH375控制端口

#define  WR                 PBout(11)

#define  RD                 PBout(10)

#define  CS                 PBout(9)

#define  A0                 PBout(8)

#define  INT                PBin(12)

          端口初始化代码如下:


 

void CH375_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE); //

 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |GPIO_Pin_11  ;  

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOB, &GPIO_InitStructure);  //

 

   

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;      //   INT中断

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;// GPIO_Mode_IPU;

  GPIO_Init(GPIOB, &GPIO_InitStructure);

 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 |GPIO_Pin_3|

GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7  ; //GPIOC数据端口

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOC, &GPIO_InitStructure);  //

}

//写命令

void CH375_WR_CMD( u8 cmd )

{

   u16 TempData=0;

   DATA_MODE_OUT;  //设置成数据输出

   TempData=GPIO_ReadOutputData(GPIO_CH375_Data);  //读取数据口数据,保护高8位

   TempData &= 0xFF00;     //低8位清0,保留高8位状态

   TempData |= (u16)cmd;   //写命令

 

delay_us(10);    //延时

CS=0;           //打开片选

// delay_us(10);

A0=1;           //命令模式

// delay_us(10);

GPIO_Write(GPIO_CH375_Data, TempData); //向CH375写命令码

//delay_us(10);

WR=0;           //打开写使能

delay_us(10);   //

WR=1;           //关闭写使能

//delay_us(10);

CS=1;           //关闭片选

// delay_us(10);

A0=1;           //恢复A0为高电平

delay_us(200);  //延时

}

//写数据

void CH375_WR_DAT( u8 dat )

{

   u16 TempData=0;

   DATA_MODE_OUT;   //数据端口设置成输出,发送数据给CH375

   TempData=GPIO_ReadOutputData(GPIO_CH375_Data);//读数据端口数据,保护高8位

   TempData &= 0xFF00;  //低8位清0

   TempData |= (u16)dat;  //写数据

 

delay_us(10);    //

CS=0;            //

//delay_us(10);

A0=0;            //

//delay_us(10);

GPIO_Write(GPIO_CH375_Data, TempData); //

//delay_us(10);

WR=0;            //

delay_us(10);

WR=1;            //

// delay_us(10);

CS=1;            //

//delay_us(10); 

A0=1;            //

delay_us(200);   //

}

//读取数据

u8  CH375_RD_DAT( void )

{

   u8 PortData;   

   DATA_MODE_IN;  //

 

delay_us(10);   //

CS=0;           //

// delay_us(10);

A0=0;           //

//delay_us(10);

RD=0;           //

// delay_us(10);

PortData = (u8)( GPIO_ReadInputData(GPIO_CH375_Data) );  //

delay_us(10);

RD=1;           //

//delay_us(10);

CS=1;           //

//delay_us(10);

A0=1;           //

//delay_us(10);

   return PortData; //

}

//等待中断

u8  WaitInterrupt( void )

{   

delay_us(10);

INT=1;      //IO口作输入先置高

while(INT);   //等待中断,低电平有效

delay_us(10);

    CH375_WR_CMD( CMD_GET_STATUS );  //产生操作完成中断,获取中断状态,收到GET_STATUS命令到INT#引脚撤消中断最大延时3us

    delay_us(10);

return( CH375_RD_DAT( ) );

}

写好读写数据命令函数后就是CH375初始化和磁盘初始化:


//CH375芯片初始化,设置CH375为USB主机模式,成功返回0,失败返回1

u8  CH375Init( void )

{

u8 i;

  u8 Read_Data=0;

    CH375_WR_CMD( CMD_CHECK_EXIST );  //测试工作状态  

CH375_WR_DAT( 0x55 );  // 测试数据

    Read_Data = CH375_RD_DAT( );  // 返回的数据应是测试数据取反,如发送0x55,返回0xAA

   if ( Read_Data != 0xaa ) //CH375出错

   {  

     for ( i = 100; i != 0; i -- )

     {  

    CH375_WR_CMD( CMD_RESET_ALL );  

delay_ms(50); //RESET_ALL命令的执行时间最大为40ms

        CH375_WR_CMD( CMD_CHECK_EXIST );  // 测试工作状态

        CH375_WR_DAT( 0x55 );           // 测试数据

        Read_Data = CH375_RD_DAT( );  

        if ( Read_Data == 0xaa )    //读取到的数据是输入数据按位取反

           break;

      }      

    }

 

     CH375_WR_CMD( CMD_SET_USB_MODE );  // 设置USB工作模式

delay_us(30);//设置USB工作模式为等待20us

     CH375_WR_DAT( 6 );  //模式代码,自动检测USB设备连接

     for ( i = 0xff; i != 0; i -- )  // 等待操作成功,通常要等待10uS-20uS //

     {

delay_us(20);

       if ( CH375_RD_DAT( ) == CMD_RET_SUCCESS )   break;  //操作成功,退出循环

     }

     if ( i != 0 ) return( 0 );  // 操作成功,返回0

     else return( 1 );  // CH375初始化出错,如芯片型号出错或处于串口方式或不支持,返回1

}

//磁盘初始化,成功返回0,失败返回1

unsigned char CH375_InitDisk(void)

 unsigned char status,i,j=0;

//delay_us(100);

 status=WaitInterrupt();

delay_us(100);

 if(status==USB_INT_DISCONNECT) return 1;  //USB设备断开 

 

 while(1)

 {

  CH375_WR_CMD(CMD_DISK_INIT);  //初始化USB存储器

delay_us(100);

  status=WaitInterrupt();        //等待中断并获取中断状态

delay_us(100);

  if(status==USB_INT_SUCCESS) 

   break;

 }

 

 while(1) //以下代码均源自于沁恒的官方优盘初始化函数,借用它可提高对优盘的兼容性

 {   

  j++;

  CH375_WR_CMD(CMD_DISK_SIZE);  //获取优盘容量

delay_us(100);

  status=WaitInterrupt();       //等待中断并获取中断状态

delay_us(100);

  if(status==USB_INT_SUCCESS) 

   break;

  else 

  {

   //Delay(1000);

delay_us(100);

   CH375_WR_CMD(CMD_DISK_R_SENSE); //主机方式:检查USB存储器错误

delay_us(100);

   status=WaitInterrupt();         //等待中断并获取中断状态

delay_us(100);

   if(status==USB_INT_SUCCESS)            

continue;                  //初始化成功跳出while(1)

   else 

    return 1;          //初始化失败,返回1

  }

  if(j==5) 

   return 1;      //初始化失败,返回1

 }

 

 for(i=0;i!=5;i++)

 {

//delay_us(100);

  CH375_WR_CMD( CMD_DISK_READY );     //检查USB存储设备的错误

delay_us(100);

  status=WaitInterrupt();             //等待中断并获取中断状态

delay_us(100);

  if(status==USB_INT_SUCCESS) 

   return 0;                          //优盘已经成功初始化,返回0

 }

 return 1;     //优盘初始化失败,返回1

}

后面就是main函数了,测试扇区读写功能:


#define ADDR 100//6600000//100 //要操作的优盘物理扇区地址 用winhex打开物理磁盘可查看扇区地址数据 

 

u8 flag1=0;

u8 Write_pbuf[512];   //发送数据缓冲区

u8 Read_pbuf[2048];   //接收数据缓冲区

u8 status=0xff; //初始化状态标志

 

 

//注意:单片机要先上电,再插入优盘

 int main(void)

 {

u16 i=0;  

delay_init();     //延时函数初始化   

LED_Init();

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

uart_init(9600); //串口初始化波特率9600

printf("串口设置完毕rn");

delay_ms(100); //内部电源上电的复位时间最大为40ms,这里延时防止出现CH375初始化失败

CH375_GPIO_Init(); //

CH375_WR_CMD(CMD_GET_IC_VER);  // 获取芯片及固件版本

status=CH375_RD_DAT();  //  

printf("芯片版本为:%#xrn",status);

status=CH375Init(); //初始化CH375芯片,成功返回0,失败返回1

printf("CH375芯片初始化值:%#xrn",status);

CH375_WR_CMD(CMD_DISK_MAX_LUN);  //获取USB存储设备的最大逻辑单元号

status=CH375_RD_DAT();  // 最大逻辑单元号

printf("USB存储设备的最大逻辑单元号为:%#xrn",status);

//status=InitDisk(); //初始化优盘,成功返回0,失败返回1

//注意:单片机要先上电,再插入优盘

status=CH375_InitDisk(); //上电后再插入优盘 金士顿8G优盘 东莞16G 3.0优盘测试通过

printf("U盘初始化值:%#xrn",status);

status=Get_CH375DiskSize();//打印磁盘容量,单位MByte

for(i=0;i<512;i++)

Write_pbuf[i]=i;//0x55;//    //向数据缓冲区中写入0-255 0-255 共512个字节

printf("向缓冲区中装入完毕rn");

//CH375WriteSector(ADDR,Write_pbuf);//将数据缓冲区中的512个字节数据写入优盘的第ADDR个扇区

CH375_WriteDisk(Write_pbuf,ADDR,4); //连续写多个扇区

printf("写U盘扇区完毕rn");

 

for(i=0;i<2048;i++) //清空接收数据缓冲区

{

Read_pbuf[i]=0;

}

printf("清空接收缓冲区完毕rn");

//CH375ReadSector(ADDR+1,Read_pbuf);//从优盘的第ADDR个扇区中读取512个字节数据到数据缓冲区

CH375_ReadDisk(Read_pbuf,ADDR,4);  //连续读取多个扇区数据

//查看读取到的几个扇区数据,只取一小部分

for(i=0;i<10;i++)

{

printf("读取到的扇区数据为:i=%d   Read_pbuf[i]=%#xrn",i,Read_pbuf[i]);

}

for(i=520;i<530;i++)

{

printf("读取到的扇区数据为:i=%d   Read_pbuf[i]=%#xrn",i,Read_pbuf[i]);

[1] [2]
关键字:STM32F103R  C驱动CH375B  读写优盘扇区数据 引用地址:STM32F103RC驱动CH375B模块读写优盘扇区数据

上一篇:STM32单片机(3) 串口中断通信
下一篇:stm32f103+znfat+ch375+vs1003实现简单mp3播放器功能

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved