149和ch376通讯问题

2019-07-31 15:22发布

用msp430与CH376通过SPI通信来读取U盘文件,但是始终无法识别U盘,而且初始化老出错。
请哪位大大帮忙看看程序。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
1条回答
heibaiyinjiag
2019-07-31 19:56
下面是主程序。。。。
#include "in430.h"
#include "CH376INC.h"
#include "msp430x14x.h"
#include "functions.h"
#include "Boardconfig.h"
uchar buf[20];
void int_usart();
void sent_byte(unsigned char data);

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  uchar s;
  uchar i;
  BoardConfig(0xf0);
  initsys();
  initspi();
  initport();
  int_usart();
  CH376_SPI_RST_1;
  Delayms( 20 );
  CH376_SPI_RST_0;
  Delayms( 100 );
  s=mInitCH376Host();
  mStopIfError(s);
  while(1)
  {
    while ( CH376_DiskConnect()!= USB_INT_SUCCESS )                                /* 检查U盘是否连接,等待U盘插入,对于SD卡,可以由单片机直接查询SD卡座的插拔状态引脚 */
     {  
Delayms( 100 );
     }
//Delayms( 200 );                                                         
for ( i = 0; i < 100; i ++ )                                                   
{  
Delayms( 50 );
s = CH376_DiskMount( );                                                      /* 初始化磁盘并测试磁盘是否就绪 */
if ( s == USB_INT_SUCCESS )                                                 /* 准备好 */
{
                          P2OUT&=~BIT4;//成功亮D5
    break;                                          
}
else if ( s == ERR_DISK_DISCON )                                            /* 检测到断开,重新检测并计时 */
    {
        break;  
    }
if ( CH376_GetDiskStatus( ) >= DEF_DISK_MOUNTED && i >= 5 )                  /* 有的U盘总是返回未准备好,不过可以忽略,只要其建立连接MOUNTED且尝试5*50mS */
{
    break;           
}
}
if ( s == ERR_DISK_DISCON )                                                     /* 检测到断开,重新检测并计时 */
{  
continue;
}

if ( CH376_GetDiskStatus( ) < DEF_DISK_MOUNTED )                                 /* 未知USB设备,例如USB键盘、打印机等 */
{  
goto UnknownUsbDevice;
}
UnknownUsbDevice:
while ( CH376_DiskConnect( )==USB_INT_SUCCESS )                  /* 检查U盘是否连接,等待U盘拔出 */
{  
          Delayms( 100 );
}
  }
}
void int_usart()
{  
  U0CTL|=SWRST;//复位串口
  U0CTL|=CHAR; //8位数据
  U0TCTL|=SSEL1;//select SMCLK AS CLK
  //U0BR0=0Xa0;
  //U0BR1=0X01;
  //UMCTL0=0Xc0;//19200
  U0BR0 = 0x45;
  U0BR1 = 0x00;
  U0MCTL = 0x00; //115200
  ME1|=UTXE0;//使能接收和发送
  U0CTL&=~SWRST;//
  //IE1|=URXIE0;//使能接收中断
  //P3SEL|=BIT4;
  //P3SEL|=BIT5;//选择I/O口使用扩展功能
  P3SEL |= 0x30;
  P3DIR |= BIT4;
}
void sent_byte(unsigned char data)
{
  
  while((IFG1&UTXIFG0)==0);//判断发送缓冲区是否结束
  U0TXBUF=data;
}
#include "functions.h"
#include "msp430x14x.h"
#include "CH376INC.h"
void initsys(void)//system clock
{
  uchar i;
  BCSCTL1&=~XT2OFF;                        
  do
  {
  IFG1 &= ~OFIFG;                     
  for (i = 0xFF; i > 0; i--);   
  }
  while ((IFG1 & OFIFG) != 0);
  BCSCTL2|=SELM1+SELS;
}
void initspi(void)
{
  U1CTL = SWRST;                            // 8-bit SPI Master **SWRST**
  U1CTL = CHAR | SYNC | MM;         // 8-bit SPI Master **SWRST**   
  U1TCTL = SSEL1 | SSEL0 | STC;     // SMCLK, 3-pin mode, clock idle low, data valid on rising edge, UCLK delayed
  U1TCTL &= ~CKPH;//UCLK延时半个周期作为SPI时钟,时钟低电平为无效信号,上升沿锁存数据
  U1TCTL &= ~CKPL;
  U1BR0 = 0x04;                             // 0x02: UCLK/2 (4 MHz), works also with 3 and 4
  U1BR1 = 0x00;                 
  U1MCTL = 0x00;
  U1CTL &= ~SWRST;                          // clear SWRST
  IE2 &=~UTXIE1;
  IE2 &=~URXIE1;
  ME2|= USPIE1;                            // Enable USART1 SPI mode
}
void initport(void)
{
  //spi
  P5DIR|=BIT0+BIT1+BIT3;         //设置端口方向
  P5SEL|=BIT1+BIT2+BIT3;             //设置功能
  //others
  P2DIR|=0xff;
  P2DIR&=~BIT7;
  P2DIR&=~BIT1;
  P2IE|=BIT7;
  P2IES|=0x00;
  P2OUT|=BIT0+BIT2+BIT3+BIT4+BIT5+BIT6;
  _EINT();
}
uchar mInitCH376Host( void )
{  //_DINT();
uchar res;
        //CH376_SPI_SCS_1;
SPI_Write_CMD( CMD_CHECK_EXIST );                                                /* 测试单片机与CH376之间的通讯接口 */
SPI_Write_Byte( 0x55 );
res=SPI_Read_Byte( );
CH376_SPI_SCS_1;
        //Delayus(100);
        
if ( res != 0xAA )
         // P2OUT&=~BIT5;
          return( ERR_USB_UNKNOWN );/* 通讯接口不正常,可能原因有:接口连接异常,其它设备影响(片选不唯一),串口波特率,一直在复位,晶振不工作 */
SPI_Write_CMD( CMD11_SET_USB_MODE );
     // P2OUT&=~BIT4;
        /* while(1);
        {P2OUT&=~BIT5;
        Delayms(1000);
        P2OUT|=BIT5;
         Delayms(1000);}*//* 设备USB工作模式 */
        
SPI_Write_Byte( 0x06 );
//P2OUT&=~BIT4;
        Delayus( 20 );
res = SPI_Read_Byte( );
CH376_SPI_SCS_1;
#ifndef CH376_SPI_INT
#ifdef //CH376_SPI_SDO
//SPI_Write_CMD( CMD20_SET_SDO_INT );                                                /* 设置SPI的SDO引脚的中断方式 */
SPI_Write_Byte( 0x16 );
SPI_Write_Byte( 0x90 );                                                            /* SDO引脚在SCS片选无效时兼做中断请求输出 */
CH376_SPI_SCS_1;
#endif
#endif
if ( res == CMD_RET_SUCCESS )
{
    return( USB_INT_SUCCESS );
}
else
{
    return( ERR_USB_UNKNOWN );                                                      /* 设置模式错误 */
}
}
void Delayus(uint US)   
{
    uint i;
   
    US=US*5/4;  // 5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值
    for( i=0;i<US;i++);
}
void Delayms(uint MS)   
{
     uint i,j;
     
     for(i=0;i<MS;i++);
     for(j=0;j<1141;j++); // 1141是在8MHz晶振下,通过软件仿真反复实验得到的数值
}
uchar   SPI_Read_Byte()
{  
  uchar rByte;
  while((IFG2&URXIFG1)==0);
  rByte=U1RXBUF;
  return rByte;
}
void    SPI_Write_Byte(uchar wByte)
{   
  U1TXBUF=wByte;
  while((IFG2&UTXIFG1)==0);   // 等待发送完成
}
void SPI_Write_CMD( uchar mCmd )
{
#ifdef CH376_SPI_BZ
uchar i;
#endif
CH376_SPI_SCS_1;  /* 防止之前未通过xEndCH376Cmd禁止SPI片选 */
Delayus(5);
CH376_SPI_SCS_0;                                                                  /* SPI片选有效 */
SPI_Write_Byte( mCmd );                                                              /* 发出命令码 */
#ifdef CH376_SPI_BZ
    //    if
for ( i = 30; i != 0 && CH376_SPI_BZ; -- i ); /* SPI忙状态查询,等待CH376不忙,或者下面一行的延时1.5uS代替 */
#else
       // else
        //{
Delayus(5);
Delayus(5);
Delayus(5);
       // )
#endif
}
/*******************************************************************************
* 函  数  名      : CH376_Read_Var8
* 描      述      : 读CH376芯片内部的8位变量.
*******************************************************************************/
uchar CH376_Read_Var8( uchar var )
{
uchar c0;
SPI_Write_CMD( CMD11_READ_VAR8 );                                                   /* 读取指定的8位文件系统变量 */
SPI_Write_Byte( var );
c0 = SPI_Read_Byte( );
CH376_SPI_SCS_1;
return( c0 );
}
/*******************************************************************************
* 函  数  名      : CH376_Read_Block
* 描      述      : 从当前主机端点的接收缓冲区读取数据块,.
*******************************************************************************/
uchar CH376_Read_Block(uchar *buf)
{

  uchar status, len;
  SPI_Write_CMD( CMD01_RD_USB_DATA0 );
  status = len = SPI_Read_Byte( );  // 长度
  if ( len ) {
do {
*buf = SPI_Read_Byte( );
buf ++;
   } while ( -- len );
           }
  CH376_SPI_SCS_1;
  return( status );
}
/////////////////////////////////////////////
uchar CH376_DiskMount( void )
{
   return( CH376_SendCmd_WaitInt( CMD0H_DISK_MOUNT ) );/* 初始化磁盘并测试磁盘是否就绪 */
}
uchar Query376Interrupt( void )
{
#ifdef CH376_SPI_INT
return( CH376_SPI_INT ? FALSE : TRUE );                                            /* 如果连接了CH376的中断引脚则直接查询中断引脚 */
//#else
//return( CH376_SPI_SDO ? FALSE : TRUE );                                             /* 如果未连接CH376的中断引脚则查询兼做中断输出的SDO引脚状态 */
#endif
}
void mStopIfError( uchar iError )
{
if ( iError == USB_INT_SUCCESS )
    {
      P2OUT&=~BIT2;           
    }
    else
    {
      P2OUT&=~BIT3;
    }

}
uchar CH376_SendCmd_WaitInt( uchar mCmd )
{
SPI_Write_CMD( mCmd );
CH376_SPI_SCS_1;
return( Wait376Interrupt( ) );
}
#ifndef NO_DEFAULT_CH376_INT//用于禁止默认的Wait376Interrupt子程序,禁止后,应用程序必须自行定义一个同名子程序
uchar Wait376Interrupt( void )
{
#ifdef DEF_INT_TIMEOUT                /* 是否定义了超时时间 */
#if DEF_INT_TIMEOUT < 1      /* 没有定义 */
while ( Query376Interrupt() == FALSE );       /* 一直等中断 */
return( CH376_GetIntStatus() );     /* 检测到中断 */
#else                            /* 定义了超时时间 */
UINT32 i;
for ( i = 0; i < DEF_INT_TIMEOUT; i ++ )   /* 计数防止超时 */
{  
if ( Query376Interrupt( ) )
{
    return( CH376_GetIntStatus( ) );          /* 检测到中断 */
}
}
return( ERR_USB_UNKNOWN );         /* 不应该发生的情况 */
#endif
#else
UINT32 i;
for ( i = 0; i < 5000000; i ++ )     /* 计数防止超时,默认的超时时间,与单片机主频有关 */
{  
if ( Query376Interrupt( ) )
{
    return( CH376_GetIntStatus( ) );
}
        /* 在等待CH376中断的过程中,可以做些需要及时处理的其它事情 */
}
return( ERR_USB_UNKNOWN );    /* 不应该发生的情况 */
#endif
}
#endif
uchar CH376_GetIntStatus( void )
{
uchar status2;
SPI_Write_CMD( CMD01_GET_STATUS );
status2 = SPI_Read_Byte( );
CH376_SPI_SCS_1;
return( status2 );
}
uchar CH376_GetDiskStatus( void )
{
return( CH376_Read_Var8( VAR_DISK_STATUS ) );
}
uchar CH376_DiskConnect( void )
{
if ( Query376Interrupt( ) )
{
CH376_GetIntStatus( );   /* 检测到中断 */
}
return( CH376_SendCmd_WaitInt( CMD0H_DISK_CONNECT ) ); /* 检查磁盘是否连接 */
}

uchar mInitCH376Host( void )函数 中SPI_WRITE_BYTE()写入0x55 返回值res=SPI_Read_Byte( )=0X06

一周热门 更多>