- 打卡等级:偶尔看看I
- 打卡总天数:12
- 最近打卡:2024-10-08 15:50:35
注册会员
- 积分
- 138
|
发表于 2024-9-26 11:29:15
|
显示全部楼层
你好,能不能再抽空帮我看看这个问题:
读W25Q,指令+地址是4个字节,DMA读128字节,用逻辑分析仪捕获应该是132个字节才对,
但实际捕获显示DMA只读取了127字节,
如果设置DMA读256字节,则实际也只读取了255字节,
能否帮忙看看是哪里有问题?
/********************************************************
标准2线_硬件SPI+DMA_新代码测试
STC8H4K64TL-LQFP32
*********************************************************/
#include "stc8h.h"
#include "stdio.h"
#include "intrins.h"
#include <string.h>
#define u8 unsigned char //1字节 0~255
#define u16 unsigned int //2字节 0~65535
sbit SPI_SCLK = P3^2;
sbit SPI_MISO = P3^3;
sbit SPI_MOSI = P3^4;
sbit SPI_CS = P3^5;
sbit W25Q_IO2 = P2^0;
sbit W25Q_IO3 = P2^1;
bit busy = 0;
void delayms(u16 count) //* n*1ms延时
{
u8 i,j;
u16 k; //u16:0-65535,最长约65秒
for(k=0;k<count;k++){
i = 44;j = 195; //1ms@45MHz
do{
while (--j);
}
while (--i);
}
}
#define SPIF 0x80 //1000 0000 SPSTAT.7
#define WCOL 0x40 //0100 0000 SPSTAT.6
void SPI_Config()
{
P_SW1 |= 0x0C;
P_SW2 |= 0x80;
SPSTAT = 0xC0; //
SPCTL = 0xD0; //B1101 0000 忽略SS引脚,使能SPI,先收发MSB,主机,
//IE2 |= 0x02; //使能SPI中断
}
void SPI_ISR()interrupt 9
{
// P_SW2 |= 0x80;
// SPCTL = 0xD0;
// SPI_CS = 1;
// busy = 0;
}
////////////////////////////////////////////////////////////
void SPI_SendByte(u8 dat)
{
SPDAT = dat;
while (!(SPSTAT & SPIF)); //等待发送完成
SPSTAT = SPIF | WCOL; //清除SPI状态位
}
void SPI_WriteNByte(u8 *dat,u8 len)
{
u8 i;
for(i=0;i<len;i++){
SPI_SendByte(dat);
}
}
//u8 SPI_Swap(u8 dat)
//{
// SPDAT = dat; //触发SPI发送数据
// while(busy);// (!(SPSTAT & 0x80)); //等待发送完成
// SPSTAT = 0xC0; //清除SPI状态位
// return SPDAT; //返回SPI数据
//}
u8 xdata DmaTxBuffer[256]; //_at_ DMA_TX_ADDR;
u8 xdata DmaRxBuffer[256]; //_at_ DMA_RX_ADDR;
bit DmaSPIFlag;
void DMA_SPI_Config(void)
{
P_SW2 = 0x80;
DMA_SPI_STA = 0x00; //清中断
DMA_SPI_CFG = 0xE0; //使能中断,使能接收,使能发送
DMA_SPI_AMT = 127; //设置传输总字节数:n+1
DMA_SPI_TXAH = (u8)((u16)&DmaTxBuffer >> 8); //SPI发送数据存储地址
DMA_SPI_TXAL = (u8)((u16)&DmaTxBuffer);
DMA_SPI_RXAH = (u8)((u16)&DmaRxBuffer >> 8); //SPI接收数据存储地址
DMA_SPI_RXAL = (u8)((u16)&DmaRxBuffer);
DMA_SPI_CFG2 = 0x00; //不自动控制SS脚
DMA_SPI_CR = 0x81; //使能并清除FIFO,但未激活主机或从机模式
}
void DMA_SPI_ISR() interrupt 49
{
DMA_SPI_STA = 0;
DmaSPIFlag = 0;
}
//********************************************************
u8 dss[20];
void main()
{
P_SW2 = 0x80;
P0M0 = 0x00; P0M1 = 0x00;
P1M0 = 0x00; P1M1 = 0x00;
P2M0 = 0x00; P2M1 = 0x00;
P3M0 = 0x00; P3M1 = 0x00;
P4M0 = 0x00; P4M1 = 0x00;
P5M0 = 0x00; P5M1 = 0x00;
W25Q_IO2 = 1; //WP
W25Q_IO3 = 1; //HOLD
EA = 1;
SPI_Config();
DMA_SPI_Config();
//W25Q_Init();
SPI_CS = 0;
SPI_SendByte(0x66);
SPI_SendByte(0x99);
SPI_CS = 1;
memset(DmaTxBuffer,0xFF,sizeof(DmaTxBuffer));
memset(DmaRxBuffer,0xFF,sizeof(DmaRxBuffer));
memset(dss,0xFF,sizeof(dss));
dss[0] = 0x03;//(u8)(0x03); //W25Q标准读指令
dss[1] = 0x08;//(u8)(addr>>16&0x0000FF);
dss[2] = 0x40;//(u8)(addr>>8&0x0000FF);
dss[3] = 0x00;//(u8)(addr&0x0000FF);;
while(1)
{
DmaSPIFlag = 1; //设置标记: 1=忙
//开始传输
SPI_CS = 0;
SPI_WriteNByte(dss,4); //先发送指令给W25Q
DMA_SPI_CR |= 0x40; //B0100 0000开始SPI_DMA主模式操作
while(DmaSPIFlag); //通信完成后DmaSPIFlag=0,,,注意,没有超时处理,此处如错误则无法返回
SPI_CS = 1;
delayms(1000);
}
}
|
|