По просьбам трудящихся...
Под 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, но обработчик не встает
}
}
}