/***************************************************************************
* 文件名:sd.c
* 功 能:sd 卡扇区的读写
* 作 者:TXMCU
* 日 期:
* 备 注:
//软件思路:1、SD卡采用SPI通信协议
// 2、先往SD里顺序写入0-255-0共512个数据,然后等待按键key0按下后,读
// 数据送回数码管显示
//开发板连接方法:将JP10 JP11 JP12 JP13这4个跳线帽分别接到sd card位置
// 把JP8的的跳线帽跳到DPY位置上,JP14选择在IO口位置上
****************************************************************************/
#include<pic.h> //调用头文件
__CONFIG(0x1832);
#define cs RC2 //定义SD卡片选脚
//0-9显示代码表格
const unsigned char TABLE[] = {0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0x6f};
void spi_init(); //申明系统初始函数
void spi_low(); //申明产生低波特率函数(SD卡初始化使用)
void spi_high(); //申明产生高波特率函数(SD卡初始化后使用)
unsigned char sd_reset(); //申明SD卡初始化函数
unsigned char SD_SendCommand(unsigned char cmd, unsigned long arg); //申明写SD卡命令函数
unsigned char SPI_WriteByte(unsigned char val); //申明写一字节函数
unsigned char SPI_ReadByte(void); //申明接收一字节函数
unsigned char SD_WriteSingleBlock(unsigned long sector); //申明写SD卡单BLOCK数据函数
unsigned char SD_ReadSingleBlock(unsigned long sector); //申明读SD卡单BLOCK数据函数
void display(unsigned char temp); //申明结果显示函数
void delay(); //申明延时函数(显示时用)
/****************************************************************************
* 名 称:
* 功 能:主函数
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
void main()
{
unsigned char loop, res;
delay();
delay();
delay();
loop = 1;
TRISB = 0X03;
cs = 1;
while (loop)
{
spi_init(); //调用系统初始化函数
res = sd_reset(); //调用SD卡初始化函数
if (res) break; //SD卡初始化是否正常,不正常,退出循环,不执行下面的读写操作
SD_WriteSingleBlock(1); //调用写SD卡单BLOCK函数,其中扇区号为1
if (res) break;
while(RB0); //等大key0被按下
SD_ReadSingleBlock(1); //调用读SD卡单BLOCK函数,其中扇区号为1
if (res) break;
loop = 0;
RC1 = 0;
while (1);
}
RC0 = 1;
while (1);
}
/****************************************************************************
* 名 称:spi_init()
* 功 能:系统初始化
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
void spi_init()
{
TRISC = 0xd0; //设置SDI为输出,其他C口为输出
TRISD = 0X00; //设置D口为输出
TRISA = 0X00; //设置A口为输出
ADCON1 = 0X07; //设置A口为普通数字口
SSPCON = 0x31; //空闲时总线为高电平,fosc/64
SSPSTAT = 0x80; // 输出数据的末尾采样输入数据,上升沿发送数据
RC0 = 0;
RC1 = 0;
PORTA = 0XFF;
}
/****************************************************************************
* 名 称:spi_low()
* 功 能:设置低波特率
* 入口参数:
* 出口参数:
* 说 明:(SD卡初始化时用)
****************************************************************************/
void spi_low()
{
SSPCON = 0x31; //SPI时钟选用系统时钟的fosc/64
}
/****************************************************************************
* 名 称:spi_high()
* 功 能:设置高波特率
* 入口参数:
* 出口参数:
* 说 明:(SD卡初始化后使用)
****************************************************************************/
void spi_high()
{
// SSPCON=0x31; //SPI时钟选用系统时钟的fosc/16
SSPCON = 0X30;
}
/****************************************************************************
* 名 称:SPI_WriteByte
* 功 能:写一字节到sd卡
* 入口参数:unsigned char val 要写的数据
* 出口参数:
* 说 明:
****************************************************************************/
unsigned char SPI_WriteByte(unsigned char val)
{
SSPBUF = val; //待发送数据装载到发送寄存器
while (!SSPIF); //等待发送完成
SSPIF = 0; //清除发送完成标志位
return SSPBUF; //读取接收寄存器(即使是无效数据也需清空)
}
/****************************************************************************
* 名 称:SPI_ReadByte()
* 功 能:接收一字节
* 入口参数:
* 出口参数:
* 说 明:
****************************************************************************/
unsigned char SPI_ReadByte(void)
{
SSPBUF = 0xff; //发送寄存器装载数据,以启动数据接收
while (!SSPIF); //等待接收完成
SSPIF = 0; //清除接收完成标志位
return SSPBUF; //读取接收到的数据
}
/****************************************************************************
* 名 称:SD_SendCommand()
* 功 能:向sd发送命令
* 入口参数:unsigned char cmd 命令, unsigned long arg 参数
* 出口参数:
* 说 明:
****************************************************************************/
unsigned char SD_SendCommand(unsigned char cmd, unsigned long arg)
{
unsigned char r1;
unsigned char retry1 = 0; //重复操作次数
cs = 0; //使能片选信号
SPI_WriteByte(cmd | 0x40); //分别写入命令
SPI_WriteByte(arg >> 24); //数据段第4字节
SPI_WriteByte(arg >> 16); //数据段第3字节
SPI_WriteByte(arg >> 8); //数据段第2字节
SPI_WriteByte(arg); //数据段第1字节
SPI_WriteByte(0x95); //CRC效验和
while ((r1 = SPI_WriteByte(0xff)) == 0xff) //等待响应
if (retry1++ > 200) break; //超时退出
cs = 1; //清初片选信号
return r1; //返回状态值
}
/****************************************************************************
* 名 称: sd_reset()
* 功 能:SD卡初始化
* 入口参数:
* 出口参数:0-正确 1-错误
* 说 明:
****************************************************************************/
unsigned char sd_reset()
{
unsigned char i;
unsigned char retry; //重复次数
unsigned char r1 = 0;
retry = 0;
delay();
delay();
spi_low(); //使用低速初始化
do
{
for (i = 0;i < 100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(0, 0); //发idle命令
retry++;
if (retry > 20) return 1; //超时退出
}
while (r1 != 0x01); //等待IDLE命令返回
retry = 0;
cs = 0;
do
{
for (i = 0;i < 100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(1, 0); //发Active命令
retry++;
if (retry > 254) return 1; //超时退出
}
while (r1);
spi_high(); //使用高波特率
for (i = 0;i < 100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(59, 0); //关crc
if (r1) return 1; //返回不正确,退出初始化
for (i = 0;i < 100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(16, 512); //设扇区大小512
if (r1 != 0) return 1; //返回不正确,退出初始化
return 0; //正常返回
}
/****************************************************************************
* 名 称:SD_WriteSingleBlock()
* 功 能:写一个扇区
* 入口参数:unsigned long sector 扇区号
* 出口参数:0-写入正确 1-失败
* 说 明:
****************************************************************************/
unsigned char SD_WriteSingleBlock(unsigned long sector)
{
unsigned char r1;
unsigned int i;
unsigned char retry = 0;
spi_low();
do
{
for (i = 0;i < 100;i++) SPI_WriteByte(0xff);
r1 = SD_SendCommand(24, sector << 9); //写命令
retry++;
if (retry > 10) return 1;
sd.zip_pic16f877a sd
版权申诉
7 浏览量
2022-09-24
20:52:06
上传
评论
收藏 3KB ZIP 举报
我虽横行却不霸道
- 粉丝: 73
- 资源: 1万+
最新资源
- 解析机器人_安卓.apk
- 基于matlab实现的关于雷达恒虚警检测一些问题的程序仿真.rar
- 基于matlab实现的函数-对滑动轴承由油膜剪切力产生的摩擦力用matlab进行求解.rar
- 基于matlab实现的滑动轴承的雷诺方程求解与偏心率和承载能力的关系.rar
- 整理2010-2020年各省农村居民消费价格指数
- 基于matlab实现的基于粒子群算法的交通路径研究matlab源程序时间窗车辆路径规划PSO-VRPTW.rar
- 基于matlab实现的雷达的恒虚警检测技术,二维cfar,采用十字形取数法.rar
- 基于matlab实现的雷达的恒虚警检测程序,这里你可以进行雷达信号的恒虚警检测.rar
- 基于matlab实现的雷达CFAR恒虚警检测二维信号仿真
- 基于matlab实现的计算无量纲非线性油膜力,无量纲形势的函数,易于调用,滚动轴承支撑的碰磨转子.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈