文档库 最新最全的文档下载
当前位置:文档库 › Spi_LedWord

Spi_LedWord

//##########################################################################################################
//
// FILE: zSpi_LedWord.c
//
// TITLE: DSP2802x Device Spi Digital Loop Back program.
//
// ASSUMPTIONS:
//
// This program requires the DSP2802x header files.
//
// This program uses the internal loop back test mode of the peripheral.
// Other then boot mode pin configuration, no other hardware configuration
// is required.
//
// As supplied, this project is configured for "boot to SARAM"
// operation. The 2802x Boot Mode table is shown below.
// For information on configuring the boot mode of an eZdsp,
// please refer to the documentation included with the eZdsp,
//
// $Boot_Table
// While an emulator is connected to your device, the TRSTn pin = 1,
// which sets the device into EMU_BOOT boot mode. In this mode, the
// peripheral boot modes are as follows:
//
// Boot Mode: EMU_KEY EMU_BMODE
// (0xD00) (0xD01)
// ---------------------------------------
// Wait !=0x55AA X
// I/O 0x55AA 0x0000
// SCI 0x55AA 0x0001
// Wait 0x55AA 0x0002
// Get_Mode 0x55AA 0x0003
// SPI 0x55AA 0x0004
// I2C 0x55AA 0x0005
// OTP 0x55AA 0x0006
// Wait 0x55AA 0x0007
// Wait 0x55AA 0x0008
// SARAM 0x55AA 0x000A <-- "Boot to SARAM"
// Flash 0x55AA 0x000B
// Wait 0x55AA Other
//
// Write EMU_KEY to 0xD00 and EMU_BMODE to 0xD01 via the debugger
// according to the Boot Mode Table above. Build/Load project,
// Reset the device, and Run example
//
// $End_Boot_Table
//
// DESCRIPTION:
//
// This program is a SPI example that uses the internal loopback of
// the peripheral. Interrupts are not used.
//
// A stream of data is sent and then compared to the recieved stream.
//
// The sent data looks like this:
// 0000 0001 0002 0003 0004 0005 0006 0007 .... FFFE FFFF
//
// This pattern is repeated forever.
//
// Watch Variables:
// sdata - sent data
// rdata - received data
//
//##########################################################################################################

#include "DSP28x_Project.h" // Device Headerfile and Examples Include File

// Prototype statements for functions found within this file.
// interrupt void ISRTimer2(void);
void delay_loop(void);
void spi_xmit(Uint16 a);
void spi_fifo_init(void);
void spi_init(void);
void error(void);
void delay_us(Uint16 us);
void delay_ms(Uint16 us);
void LedWord_io_init(void);

uchar RowShift = 0x08;
Uint16 Ledcount;

Uint16 LedWord[16] = {
0x0200,0x0200,0x0200,0x0220,0x7FF0,0x0220,0x0220,0x0420,
0x0420,0x0420,0x0820,0x0824,0x1024,0x2026,0x403C,0x

0000}; // 九
Uint16 LedWordModify[16] = {
0x0200,0x0200,0x0200,0x0220,0x7FF0,0x0220,0x0220,0x0420,
0x0420,0x0420,0x0820,0x0824,0x1024,0x2026,0x403C,0x0000}; // 九
Uint16 LedWords[48]={
0x0000,0x7FE0,0x0020,0x0020,0x1020,0x1020,0x1020,0x1FFC,
0x0004,0x0004,0x0004,0xFFE4,0x0004,0x0004,0x0028,0x0010,
0x1000,0x92F0,0x9290,0x9290,0xFE90,0x0090,0xFE90,0x0290,
0x0290,0x7E90,0x4090,0x4092,0x4692,0x5912,0x610E,0x0200,
0x0850,0x0848,0x0880,0x7EFE,0x1190,0x1290,0x20FC,0x2890,
0x4890,0x48FC,0x9090,0x1490,0x2290,0x7EFE,0x2280,0x0080};

unsigned int LedFrameCounter=0;
unsigned int LedDispLine=0;
void main(void)
{
// Uint16 sdata; // send data
// Uint16 rdata; // received data

// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2802x_SysCtrl.c file.
InitSysCtrl();

// Step 2. Initalize GPIO:
// This example function is found in the DSP2802x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio(); // Skipped for this example
// Setup only the GP I/O only for SPI-A functionality
// This function is found in DSP2802x_Spi.c
InitSpiaGpio();
LedWord_io_init();
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;

// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2802x_PieCtrl.c file.
InitPieCtrl();

// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;

// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP2802x_DefaultIsr.c.
// This function is found in DSP2802x_PieVect.c.
InitPieVectTable();

// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2802x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
spi_fifo_init(); // Initialize the Spi FIFO
spi_init(); // init SPI

// Step 5. User specific code:
// Interrupts are not used in this example.
// sdata = 0x0000;
for(;;)
{
for(LedFrameCounter=0;LedFrameCounter<48;LedFrameCounter++)
{
RowShift=0x08;
// 该段程序用于LED 16*16 汉字字屏
for(Ledcount=0;Ledcount<16;Ledcount++)
{
if(RowShift == 0x18)
RowShift=0x08;
GpioDataRegs.GPADAT.all = RowShift;
//LedDispLine=(Ledcount+LedFrameCounter)%16;
LedDispLine=(Ledcount)%16;
LedWordModify[LedDispLine]=LedWords[LedDispLine+(LedFrameCounter/16)*16]<<(LedFrameCounter%16))+(LedWords[(LedDispLine+16+(LedFrameCounter/16)*16)%48]>>(16-(LedFrameCounter%16));
// spi_xmit(0x5555);
spi_xmit(~LedWord

Modify[LedDispLine]);
// delay_us(30);

// while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
// // Check against sent data
// rdata = SpiaRegs.SPIRXBUF;
// if(rdata != ~LedWord[Ledcount]) error();
RowShift ++;
delay_us(150);
}
LedWordModify[0]=LedWordModify[0]<<1;
spi_xmit(~LedWordModify[0]);
}
}
}

// Step 7. Insert all local Interrupt Service Routines (ISRs) and functions here:

//***********************************************************************************************************
// delay_us (unsigned int us): 微秒级延时
// delay_ms (unsigned int ms): 毫秒级延时
// 在60MHz主频时,指令周期为16.6667ns,60 个指令周期为1us,60000 个指令周期为1ms,
//***********************************************************************************************************
void delay_us (Uint16 us)
{
Uint16 i,j;
for(i=0;i{
for(j=0;j<60;j++); //内层循环1微秒定时
}
}

void delay_ms (Uint16 ms)
{
Uint16 i,j;
for(i=0;i{
for(j=0;j<6000;j++); //内层循环1毫秒定时
}
}

void delay_loop()
{
long i;
for (i = 0; i < 1000000; i++) {}
}

void error(void)
{
asm(" ESTOP0"); // Test failed!! Stop!
for (;;);
}


//**************** SPI 函数 ****************//
/********************************************************************************************
函数: spi_init()
功能: SPI初始化
********************************************************************************************/
void spi_init()
{
SpiaRegs.SPICCR.bit.SPISWRESET=0;
/* 对SPI配置控制寄存器(SPICCR)进行配置 */
// SpiaRegs.SPICCR.all =0x000F; // 这条指令与下面4条指令等价
SpiaRegs.SPICCR.bit.SPICHAR=0x0F; // 字符移送的长度为16位
SpiaRegs.SPICCR.bit.SPILBK=0; // 禁止回送模式
// 由外部接线进行数据回送

SpiaRegs.SPICCR.bit.CLKPOLARITY=0; // 上升沿传送出数据,用于74HC595
// SpiaRegs.SPICCR.bit.CLKPOLARITY=1; // 下降沿传送出数据,用于74HC164
// 注意:采用74HC164时,LED 屏(16*16)必须选用下降沿传送出数据,否则 LED 屏显示不正常


SpiaRegs.SPICCR.bit.SPISWRESET=0;
// 将SPI操作标志位初始化为默认状态,特别是将下面SPI状态寄存器的3个标志位清0:
// BUFFULL_FLAG(SPISTS[5]) SPI发送缓冲器已满标志位
// INT_FLAG(SPISTS[6]) SPI中断标志位
// OVERRUN_FLAG(SPISTS[7]) SPI接收溢出标志位
// 用户必须在改变SPI控制寄存器的配置之前将SPISWRESET清0,而在设置完成之后将
// SPISWRESET置1。
/*
SPICHAR:4; // 3:0 字符长度控制位 字符长度 = SPICHAR + 1
SPILBK:1; // 4 回送使能/禁止 0/1:禁止 SPI 回送模式 / 使能 SPI 回

送模式
rsvd1:1; // 5 保留
CLKPOLARITY:1; // 6 时钟极性控制位 0/1:上升沿传送数据 / 下降沿传送数据
SPISWRESET:1; // 7 SPI软件复位 0/1:SPI 标志位复位 / SPI 准备发送或接收
rsvd2:8; // 15:8 保留
*/

/* 对SPI控制寄存器(SPICTL)进行配置 */
// SpiaRegs.SPICTL.all =0x0006; // 这条指令与下面5条指令等价
SpiaRegs.SPICTL.bit.SPIINTENA=0; // 关SPI中断
SpiaRegs.SPICTL.bit.TALK=1; // 使能发送
SpiaRegs.SPICTL.bit.MASTER_SLAVE=1;
// 设置当前机为主机模式:SPISIMO引脚输出,SPISOMI引脚输入
SpiaRegs.SPICTL.bit.CLK_PHASE=0; // 0: 常规SPI时钟方案
// 0/1: SPICLK 无延迟 / SPICLK 延迟 1/2 周期
SpiaRegs.SPICTL.bit.OVERRUNINTENA=0;
// 禁止OVERRUN_FLAG(SPISTS[7])标志位引发的中断
/*
SPIINTENA:1; // 0 中断使能
TALK:1; // 1 主/从发送使能
MASTER_SLAVE:1; // 2 网络主/从机模式控制
CLK_PHASE:1; // 3 SPI时钟相位选择
OVERRUNINTENA:1; // 4 溢出中断使能
*/

//###############################################################################################
// SPI波特率的计算:
// (1)系统时钟 SYSCLKOUT
// 通过 头文件 DSP2802x_Device.h 及头文件 DSP2802x_Examples.h, 系统时钟设定为 60 MHz
//
// (2)计算低速外设时钟 LSPCLK
// 低速外设时钟与系统时钟 SYSCLKOUT 的关系参见式(4.1)
// 当LOSPCP[2:0]不等于0时,有 LSPCLK = SYSCLKOUT/[LOSPCP[2:0]*2]
//
// 其中 LOSPCP[2:0]=2,默认值,参见 DSP2802x_SysCtrl.c 函数中的指令
// " SysCtrlRegs.LOSPCP.bit.LSPCLK = 0x0002; "
// 因此, 低速外设时钟 LSPCLK (频率) = 60/4 = 15 MHz
//

// (3)SPI波特率寄存器的设置
// 根据式(5.4)或 式(5.3) SPIBRR = [LSPCLK/SPI(波特率)]-1 或
// SPI(波特率) = LSPCLK/(SPIBRR+1) 当 3 <= SPIBRR <= 127
// SPI(波特率) = LSPCLK/4 当 SPIBRR=0,1,2,3 时
//
// 例如本例设置SPIBRR = 0x7F = 127, 则 SPI(波特率) = 15 000 000/128 = 117188
// SPIBRR = 0, SPI(波特率) = 15 000 000/4 = 3.75 MHz
//###############################################################################################
SpiaRegs.SPIBRR =0; // 波特率设置


/* 对SPI配置控制寄存器(SPICCR)再进行配置 */
//SpiaRegs.SPICCR.all =0x009F;
// 较之在该函数中出现的"SpiaRegs.SPICCR.all =0x000F;"指令,改变了下面两条指令:
SpiaRegs.SPICCR.bit.SPISWRESET=1; // SPI准备发送或接收下一字。
SpiaRegs.SPICCR.bit.SPILBK=1;
// 使能SPI回送模式。 SIMO/SOMI线在内部连接,用于模块自行测试。

/* 对SPI优先权控制寄存器(SPIPRI)的仿真控制位进行设置 */
SpiaRegs.SPIPRI.bit.FREE = 1; // 空转。忽

视中断挂起,SPI继续工作。
}


void spi_xmit(Uint16 a)
{
SpiaRegs.SPITXBUF=a;
}

void spi_fifo_init()
{
// Initialize SPI FIFO registers
SpiaRegs.SPIFFTX.all=0xE040;
SpiaRegs.SPIFFRX.all=0x2044;
SpiaRegs.SPIFFCT.all=0x0;
}

void LedWord_io_init(void)
{
EALLOW;

GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0x00; // 设置GPIO0-GPIO7 为GPIO
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 0x00;
GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 0x00;
GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 0x00;

GpioCtrlRegs.GPADIR.bit.GPIO0 = 0x11; // 设置GPIO0-GPIO7 为输出
GpioCtrlRegs.GPADIR.bit.GPIO1 = 0x11;
GpioCtrlRegs.GPADIR.bit.GPIO2 = 0x11;
GpioCtrlRegs.GPADIR.bit.GPIO3 = 0x11;

EDIS;
}


//===========================================================================
// No more.
//===========================================================================


相关文档