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

📄 spi.c

📁 基于MEGA8单片机的AVR单片机STK500编程器源代码(GCC编译器),改软件完全实现ATMEL STK500协议
💻 C
字号:

#include <avr/io.h>
#include <avr/eeprom.h>

#include "spi.h"
#include "tools.h"
#include "extern_vars.h"

static unsigned char use_sw_spi = 0;

#define MOSI_SET	PORTB|=BIT3_POS
#define MOSI_CLEAR	PORTB&=BIT3_NEG

#define MISO_IN		PINB&BIT4_POS

void spi_enable(void)
{
  unsigned char i;

  R_RES_ON;
  wait_ms(2);
  PORTB &= BIT3_NEG & BIT5_NEG;	//MOSI and SCK low
  DDRB |= BIT3_POS | BIT5_POS;	//MOSI and SCK als Ausgang

  if (eeprom_read_byte(&eeprom_sck_period) > 64)
    {
      use_sw_spi = 1;  //使用模拟SPI
      SPCR=0x00;
    }
  else
    {
      use_sw_spi = 0;  //使用硬件SPI
      SPCR = 0x51;					//SPI Master /16
      spi_set_speed(eeprom_read_byte(&eeprom_sck_period));
    }

  R_RES_OFF;
  for (i=0;i<200;i++) asm("nop");
  R_RES_ON;
  wait_ms(2);

}

void spi_disable(void)
{
  SPCR=0x00;						//SPI aus
  DDRB &= BIT3_NEG & BIT5_NEG;	//MOSI und SCK als Eingang (hochohmig)
  R_RES_OFF;
}

void spi_reset(void)
{
  R_RES_OFF;
  wait_ms(2);
  R_RES_ON;
}

/**
	Stellt die Geschwindigkeit des SPI-Busses ein (bei f=8MHz)
	0:	/2		4MHz	--SPI2X
	1	/4		2MHz
	2:	/8		1MHz	--SPI2X
	3	/16		500kHz
	4:	/32		250kHz	--SPI2X
	5	/64		125kHz
	6:	/128	62,5kHz

	weitere Geschwindigkeiten geplant
	-> dann per Software-SPI
*/
void spi_set_speed(unsigned char s)
{
  if ((s==0)||(s==2)||(s==4)) SPSR|=1;
  else SPSR&=0xFE;

  switch (s)
    {
    case 0:
    case 1:
      SPCR&=0xFC;
      break;
    case 2:
    case 3:
      SPCR&=0xFC;
      SPCR|=0x01;
      break;
    case 4:
    case 5:
      SPCR&=0xFC;
      SPCR|=0x02;
      break;
    case 6:
      SPCR|=0x03;
      break;
    default:		//Wenn Wert ung黮tig ganz langsam
      SPCR|=0x03;
      break;
    }
}

void spi_clock_pulse(void)  //模拟SPI时钟
{
  if (!use_sw_spi)
    {
      SPCR&=BIT6_NEG;		//SPI 使能关闭
    }

  PORTB|=BIT5_POS;	//SPI SCK impuls
  wait_ms(2);
  PORTB&=BIT5_NEG;

  if (!use_sw_spi)
    {
      SPCR|=BIT6_POS;		//SPI 使能
    }
}

/**
	Does a 8 bit transfer over the SPI-Interface
	and gives back the byte received

	@param	d	the byte to be transmitted

	@return		the byte received
*/
unsigned char spi_transfer_8(unsigned char d)
{
  if (!use_sw_spi)
    {
      SPDR=d;
      while (!(SPSR&0x80));

      return SPDR;
    }
  else
    {
      unsigned char result=0,i;
      volatile unsigned int j;

      for (i = 0; i < 8; i++)
        {
          if (d&0x80)
            {
              MOSI_SET;
            }
          else
            {
              MOSI_CLEAR;
            }
          d<<=1;
          result<<=1;

          for (j = 0; j < 18; j++) asm volatile("nop");
          PORTB|=BIT5_POS; //sck 
          if (MISO_IN)
            {
              result|=1;
            }
          for (j = 0; j < 18; j++) asm volatile("nop");
          PORTB&=BIT5_NEG;
        }
      MOSI_CLEAR;

      return result;
    }
}

/**
	Does a 16 bit transfer over the SPI-Interface
	and gives back the last byte received

	@param	d	the int to be transmitted

	@return		the last byte received
*/
unsigned char spi_transfer_16(unsigned int d)
{
  spi_transfer_8((d>>8)&0xFF);
  return spi_transfer_8(d&0xFF);
}

/**
	Does a 32 bit transfer over the SPI-Interface
	and gives back the last byte received

	@param	d	the long to be transmitted

	@return		the last byte received
*/
unsigned char spi_transfer_32(unsigned long d)
{
  spi_transfer_8((d>>24)&0xFF);
  spi_transfer_8((d>>16)&0xFF);
  spi_transfer_8((d>>8)&0xFF);
  return spi_transfer_8(d&0xFF);
}

⌨️ 快捷键说明

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