通过SPI总线TMC262的读写
头文件如下:
#ifndef __SPI_TMC26x_H
#define __SPI_TMC26x_H
void InitSPI(void);
UCHAR ReadWriteSPI(UCHAR DeviceNumber, UCHAR Data, UCHAR LastTransfer);
#endif
里面初始化SPI总线以及读写SPI。
初始化SPI函数如下:
void InitSPI(void)
{
//Clock f黵 SPI einschalten
AT91C_BASE_PMC->PMC_PCER=1 << AT91C_ID_SPI0;
先看定义:
基址定义:
#define AT91C_BASE_PMC ((AT91PS_PMC) 0xFFFFFC00) // (PMC) Base Address
_AT91S_PMC为一个结构体,定义了如下一系列的寄存器
其中类型为:
typedef volatile unsigned int AT91_REG;// Hardware register definition
再看赋值:#define AT91C_ID_SPI0 ((unsigned int) 4) // Serial Peripheral Interface 0
再看 AT91C_BASE_PMC->PMC_PCER=1 << AT91C_ID_SPI0;
可以知道,此句的意思就是以AT91C_BASE_PMC为基址有一系列的空间,放置东东类型为一个结构体,里面的成员有{……PMC_PCER,……}。整条语句所干的活就是对某个基址下的结构体里面的成员幅值。
比如下面一条:
AT91C_BASE_PIOA->PIO_PDR=BIT18|BIT17|BIT16|BIT12;
很容易,就是给AT91C_BASE_PIOA为基址的结构体内的成员PIO_PDR赋值为BIT18|BIT17|BIT16|BIT12(也就是18.17.16.12位置位)
typedef struct _AT91S_PMC {
AT91_REG PMC_SCER; // System Clock Enable Register
AT91_REG PMC_SCDR; // System Clock Disable Register
AT91_REG PMC_SCSR; // System Clock Status Register
AT91_REG Reserved0[1]; //
AT91_REG PMC_PCER; // Peripheral Clock Enable Register
AT91_REG PMC_PCDR; // Peripheral Clock Disable Register
AT91_REG PMC_PCSR; // Peripheral Clock Status Register
AT91_REG Reserved1[1]; //
AT91_REG PMC_MOR; // Main Oscillator Register
AT91_REG PMC_MCFR; // Main Clock Frequency Register
AT91_REG Reserved2[1]; //
AT91_REG PMC_PLLR; // PLL Register
AT91_REG PMC_MCKR; // Master Clock Register
AT91_REG Reserved3[3]; //
AT91_REG PMC_PCKR[4]; // Programmable Clock Register
AT91_REG Reserved4[4]; //
AT91_REG PMC_IER; // Interrupt Enable Register
AT91_REG PMC_IDR; // Interrupt Disable Register
AT91_REG PMC_SR; // Status Register
AT91_REG PMC_IMR; // Interrupt Mask Register
} AT91S_PMC, *AT91PS_PMC;
//SPI-Pins verbinden
AT91C_BASE_PIOA->PIO_PDR=BIT18|BIT17|BIT16|BIT12;
AT91C_BASE_PIOA->PIO_ASR=BIT18|BIT17|BIT16|BIT12;
//SPI konfigurieren
AT91C_BASE_SPI0->SPI_CR=AT91C_SPI_SWRST|AT91C_SPI_SPIEN; //SPI-Reset
AT91C_BASE_SPI0->SPI_CR=AT91C_SPI_SWRST|AT91C_SPI_SPIEN; //SPI-Reset (zweimal wegen Rev. B Erratum)
AT91C_BASE_SPI0->SPI_CR=AT91C_SPI_SPIEN; //SPI ist eingeschaltet
AT91C_BASE_SPI0->SPI_MR=AT91C_SPI_MODFDIS|AT91C_SPI_PS_VARIABLE|AT91C_SPI_MSTR; //Master Mode, Chip Select ohne Dekoder
//MODFDIS ist hier sehr wichtig!!!
AT91C_BASE_SPI0->SPI_CSR[0]=AT91C_SPI_CPOL|AT91C_SPI_CSAAT|(24<<8); //2MBit (Device 0)
AT91C_BASE_SPI0->SPI_CSR[1]=AT91C_SPI_CPOL|AT91C_SPI_CSAAT|(24<<8); //2MBit (Device 1)
AT91C_BASE_SPI0->SPI_CSR[2]=AT91C_SPI_CPOL|AT91C_SPI_CSAAT|(24<<8); //2MBit (Device 2)
AT91C_BASE_SPI0->SPI_CSR[3]=AT91C_SPI_CPOL|AT91C_SPI_CSAAT|(24<<8); //2MBit (Device 3)
}
以上是对SPI寄存器的操作,我用的MCU为ATMEGAL32,寄存器的设定在以后的程序里面再介绍。下面是SPI的读写程序。
入口参数为TMC262的编号,写入的数据,和写入的数据是不是最后一位数据。
也就是说,哪个TMC262?写入什么数据?是不是最后一位数据?如果不是最后一位,则数据格式为16位的器件编号+数据,如果已经是最后一位了,则需要加上休止符。
而读数据的逻辑为:如果状态寄存器和溢出标志为闲置状态,则返回接收到的数据,如果处于忙碌状态,则等待。具体程序如下。
UCHAR ReadWriteSPI(UCHAR DeviceNumber, UCHAR Data, UCHAR LastTransfer)
{
//Transfer initiieren
if(LastTransfer)
AT91C_BASE_SPI0->SPI_TDR=(DeviceNumber<<16)|Data|AT91C_SPI_LASTXFER;
else
AT91C_BASE_SPI0->SPI_TDR=(DeviceNumber<<16)|Data;
//Warte bis Transfer beendet (Byte empfangen)
while((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_RDRF)==0);
//Empfangenes Byte zur點kgeben
return AT91C_BASE_SPI0->SPI_RDR & 0xff;
}
下面对读写TMC262的程序进行简单介绍:
Static定义其为静态全局变量,也就是说在整个文档中都可以调用。
已经知道,TMC的寄存器数据有20位,MCU的int有32位,函数实现如下:
static void ReadWrite262(UCHAR Which262, UINT *ReadInt, UINT WriteInt)
{
*ReadInt=ReadWriteSPI(SPI_DEV_TMC26x, WriteInt >> 16, FALSE);
*ReadInt<<=8;
*ReadInt|=ReadWriteSPI(SPI_DEV_TMC26x, WriteInt >> 8, FALSE);
*ReadInt<<=8;
*ReadInt|=ReadWriteSPI(SPI_DEV_TMC26x, WriteInt & 0xff, TRUE);
*ReadInt>>=4;
}
文章评论(0条评论)
登录后参与讨论