⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 GPS logger and emulator which includes SPI, SD and UART drivers and implements for C51 MCUs
💻 C
字号:
#include "REG51ED2.h"

typedef unsigned char byte;
typedef unsigned int  word;
typedef unsigned long dword;
byte  *HexTab="0123456789ABCDEF";
bit   Debug=0;

byte  CursorLCD=0;
byte  OutBufferSER[64];
byte  OutLenSER=0;
byte  OutIdxSER=0;
bit   SERRxCmplt=0;
bit   SendingSER=0;
byte  InBufferSER[64];
byte  InLenSER=0;
byte  InIdxSER=0;

byte  InSPI;
int   InIdxSPI=0;
bit   TxCmpltSPI=0;
byte  SectBuf[513];
int   data SectIdx=0;
dword data SectNo=629;
byte  data Bank[6];
byte  xdata EEPBank[6] _at_ 0;
/************************************************************************/
void Delay1(void)
{
  int i;
  for(i=0;i<100l;i++);
}
/************************************************************************/
void Delay2(void)
{
  int i;
  for(i=0;i<20000l;i++);
}
/************************************************************************/
void EEPWriteWord(byte Addr,byte *Data)
{
  while(EECON & 1);
  EA=0;
  EECON=2;
  while(EECON & 1);
  EEPBank[Addr  ]=Data[0];
  while(EECON & 1);
  EEPBank[Addr+1]=Data[1];
  while(EECON & 1);
  EECON=0;
  EA=1;
}
/************************************************************************/
void EEPReadWord(byte Addr,byte *Data)
{
  while(EECON & 1);
  EA=0;
  EECON=2;
  Data[0]=EEPBank[Addr  ];
  Data[1]=EEPBank[Addr+1];
  EECON=0;
  EA=1;
}
/************************************************************************/
void WriteInsCharLCD(byte a)
{
  P2=(a>>4)&0xf;
  P2^=0x20;
  P2^=0x20;
  Delay1();
  P2=a&0xf;
  P2^=0x20;
  P2^=0x20;
  Delay1();
}
/************************************************************************/
void ResetLCD(void)
{
// P2 3..0 = DB7..4
// P2 4    = RS
// P2 5    = E
  WriteInsCharLCD(0x33);
  WriteInsCharLCD(0x32);

  WriteInsCharLCD(0x2c); // 4 bits, 2 line, 0 font
  WriteInsCharLCD(0x08); // Display off

  WriteInsCharLCD(0x01); // Display clear
  WriteInsCharLCD(0x06); // Entry Mode Set

  WriteInsCharLCD(0x80); // AddressSet
  WriteInsCharLCD(0x0c); // Display on
  CursorLCD=0;
}
/************************************************************************/
void WriteDataCharLCD(byte a)
{
  P2=(a>>4)|0x10;
  P2^=0x20;
  P2^=0x20;
  Delay1();
  P2=(a&0xf)|0x10;
  P2^=0x20;
  P2^=0x20;
  Delay1();
  CursorLCD++;
  CursorLCD&=0x1f;
  if(CursorLCD==16)
    WriteInsCharLCD(0xc0);
}
/************************************************************************/
void ClsLCD(void)
{
  CursorLCD=0;
  P2=0x0;
  P2^=0x20;
  P2^=0x20;
  Delay1();
  P2=1;
  P2^=0x20;
  P2^=0x20;
  Delay1();
}
/************************************************************************/
void WriteStrLCD(byte *s)
{
  byte i=0;
  ClsLCD();
  while(*s)
  {
    i++;
    if(i>33) return;
    WriteDataCharLCD(*s);
    s++;
  }
}
/************************************************************************/
void WriteByteLCD(byte i)
{
  WriteDataCharLCD(HexTab[(i>> 4)&0xf]);
  WriteDataCharLCD(HexTab[(i    )&0xf]);
}
/************************************************************************/
void WriteHexLCD(word i)
{
  WriteByteLCD((i>>8) & 0xff);
  WriteByteLCD((i)    & 0xff);
}
/************************************************************************/
byte ReadKBD(void)
{
  return ~P1 & 0x1f;
}
/************************************************************************/
void InterruptSER(void) interrupt 4
{
  if(RI==1)  // Is Serial Receive Interrupt
  {
    InBufferSER[0]=SBUF;
    SERRxCmplt=1;
//    SBUF=InBufferSER[0];
/*
    if(SBUF=='@')
      SER_Idx=0;
    if(SER_Idx==SER_BUF_LEN)
      SER_Idx=0;
    SER_Buf[SER_Idx]=SBUF;
    SER_Idx++;
*/
    RI=0;
  }
  if(TI==1)
  {
    TI=0;
    if(OutLenSER)
      if(OutIdxSER!=OutLenSER)
        SBUF=OutBufferSER[OutIdxSER++];
      else
        SendingSER=0;
    else
      SendingSER=0;
  }
}
/************************************************************************/
void InitSER(void)
{
  // 9600 8n1
  PCON=0x80;
  SCON=0x50;
  BDRCON=0x1e;
  BRL=192;
  IEN0=0x90;
  IEN1=0x4;
  IPH0=0x10;
  IPH1=0;
  IPL0=0;
  IPL1=0;
}
/************************************************************************/
void WriteCharSER(byte a)
{
  if((!OutLenSER) || (OutLenSER==OutIdxSER))
  {
    if(SendingSER)
    {
      OutBufferSER[0]=a;
      OutLenSER=1;
      OutIdxSER=0;
    }
    else
    {
      TI=0;
      SBUF=a;
      OutLenSER=0;
      OutIdxSER=0;
      SendingSER=1;
    }
  }
  else
  {
    OutBufferSER[OutLenSER]=a;
    if(OutLenSER<63)
      OutLenSER++;
    SendingSER=1;
  }
}
/************************************************************************/
void WriteStrSER(byte *s)
{
  while(*s)
  {
    WriteCharSER(*s);
    s++;
  }
}
/************************************************************************/
byte ReadCharSER(void)
{
  while(!SERRxCmplt);
  SERRxCmplt=0;
  return InBufferSER[0];
}
/************************************************************************/
void AlignCharSER(byte c)
{
  SERRxCmplt=0;
  while(ReadCharSER()!=c);
  SERRxCmplt=1;             // ungetch the c
}
/************************************************************************/
void InitSPI(void)
{
  SPCON|=0x10;				/* Master mode */
  SPCON|=0x82;				/* Fclk Periph/128 */
  SPCON|=0x20;				/* P1.1 is available as standard I/O pin */
  SPCON&=~0x08;				/* CPOL=0; transmit mode example */
  SPCON&=~0x04;				/* CPHA=1; transmit mode example */
  SPCON|=0x40;				/* run spi */
  IEN1 |= 0x04;             /* enable spi interrupt */
  EA=1;
}
/************************************************************************/
void InterruptSPI(void) interrupt 9 /* interrupt address is 0x004B */
{
  switch(SPSTA)             /* read and clear spi status register */
  {
    case 0x80:
      InSPI=SPDAT;    		/* read receive data */
//      if(InIdxSPI<512)
//        InIdxSPI++;
      TxCmpltSPI=1;         /* set software flag */
    break;
    case 0x10:              /* put here for mode fault tasking */
    case 0x40:              /* put here for overrun tasking */
    break;
  }
}
/************************************************************************/
byte SPI(byte b)
{
  SPDAT=b;              /* send an example data */
  while(!TxCmpltSPI);	/* wait end of transmition */
  TxCmpltSPI = 0;		/* clear software transfert flag */
  return InSPI;
}
/************************************************************************/
byte MMCCmd(byte cmd,dword arg)
{
  byte r,retry=0;
  SPI(cmd|0x40);
  SPI((arg>>24)&0xff);
  SPI((arg>>16)&0xff);
  SPI((arg>> 8)&0xff);
  SPI((arg    )&0xff);
  SPI(0x95); 				// only for MMC_GO_IDLE_STATE
  while((r=SPI(0xff))==0xff)// wait for response
    if(retry++>64) break;
  return r;
}
/************************************************************************/
byte MMCInit(void)
{
  byte i,r,retry=0;

  TxCmpltSPI=0;
  do
  {
    for(i=0;i<10;i++)  SPI(0xFF);
    r=MMCCmd(0,0);	 		// resetting card, go to SPI mode
    retry++;
    if(retry>10) return 0xff;
  }while(r!=0x01);
  retry=0;
  do
  {
    r=MMCCmd(1,0); 			// SEND_OP_COND (Activates the card抯 initialization process)
    retry++;
    if(retry>100) return 0xff;
  }while(r);
  r=MMCCmd(59,0);			// Turns the CRC option off
  r=MMCCmd(16,512);			// set block length to 512 bytes
  return 0;
}
/************************************************************************/
byte MMCRead(dword sect,byte *buf)
{
  byte r;
  word i;
  r=MMCCmd(17,sect<<9);		// MMC_READ_SINGLE_BLOCK
  if(r) return r;
  while(SPI(0xff)!=0xfe);	// MMC_STARTBLOCK_READ
  for(i=0;i<0x200;i++)
    *buf++=SPI(0xff);
  SPI(0xff);				// read 16-bit CRC
  SPI(0xff);
  return 0;
}
/************************************************************************/
byte MMCWrite(dword sect,byte *buf)
{
  byte r;
  word i;
  r=MMCCmd(24,sect<<9);		// MMC_WRITE_SINGLE_BLOCK
  if(r) return r;
  SPI(0xff);				// send dummy
  SPI(0xfe);				// MMC_STARTBLOCK_WRITE
  for(i=0;i<0x200;i++)
    SPI(*buf++);
  SPI(0xff); 				// 16 bits dummy CRC
  SPI(0xff);

  r=SPI(0xff);				// read data response token
  if((r&0x1f)!=0x5 )
  	return r;
  while(!SPI(0xff));		// wait until card not busy
  return 0;
}
/************************************************************************/
void MMCWriteByte(byte c)
{
  SectBuf[SectIdx]=c;
  SectIdx++;
  SectBuf[SectIdx]=0;
  if((c==13) || (SectIdx==512))
  {
    MMCWrite(SectNo,SectBuf);
    if(SectIdx==512)
    {
      SectNo++;
      SectIdx=0;
    }
    EEPWriteWord(0,(byte *)(&SectNo));
    EEPWriteWord(2,(byte *)(&SectNo)+2);
    EEPWriteWord(4,(byte *)(&SectIdx));
    WriteCharSER('>');
    ClsLCD();
    WriteDataCharLCD('<');
    WriteHexLCD((SectNo>>16) & 0xffff);
    WriteHexLCD((SectNo) & 0xffff);
    WriteDataCharLCD(':');
    WriteHexLCD(SectIdx);
    WriteDataCharLCD('>');
  }
}
/************************************************************************/
byte MMCReadByte(void)
{
  if(SectIdx==512)
  {
    MMCRead(SectNo,SectBuf);
    SectNo++;
    SectIdx=0;
  }
  SectIdx++;
  return SectBuf[SectIdx-1];
}
/************************************************************************/
#include "GPSData.h"
/************************************************************************/
void main(void)
{
  int i;
  byte c,j;

Restart:
  ResetLCD();
  WriteStrLCD(" Begin ");
  Delay2();
  InitSER();
  InitSPI();
  if(P3 & 0x4)
  {
    if((i=MMCInit()))
    {
      ClsLCD();
      WriteHexLCD(i);
      WriteStrLCD("MMC Error! A Key To Restart");
      for(;;)
        if(ReadKBD())
          goto Restart;
    }
    ClsLCD();
    WriteStrLCD("   SiNA Micro   SD Analyzer 1.0");
    Delay2();

    if(ReadKBD())
    {
      WriteStrLCD(" Data Scratch?  1.Yes      2.No ");
      while(ReadKBD());
      for(;;)
        if(ReadKBD()!=0)
          if(ReadKBD()==1)
          {
            // write in the eeprom the 629,0
            SectNo=629;
            SectIdx=0;
            EEPWriteWord(0,(byte *)(&SectNo));
            EEPWriteWord(2,(byte *)(&SectNo)+2);
            EEPWriteWord(4,(byte *)(&SectIdx));
            WriteStrLCD("     Car BlackBox 1.0");
            break;
          }
          else
            break;
    }
    // read the sectno, sect idx from eeprom
    ClsLCD();
    while(EECON & 1);

    EEPReadWord(0,(byte *)(&SectNo));
    EEPReadWord(2,(byte *)(&SectNo)+2);
    EEPReadWord(4,(byte *)(&SectIdx));
    MMCRead(SectNo,SectBuf);
    WriteHexLCD((SectNo>>16) & 0xffff);
    WriteHexLCD((SectNo) & 0xffff);
    WriteDataCharLCD(':');
    WriteHexLCD(SectIdx);

    for(;;)
    {
      AlignCharSER('@');
      ClsLCD();
      for(i=0;i<55;i++)
      {
        MMCWriteByte(c=ReadCharSER());
        if(i>0 && i<33)
          WriteDataCharLCD(c);
      }
      MMCWriteByte(10);
      MMCWriteByte(13);
    }
    // 3. Allocate and add a new sector to a file
// Now temporilly writes on a preallocated file.
  }
  else
//@060818132304N3541145E05125230G007+01179E0000N0000U0000
  {
    WriteStrLCD("   GPS Emulator 1.0");
    Delay2();

    WriteStrLCD("Which source?   1.Internal 2.MMC");
    for(j=0;!j;)
      j=ReadKBD();
    if(j<2)
    {
      WriteStrLCD("GPS Emulator 1.0 Internal Source");
      Delay2();
      for(;;)
      {
        for(i=0;i<999;i++)
        {
          WriteStrSER(GPSData[i]);
          WriteCharSER(10);
          WriteCharSER(13);
          WriteStrLCD(GPSData[i]+2);
          Delay2();
        }
        for(i=998;i>=0;i--)
        {
          WriteStrSER(GPSData[i]);
          WriteCharSER(10);
          WriteCharSER(13);
          WriteStrLCD(GPSData[i]+2);
          Delay2();
        }
      }
    }
    else
    {
      WriteStrLCD("GPS Emulator 1.0      MMC Source");
      Delay2();
      if((i=MMCInit()))
      {
        ClsLCD();
        WriteHexLCD(i);
        WriteStrLCD("MMC Error! A Key To Restart");
        for(;;)
          if(ReadKBD())
            goto Restart;
      }
    // 1. Check the file system to find first file name
    // 2. Get the first sector of the file
      for(;;)
      {
        for(i=0;i<57;i++)
        {
          if(!i)
            ClsLCD();
          WriteCharSER(c=MMCReadByte());
          if(i<32)
            WriteDataCharLCD(c);
        }
        Delay2();
    // 3. Get the next sector
    // Now temporarilly we read from a preallocated file.
      }
    }
  }
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -