使用的是s3c2440开发板的引出脚,SPI的MOSI为主输出,MISO为主输入,只有主机发送,这里测发送的波形,以及SCLK 和SEN(nSS)使能引脚的波形测得的波形出问题了
波形如下
下面是代码。不晓得哪里出错了哦#include "uart.h"
#include "adc.h"
//#include "ucos.h"
#include "2440addr.h"
#include "stdarg.h"
#include "def.h"
/* 无线模块1 */
#define MISO0 11 /* GPE11:SPI输入 */
#define GET_MISO0() ((rGPEDAT & (1<<MISO0)) >> MISO0)
#define MOSI0 12 /* GPE12:SPI输出 */
#define SET_MOSI0(value) (rGPEDAT = (rGPEDAT & ~(1<<MOSI0)) | (value<<MOSI0))
#define SCK0 13 /* GPE13:SPI输出 */
#define SET_SCK0(value) (rGPEDAT = (rGPEDAT & ~(1<<SCK0)) | (value<<SCK0))
#define CE0 14 /* GPG14:数字输出 */
#define SET_CE0(value) (rGPGDAT = (rGPGDAT & ~(1<<CE0)) | (value<<CE0))
#define GET_CE0() ((rGPGDAT & (1<<CE0)) >> CE0)
#define CSN0 2 /* GPG2: SPI输出 */
#define SET_CSN0(value) (rGPGDAT = (rGPGDAT & ~(1<<CSN0)) | (value<<CSN0))
#define IRQ0 13 /* GPG13: 中断输入 */
#define GET_IRQ0() ((rGPFDAT & (1<<IRQ0)) >> IRQ0)
/* 无线模块2 */
#define MISO1 5 /* GPG5:SPI输入 */
#define GET_MISO1() ((rGPGDAT & (1<<MISO1)) >> MISO1)
#define MOSI1 6 /* GPG6:SPI输出 */
#define SET_MOSI1(value) (rGPGDAT = (rGPGDAT & ~(1<<MOSI1)) | (value<<MOSI1))
#define SCK1 7 /* GPG7:SPI输出 */
#define SET_SCK1(value) (rGPGDAT = (rGPGDAT & ~(1<<SCK1)) | (value<<SCK1))
#define CE1 0 /* GPG0:数字输出 */
#define SET_CE1(value) (rGPGDAT = (rGPGDAT & ~(1<<CE1)) | (value<<CE1))
#define GET_CE1() ((rGPGDAT & (1<<CE1)) >> CE1)
#define CSN1 3 /* GPG3: SPI输出 */
#define SET_CSN1(value) (rGPGDAT = (rGPGDAT & ~(1<<CSN1)) | (value<<CSN1))
#define IRQ1 11 /* GPG11: 中断输入 */
#define GET_IRQ1() ((rGPGDAT & (1<<IRQ1)) >> IRQ1)
void delay(int t)
{
for(;t>0;t--);
}
static void usDelay(U32 uSeconds, void __irq (*PwmIsr)(void)) {
// set ISR for PWM Timer 4
if (PwmIsr != NULL) {
ClearPending(BIT_TIMER4);
pISR_TIMER4 = (U32) PwmIsr;
EnableIrq(BIT_TIMER4);
}
// timer input clock frequency = PCLK / (24 + 1) / 2 = 1 MHz
rTCFG0 &= ~(0xff << 8); // clear TCFG0[15:8](Prescaler 1) to 0
rTCFG0 |= 24 << 8; // Prescaler 1 = 24
rTCFG1 &= ~(0xf << 16); // clear TCFG1[19:16](MUX 4) to 0
rTCFG1 |= 0 << 16; // MUX 4 = 0000 = 1/2
rTCNTB4 = uSeconds; // use PWM Timer 4, the initial count value is uSeconds
rTCON &= ~(0x7 << 20); // clear TCON[22:20] to 0
rTCON |= 0x0 << 22; // one-shot
rTCON |= 0x1 << 21; // manula update TCNTB4
rTCON |= 0x1 << 20; // start for Timer 4
rTCON &= ~(0x1 << 21); // clear TCON[21](Timer 4 Manual Update) to zero
while(rTCNTO4)
;
}
static void InitSpi(void) {
// 设置时钟控制寄存器(CLKCON),使能SPI时钟
rCLKCON = (rCLKCON & ~(1 << 18)) | (1 << 18);
// SPI0为主设备
// 初始化GPE GPE11:MISO0(MISO);GPE12:MOSI0(MOSI);GPE13:SPICLK0(SCK)
rGPECON = (rGPECON & ~(3 << MISO0 * 2 | 3 << MOSI0 * 2 | 3 << SCK0 * 2)) |
(2 << MISO0 * 2 | 2 << MOSI0 * 2 | 2 << SCK0 * 2);
// 初始化GPG GPG13:GPG2: nSS_SPI0(CSN),配置为输出
rGPGCON = (rGPGCON & ~(3 << CSN0 * 2)) | (1 << CSN0 * 2);
rGPGUP &=~(1<<2);
// 设置波特率预定标器寄存器(SPPREn),波特率 = PCLK / 2 / (预定标器值 + 1) = 1MHz
rSPPRE0 = 0x18;
// 设置SPCONn寄存器以正确配置SPI模块
// normal; format A; active high; master; enable; polling mode
//1<<1,CPHA=1;0<<2,CPOL=0,
rSPCON0 = (rSPCON0 & ~(1 << 0 | 1 << 1 | 1 << 2 | 1 << 3 | 1 << 4 | 3 << 5)) |
(0 << 0 | 1 << 1 | 0 << 2 | 1 << 3 | 1 << 4 | 0 << 5);
// 设置SPI引脚控制寄存器(SPPINn)
// Release; Disable (general purpose)
rSPPIN0 = (rSPPIN0 & ~(1 << 0 | 1 << 2)) | (0 << 0 | 0 << 2);
}
static char Spi0Transfer(char uch1) {
char temp;
while(!(rSPSTA0&0x01));
// 将nSS(CSN)引脚设为低电平,激活SPI模块
//上面是原文,这里因为SL900A是高电平才有效
//所以这里是设置为高电平,激活SPI模块。
SET_CSN0(1);
delay(5);
// usDelay(1, NULL);
// 发送流程,若uch不为NULL,则开始发送;若uch为NULL,则自动发送哑数据
// if (uch1 != NULL)
rSPTDAT0 = uch1;
// else
// rSPTDAT0 = 0xFF;
// 判定SPSTAn寄存器的REDY标志
while (!(rSPSTA0 & 0x01))
;
// 接收流程,初始化时已经配置为TAGD位,没有数据发送时自动发送哑数据
temp = rSPRDAT0;
// 将nSS(CSN)引脚设为高电平,关闭SPI模块
SET_CSN0(0);
delay(5);
//usDelay(1, NULL);
return temp;
}
void Main(void)
{
unsigned char i,uiRcvData;
unsigned char const uiBuf[8] = {0x66, 0x00, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0xff};
Uart0_Init(115200);
InitSpi();
/*
while (1) {
for (i = 0; i < 8; i++){
Spi0Transfer(uiBuf[1]);
uiRcvData = Spi0Transfer(NULL);
Uart_Printf("\n Master: 0x%x\n", uiRcvData);
}
usDelay(1000, NULL);
}
*/
while(1)
{
Spi0Transfer(uiBuf[3]);
Spi0Transfer(uiBuf[4]);
//Uart0_Printf("i=%d\n",i);
//usDelay(1000, NULL);
}
}
|