8G1K08的SPI读写串口psram
<p>采用软件或硬件SPI方式读写串口psram,最近想用串口psram当显示屏的缓存,买了乐鑫psram64h和来扬LY68L6400芯片进行测试,用SPI方式读写成功,代码如下:</p><p>主代码文件:main.c</p>
//
//PSRAM演示程序,采用普通SPI功能读写芯片,编译时定义 HARDWARE_SPI,则使用硬件SPI功能
//否则使用软件模拟SPI,读写芯片
// # psram id:0x0D5D-46A02A547A67--PSRAM64H,SPI模式2、模式3测试能成功
// # psram id:0x0D5D-5312A4D13899--LY68L6400SLI,SPI模式0、模式3测试能成功
#include "sysdef.h"
#define BUFSIZE 256
unsigned char Device_ID = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
unsigned char xdata test_buf;
u32 systick = 0;
sbit LED = P5^4;
void Print_Drive_ID(void);
void Timer0_Init(void);
// 主函数
void main(void)
{
unsigned int i;
unsigned long addr = 0;
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M0 = 0x80; P3M1 = 0x00; //P3.7设置为推挽输出,用于PSRAM启动供电
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P1PU = 0xff; P3PU = 0xff;
Uart1_Init();
Timer0_Init();
EA = 1;
printf("uart init.\r\n");
Delay_ms(50);
printf("[%ldms]:Psram Init.\r\n",systick);
PSRAM_Init();
PSRAM_ReadID(Device_ID,8);
Delay_ms(1);
PSRAM_ReadID(Device_ID,8);
Delay_ms(1);
printf("[%ldms]:Psram Init OK.\r\n",systick);
while(1)
{
#if defined(HARDWARE_SPI)
printf("<<<<*********** USING HARDWARE SPI *************>>>>\r\n");
printf("SPI PIN--CS(P1.0), MOSI(P3.4), MISO(P3.3), SCLK(P3.2)\r\n");
#else
printf("<<<<*************** USING SOFT SPI ************>>>>\r\n");
printf("SOFT-SPI PIN--CS(P1.0), MOSI(P3.6), MISO(P1.1), SCLK(P3.5)\r\n");
#endif
PSRAM_ReadID(Device_ID,8);
printf("PSRAM64H ID: ");
Print_Drive_ID();
for(i = 0; i < 8;i++)
Device_ID = 0;
printf("\r\n");
printf("[ %ld ms]:Write Data to psram. Addr:%#lx.\r\n",systick,addr);
for(i = 0; i < sizeof(test_buf); i++)
test_buf = i;
PSRAM_Write(addr,test_buf,sizeof(test_buf));
printf("[ %ld ms]:Write Psram finish.\r\n",systick);
Delay_ms(1);
printf("[ %ld ms]:Clear cache.\r\n",systick);
for(i = 0; i < sizeof(test_buf); i++)
test_buf = 0;
printf("[ %ld ms]:Start Read Psram Data.\r\n",systick);
PSRAM_Read(addr,test_buf,sizeof(test_buf));
printf("<<<<***************** READ DATA *****************>>>>\r\n");
for(i = 0; i < sizeof(test_buf); i++){
PrintLong2Str(addr);
PrintHex2Str(test_buf);PrintHex2Str(test_buf);PrintHex2Str(test_buf);PrintHex2Str(test_buf);
PrintHex2Str(test_buf);PrintHex2Str(test_buf);PrintHex2Str(test_buf);PrintHex2Str(test_buf);
PrintHex2Str(test_buf);PrintHex2Str(test_buf);PrintHex2Str(test_buf);PrintHex2Str(test_buf);
PrintHex2Str(test_buf);PrintHex2Str(test_buf);PrintHex2Str(test_buf);PrintHex2Str(test_buf);
addr+= 16;
printf("\r\n");
}
printf("[ %ld ms]:Read Psram finish.\r\n",systick);
Delay_ms(1000);
}
}
void Print_Drive_ID(void){
PrintHex2Str(Device_ID);
PrintHex2Str(Device_ID);
PrintHex2Str(Device_ID);
PrintHex2Str(Device_ID);
PrintHex2Str(Device_ID);
PrintHex2Str(Device_ID);
PrintHex2Str(Device_ID);
PrintHex2Str(Device_ID);
}
void Timer0_Isr(void) interrupt 1
{
systick++;
if(systick % 500 == 0)
LED = !LED;
}
void Timer0_Init(void) //1毫秒@24.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x40; //设置定时初始值
TH0 = 0xA2; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
}<p>spi.c文件</p>
#include "spi.h"
#if defined(HARDWARE_SPI)
#define SPIF 0x80
#define WCOL 0x40
#define SSIG 0x80
#define SPEN 0x40
#define DORD 0x20
#define MSTR 0x10
void SPI_Init(void){
P_SW1 |= 0x0c; //SPI: SS(P3.5), MOSI(P3.4), MISO(P3.3), SCLK(P3.2)
SPCTL = 0x9C; //SSIG=1,SPEN=0,DORD=0,MSTR=1,CPOL=0,CPHA=0,SPR=00b
SPCTL |= SPI_MODE<<2;
SPSTAT = 0xC0;//SPIF、WCOL写1清空
SPCTL |= SPEN;//使能硬件SPI
}
u8 SPI_ReadWrite(u8 dat){
SPDAT = dat;
while(!(SPSTAT & SPIF));
SPSTAT = 0xC0;
return SPDAT;
}
#else
void SPI_Init(void){
CS = 1;
MOSI = 1;
MISO = 1;
CLK = S_CPOL;
}
u8 SPI_ReadWrite(u8 dat){
u8 rst = 0;
u8 i;
for(i = 0; i < 8; i++){
#if (S_CPHA) //数据前沿驱动后沿采样
{
CLK = !S_CPOL;
MOSI = (bit)(dat & 0x80);
dat <<= 1;
CLK = S_CPOL;
rst <<= 1;
rst |= MISO;
}
#else //数据前沿采样后沿驱动
{
MOSI = (bit)(dat & 0x80);
dat <<= 1;
CLK = !S_CPOL;
rst <<= 1;
rst |= MISO;
CLK = S_CPOL;
}
#endif
}
return rst;
}
#endif<p>uart.c文件</p>
#include "uart.h"
bit serial_busy;
char wptr;
char rptr;
char buffer;
void Uart1_Isr(void) interrupt 4
{
if (TI) //检测串口1发送中断
{
TI = 0; //清除串口1发送中断请求位
serial_busy = 0;
}
if (RI) //检测串口1接收中断
{
RI = 0; //清除串口1接收中断请求位
buffer = SBUF;
wptr &= 0x0F;
}
}
void Uart1_Init(void) //115200bps@24.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0xCC; //设置定时初始值
T2H = 0xFF; //设置定时初始值
AUXR |= 0x10; //定时器2开始计时
ES = 1; //使能串口1中断
}
void UartSend(char dat)
{
while (serial_busy);
serial_busy = 1;
SBUF = dat;
}
char putchar(char c){
UartSend(c);
return c;
}
void PrintHex2Str(unsigned char dat){
unsigned char i,j;
i = (dat & 0xF0)>>4;
j = dat & 0x0F;
if(i >= 0 && i <=9)
i += '0';
else if(i >= 10 && i <= 15)
i = i - 10 + 'A';
if(j >= 0 && j <=9)
j += '0';
else if(j >= 10 && j <= 15)
j = j - 10 + 'A';
UartSend(i);
UartSend(j);
UartSend(' ');
}
void PrintLong2Str(long addr){
unsigned char dat,i,j;
dat = (addr >> 16) & 0xFF;
i = (dat & 0xF0)>>4;
j = dat & 0x0F;
if(i >= 0 && i <=9)
i += '0';
else if(i >= 10 && i <= 15)
i = i - 10 + 'A';
if(j >= 0 && j <=9)
j += '0';
else if(j >= 10 && j <= 15)
j = j - 10 + 'A';
UartSend(i);
UartSend(j);
dat = (addr >> 8) & 0xFF;
i = (dat & 0xF0)>>4;
j = dat & 0x0F;
if(i >= 0 && i <=9)
i += '0';
else if(i >= 10 && i <= 15)
i = i - 10 + 'A';
if(j >= 0 && j <=9)
j += '0';
else if(j >= 10 && j <= 15)
j = j - 10 + 'A';
UartSend(i);
UartSend(j);
dat = addr & 0xFF;
i = (dat & 0xF0)>>4;
j = dat & 0x0F;
if(i >= 0 && i <=9)
i += '0';
else if(i >= 10 && i <= 15)
i = i - 10 + 'A';
if(j >= 0 && j <=9)
j += '0';
else if(j >= 10 && j <= 15)
j = j - 10 + 'A';
UartSend(i);
UartSend(j);
UartSend(' ');UartSend(' ');UartSend(' ');UartSend(' ');
}
页:
[1]