ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
23 ноября
16552 Топик полностью
ChumA (11.11.2004 20:01, просмотров: 1) ответил lamerok на А можно на код взглянуть?
По просьбам трудящихся... 
Под IAR4.10

//Малость подрезано и склеено из разных файлов, синтаксис мог и слегка того'с

#include 
#include 
#pragma language=extended

//=======================================================================================================
// Для отправки данных data_0...data_n по SPI0 должно:
//  1. Заполнить data_n...data_0 в SPI0_Buf[0]...SPI0_Buf[n] (т.е. пересылка нач. с ХВОСТА буфера)
//  2. Поместить в SPI0_cnt кол-во отправляемых байт
//  3. Вызвать SPI0_Start(data_0)
// После передачи всех данных обработчик прерывания запретит себя сам
// Состояние модуля SPI определяется по SPI0_State (не рекомендуют дергать регистры модуля до возн.прер-я )
//=======================================================================================================
unsigned char SPI0_Buf[8]; // сюда грузим то, что будем отправлять по SPI
unsigned char SPI0_Cnt;    // сюда грузим кол-во пересылаемых байт == 2 для DAC AD5317
volatile unsigned char SPI0_State;  // 0 == свободен / != 0 занят

#define CSDAC   28
#define RESDAC  29

__arm void SPI0_handler()
{
unsigned char sdat = S0SPDR;

if(SPI0_State)  // 1 == занят
  {
  if(SPI0_Cnt) // не все данные из буфера отправлены
    {
    unsigned char *spi_data;
    --SPI0_Cnt;
    spi_data = SPI0_Buf + SPI0_Cnt;
    S0SPDR = *spi_data;
    }
  else  // все данные отправлены
    {
    IO0SET = 1 << CSDAC; // CSDAC = 1
    SPI0_State = 0;       // свободен
    }
  }
}

__arm __irq void irq_handler()
{
  void (*interrupt_function)();
  unsigned int vector;

  vector = VICVectAddr; // Get interrupt vector.
  interrupt_function = (void(*)())vector;
  (*interrupt_function)(); // Call vectored interrupt function.
  VICVectAddr = 0; // Clear interrupt in VIC.
}


void SPI0_Start()
{
SPI0_State = 1;    // признак занят
IO0CLR = 1 << CSDAC; // CSDAC = 0
SPI0_Cnt = 1;     // тоже SPI0_Cnt = 2; --SPI0_Cnt;
S0SPINT |= 0x01;
S0SPDR = SPI0_Buf[SPI0_Cnt];
}

void SPI0_Setup()
{
IO0DIR |= ((1 << RESDAC) | (1 << CSDAC));  // RDAC = Out CSDAC = Out
IO0SET  = ((1 << RESDAC) | (1 << CSDAC));  // RDAC = 1 CSDAC = 1

S0SPCCR = 32;  // SPIclc = (PCLC = CCLC/VPP)/SPCCR
//         SPIE       MSTR       CPOL
S0SPCR = (1 << 7) | (1 << 5) | (1 << 4);

SPI0_State = 0;       // свободен
}

void Intr_Setup()
{
VICIntSelect = 0; // нет прерываний назначенных на FIQ

// прерывание от SPI разрешено (оно жестко приписано к VIC Chanel .10)
VICIntEnable |= (1 << VIC_SPI);

VICVectAddr10 = (unsigned int)&SPI0_handler; // на Addr14 записываем адрес обработчика прерывания SPI0
VICVectCntl10 = 0x20 | VIC_SPI;  // обработчик по Addr0 разрешен и назначен на VIC Chanel №10 (т.е. SPI0)
}

void PIN_P0_Setup()
{
//        SSEL = 15:14, MOSI = 12:13, MISO = 11:10, SCK = 9:8
PINSEL0 |= (1 << 14)  |  (1 << 12)  |  (1 << 10)  |  (1 << 8);
}

void main()
{
__disable_interrupt();

PIN_P0_Setup();
RAM_Setup();
//TO_Setup(); // 50 mS
SPI0_Setup();

Intr_Setup();

__enable_interrupt();

while(1)
{
  unsigned char dac_ch;
  for(dac_ch = 0; dac_ch < 4; ++dac_ch)
    {
    unsigned short u_out = 128;
    
    /* заком. код работает нормально
    unsigned char sdat;
    IO0CLR = 1 << 28; // CSDAC = 0
    sdat = (dac_ch << 6) | ((unsigned char)(u_out >> 6)) | 0x10;
    S0SPDR = sdat;
    while(!(S0SPSR & (1 << 7))); // SPIF - bit7
    sdat = (unsigned char)(u_out << 2);
    S0SPDR = sdat;
    while(!(S0SPSR & (1 << 7))); // SPIF - bit7
    IO0SET = 1 << 28; // CSDAC = 1
    */
    
    while(SPI0_State);   // 1 == занят    
    SPI0_Buf[0] = (unsigned char)(u_out << 2);
    SPI0_Buf[1] = (dac_ch << 6) | ((unsigned char)(u_out >> 6)) | 0x10;
    SPI0_Start();
    // после этого генерится SPIF, но обработчик не встает
    }
    
}

}