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

📄 main.c

📁 Hello ! This is Atmega spi driver source. Thank you!
💻 C
📖 第 1 页 / 共 2 页
字号:
//***************************************************************************
// showstatus - show current SPI port settings
//***************************************************************************
void showstatus(char displaymode)
{
  char tmp, ix=0;
  
  if(displaymode == STATLIST) USART_Transmit(' '); // some padding

  for(;;) // loop until the return statement is executed
  {
    send_str(status[ix]);
    switch(ix++){
      case 1:   // actual frequency
        tmp = (SPCR & 0x03) | ((SPSR & 1) << 2);              
        USART_Transmit(htoa(tmp));           
        if(displaymode == STATLIST) send_str(freq[tmp]);
        break;
      case 2:   // actual SS status 
        USART_Transmit(htoa((PORT_SPI & (1<<P_SS)) >> P_SS)); 
        break;
      case 3:   // actual auto mode
        USART_Transmit(htoa(ss_auto));         
        if(displaymode == STATLIST)
        {
          if(!ss_auto) send_str(auto0);
          else if(ss_auto == 1) send_str(auto1);
          else send_str(auto2);
        }
        break;
      case 4:   // actual data order
        tmp = (SPCR & (1 << DORD)) >> DORD;                   
        USART_Transmit(htoa(tmp));   
        if((displaymode == STATLIST) && !tmp) send_str(bit0);
        if((displaymode == STATLIST) && tmp) send_str(bit1);
        break;
      case 5:   // actual mode
        USART_Transmit(htoa((SPCR & 0x0C) >> 2));
        return; // nothing more to display
    }// end switch
    if(displaymode == STATLIST) send_str(nullprompt); // next line
    else send_str(gap);                               // or some padding
  }// end for
}

//***************************************************************************
// hexsequence - fetch, check and transmit a multi-byte sequence
//***************************************************************************
void hexsequence(void)
{
  char tx_str[MAXSEQ*2]; // enough storage for ascii encoded bytes
  char rx_str[MAXSEQ];   // storage for returned characters
  char length;
  int ix;
  
  for (ix = 0;ix < MAXSEQ*2;ix++)       // get character string
  {
    if (!(ix % 2)) USART_Transmit(':'); // separator every 2nd character
    tx_str[ix] = getnextchar();
    
    if (tx_str[ix] == '\r') break;      // detect 'enter' key pressed
    if (!isxdigit(tx_str[ix])) // detect invalid characters entered
    {
      send_str(error1);        // abort entry for illegal character
      return;                  // exit immediately
    }
    if (tx_str[ix] > '9') tx_str[ix] -= 7;
                               // A-F shifted to be consecutive from 0-9
    tx_str[ix] -= 0x30;        // Remove ASCII offset
  }
  length = ix/2;  // store number of full bytes entered

  // ensure SS pin is in idle condition if auto toggle is on
  if(!ss_auto)     sspinadjust(1); // make SS pin high
  if(ss_auto == 1) sspinadjust(0); // make SS pin low
  
  // At this point, tx_str contains length*2 valid half-bytes.
  // The conversion to bytes, SPI exchange and received byte display are
  // now carried out in seperate loops to ensure the SPI transmission takes
  // place in the shortest time period.
  
  for (ix = 0;ix < length;ix++) // convert half-bytes to bytes
    tx_str[ix] = (tx_str[ix*2] << 4) | tx_str[(ix*2)+1]; // nibbles combined
 
  if(ss_auto != 2) sspinadjust(ss_auto);  // Auto toggle SS pin if mode is on

  for (ix = 0;ix < length;ix++) // transmit the sequence
    rx_str[ix] = SPI_MasterTransmit(tx_str[ix]);         // SPI byte exchange
  
  // restore SS pin to idle condition if auto toggle is on
  if(!ss_auto)     sspinadjust(1); // make SS pin high
  if(ss_auto == 1) sspinadjust(0); // make SS pin low

  for (ix = 0;ix < length;ix++) // Display the exchange
  {
    send_str(nullprompt);
    USART_Transmit( htoa((tx_str[ix] & 0xf0) >> 4) );//display upper nibble
    USART_Transmit( htoa(tx_str[ix] & 0x0F) );       //display lower nibble
    send_str(exchange);
    USART_Transmit( htoa((rx_str[ix] & 0xf0) >> 4) );//display upper nibble
    USART_Transmit( htoa(rx_str[ix] & 0x0F) );       //display lower nibble
  }
}

//***************************************************************************
// setfreq - set the SPI SCK frequency
//***************************************************************************
void setfreq(void)
{
  char tmp;
  
  tmp = getnextchar();
  tmp -= 0x30;  // Remove ASCII offset
  
  if (tmp < 8) // a valid frequency value (unsigned, so no negative values)
  {
    SPCR &= 0xFC;        // mask off current SPR bits (bit 1 & 0)
    SPCR |= tmp & 0x03;  // set new value using two lsb of selection number
    if(tmp & 0x04) SPSR |= (1 << SPI2X); // for selection 4-7 set SPI2X
    else SPSR &= ~(1 << SPI2X);          // otherwise clear SPI2X
    send_str(newstat);
    showstatus(STATLIST);
  }
  else send_str(error1); // abort entry for illegal second character
}

//***************************************************************************
// setsspin - modify the state of SS pin on SPI port
//***************************************************************************
void setsspin(void)
{
  char tmp;
  
  tmp = getnextchar();
  tmp -= 0x30;  // Remove ASCII offset
  
  if (tmp < 2)  // a valid bit value (unsigned, so no negative values)
  {
    sspinadjust(tmp); // change pin level
    send_str(newstat);
    showstatus(STATLIST);
  }
  else send_str(error1);  // abort entry for illegal second character
}

//***************************************************************************
// sspinadjust - modify the physical SS pin on SPI port
//***************************************************************************
void sspinadjust(char level)
{
  if(level) PORT_SPI |= (1 << P_SS);  // make SS pin high
  else PORT_SPI &= ~(1 << P_SS);    // make SS pin low
  ss_level = level;
}

//***************************************************************************
// setautomode - store the required mode for SS pin auto toggle
//***************************************************************************
void setautomode(void)
{
  char tmp;
  
  tmp = getnextchar();
  tmp -= 0x30;  // Remove ASCII offset
  
  if (tmp < 3)  // a valid bit value (unsigned, so no negative values)
  {
    ss_auto = tmp;  // auto mode stored
    send_str(newstat);
    showstatus(STATLIST);
  }
  else send_str(error1);  // abort entry for illegal second character
}

//***************************************************************************
// setorder - set the bit transmission order
//***************************************************************************
void setorder(void)
{
  char tmp;
  
  tmp = getnextchar();
  tmp -= 0x30;  // Remove ASCII offset
  
  if (tmp < 2)  // a valid bit value (unsigned, so no negative values)
  {
    if(tmp) SPCR |= (1 << DORD); // set DORD bit
    else SPCR &= ~(1 << DORD);   // clear DORD bit
    send_str(newstat);
    showstatus(STATLIST);
  }
  else send_str(error1);  // abort entry for illegal second character
}

//***************************************************************************
// setmode - set the SPI communications mode
//***************************************************************************
void setmode(void)
{
  char tmp;
  
  tmp = getnextchar();
  tmp -= 0x30;  // Remove ASCII offset
  
  if (tmp < 4)  // a valid mode value (unsigned, so no negative values)
  {
    SPCR &= 0xF3;         // mask off current CPOL/CPHA bits (bit 3 & 2)
    SPCR |= tmp << 2;     // set new value
    send_str(newstat);
    showstatus(STATLIST);
  }
  else send_str(error1);  // abort entry for illegal second character
}

//***************************************************************************
// writeconfig - save the current configuration in EEPROM
//***************************************************************************
void writeconfig(void)
{
  __disable_interrupt(); // disable interrupts during EEPROM write
  config1 = SPCR;        // store SPCR register
  config2 = SPSR;        // store SPSR register
  config3 = flags;       // store global flag variable
  checksum = 0 - (config1 + config2 + config3);// generate and store checksum
  __enable_interrupt();  // Enable interrupts => enable UART interrupts
  send_str(cfgwrite);
}

//***************************************************************************
// loadconfig - fetch the configuration from EEPROM
//***************************************************************************
void loadconfig(void)
{ // check for valid config - blank EEPROM will not give zero result
  if (!((config1 + config2 + config3 + checksum) & 0xFF))
  {
    SPCR = config1;        // restore SPCR register
    SPSR = config2;        // restore SPSR register
    flags = config3;       // restore global flag variable

    sspinadjust(ss_level); // restore default SS pin level    
    
    send_str(config);
    showstatus(STATLIST);
  }
  else send_str(noconfig);
}

⌨️ 快捷键说明

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