模拟SPI程序

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。


// **********************************************************
// 1. 8位发送, 高位在前, 上升沿输出数据
// 参数分别为: data: 要写的数据
// **********************************************************
void spi8_msb_out(unsigned char data)
{
unsigned char c;
for(c = 0; c < 8; c++)
{
CLR_SPI_CLK; // 时钟输出 0
if(data & BIT7)
SET_SPI_OUT; // 输出 1
else
CLR_SPI_OUT; // 输出 0
SET_SPI_CLK; // 时钟输出1, 上升沿 发送一位
data <<= 1; // 待发送数据左移一位,使待发送位移到bit7
}
return;
}

// **********************************************************
// 2. 8位接收, 高位在前, 下降沿输入数据
// 数据返回: data: 读取的数据
// **********************************************************
u8 spi8_msb_in(u8 spinum)
{
u8 c, data;
for(c = 0; c < 8; c++)
{
CLR_SPI_CLK; // 时钟输出 0, 下降沿接收一位
data <<= 1; // 将接收到的数据左移一位, 使bit0空出来,以便接收下一位

if(SPI0_IN != 0) // SPI0_IN为io口状态检测
data |= BIT0; // 接收 1
else
data &= ~BIT0; // 接收 0

SET_SPI_CLK; // 时钟输出1
}
return data;
}

// **********************************************************
// 3. 用于 FM25系列的读数据子程序
// 参数分别为: address:要读的数据在存储器中的首地址
// nums: 要读的字节数
// buf: 读取的数据保存的缓冲区地址
// **********************************************************

void fram_read(u16 address, u16 nums, u8 * buf)
{
u16 i;
if(address > MAX_ADDRESS)
return;
if(nums == 0)
return;
_DINT();
SPI_ALL_DESELECT; // 禁止所有SPI器件
SPI_PORT_INIT; // SPI口初始化
SPI_F1_SELECT; // 片选
spi8_msb_out(READ_CMD); // 读数据命令 8位
spi16_msb_out(address); // 写 16位 地址
for(i = 0; i < nums; i++)
buf[i] = spi8_msb_in(1); // 读取数据
SPI_F1_DESELECT; // 关片选
_EINT();
return;
}

// **********************************************************
// 8. 用于 FM25系列的写数据子程序
// 参数分别为: address:数据要写到存储器中的首地址
// nums: 要写的字节数
// buf: 要写的数据保存的缓冲区地址
// **********************************************************
void fram_write(u16 address, u16 nums, u8 * buf)
{
u16 i;
if(address > MAX_ADDRESS) // 大于FRAM地址,判断为错误,返回
return;
if(nums == 0)

// 读出字节数为零,判断为错误,返回
return;
_DINT();
SPI_ALL_DESELECT; // 禁止所有SPI器件
SPI_PORT_INIT; // SPI口初始化
SPI_F1_SELECT; // 片选
spi8_msb_out(RDST_CMD); // 读状态字命令
i = spi8_msb_in(1); // 接收一字节数据
SPI_F1_DESELECT; // 关片选
if(i != 0x00) // 状态字为0,才完全没有写保护
{
SPI_F1_SELECT; // 片选
spi8_msb_out(WREN_CMD); // 设置存储器 写允许
SPI_F1_DESELECT; // 关片选
SPI_F1_SELECT; // 片选
spi8_msb_out(WRST_CMD); // 写状态字命令
spi8_msb_out(0x00); // 清0状态字
SPI_F1_DESELECT; // 关片选
// 读状态字
// 写完状态字后,(即CE由低变高),铁电存储器自动进入写禁止状态,(即WEL位(bit1)自动变为0)
// 因此读出的状态字应为0x00
SPI_F1_SELECT; // 片选
spi8_msb_out(RDST_CMD); // 读状态字命令
i = spi8_msb_in(1); // 接收一字节数据
SPI_F1_DESELECT; // 关片选
if(i != 0x00)
{
_EINT();
cError |= E_MEMORY_F;// 铁电存储器 故障
return;
}
}
// 写允许 - 发送写允许命令后,状态字将变为 0x02
SPI_F1_SELECT; // 片选
spi8_msb_out(WREN_CMD); // 设置存储器写允许
SPI_F1_DESELECT; // 关片选
// 写数据
SPI_F1_SELECT; // 片选
spi8_msb_out(WRITE_CMD); // 写数据命令
spi16_msb_out(address); // 写 16位 地址
for(i = 0; i < nums; i++)
spi8_msb_out(buf[i]); // 写数据
SPI_F1_DESELECT; // 关片选
cError &= ~E_MEMORY_F; // 清 铁电存储器 故障
_EINT();
return;
}

相关文档
最新文档