哈尔滨网站制作哪家好薇,wordpress改织梦,北京网站建设找德冿朴,一家只做正品的网站单片机——SPI总线 宗旨#xff1a;技术的学习是有限的#xff0c;分享的精神是无限的。 UART、 I2C 和 SPI 是单片机系统中最常用的三种通信协议。
1、初步介绍 SPI 是一种高速的、全双工、同步通信总线#xff0c;标准的 SPI 也仅仅使用 4 个引脚#xff0c;常用于单片…单片机——SPI总线 宗旨技术的学习是有限的分享的精神是无限的。 UART、 I2C 和 SPI 是单片机系统中最常用的三种通信协议。
1、初步介绍 SPI 是一种高速的、全双工、同步通信总线标准的 SPI 也仅仅使用 4 个引脚常用于单片机和 EEPROM、FLASH、实时时钟、数字信号处理器等器件的通信。 SPI 通信原理比 I2C要简单它主要是主从方式通信这种模式通常只有一个主机和一个或者多个从机标准的 SPI 是 4 根线分别是 SSEL 片选也写作 SCS、 SCLK 时钟也写作 SCK、 MOSI 主机输出从机输入Master Output/Slave Input 和 MISO 主机输入从机输出 Master Input/Slave Output。 SSEL从设备片选使能信号。如果从设备是低电平使能的话当拉低这个引脚后从设备就会被选中主机和这个被选中的从机进行通信。SCLK时钟信号由主机产生和 I2C通信的 SCL 有点类似。MOSI主机给从机发送指令或者数据的通道。MISO主机读取从机的状态或者数据的通道。 2、工作模式 SPI 通信的主机也是我们的单片机在读写数据时序的过程中有四种模式 CPOL:Clock Polarity就是时钟的极性。通信的整个过程分为空闲时刻和通信时刻 如果 SCLK 在数据发送之前和之后的空闲状态是高电平 那么就是CPOL1如果空闲状态SCLK 是低电平那么就是 CPOL0。 CPHA: Clock Phase就是时钟的相位。 #includereg52.htypedef unsigned char uchar;sbit DS1302_CE P1 ^ 7;
sbit DS1302_CK P3 ^ 5;
sbit DS1302_IO P3 ^ 4;struct sTime //日期时间结构体定义
{unsigned int year; //年unsigned char mon; //月unsigned char day; //日unsigned char hour; //时unsigned char min; //分unsigned char sec; //秒unsigned char week; //星期
};/* 发送一个字节到DS1302通信总线上*/
void DS1302ByteWrite(uchar dat)
{uchar mask;for (mask 0x01; mask ! 0; mask 1) //低位在前逐位移出{if ((mask dat) ! 0) //首先输出该位数据{DS1302_IO 1;}else{DS1302_IO 0;}DS1302_CK 1; //然后拉高时钟DS1302_CK 0; //再拉低时钟完成一个位的操作}DS1302_IO 1; //最后确保释放IO引脚
}
/* 由DS1302通信总线上读取一个字节*/
uchar DS1302ByteRead()
{uchar mask;uchar dat 0;for (mask 0x01; mask ! 0; mask 1) //低位在前逐位读取{if (DS1302_IO ! 0) //首先读取此时的IO引脚并设置dat中的对应位{dat | mask;}DS1302_CK 1; //然后拉高时钟DS1302_CK 0; //再拉低时钟完成一个位的操作}return dat; //最后返回读到的字节数据
}
/* 用单次写操作向某一寄存器写入一个字节reg-寄存器地址dat-待写入字节*/
void DS1302SingleWrite(uchar reg, uchar dat)
{DS1302_CE 1; //使能片选信号DS1302ByteWrite((reg 1) | 0x80); //发送写寄存器指令DS1302ByteWrite(dat); //写入字节数据DS1302_CE 0; //除能片选信号
}
/* 用单次读操作从某一寄存器读取一个字节reg-寄存器地址返回值-读到的字节*/
uchar DS1302SingleRead(uchar reg)
{uchar dat;DS1302_CE 1; //使能片选信号DS1302ByteWrite((reg 1) | 0x81); //发送读寄存器指令dat DS1302ByteRead(); //读取字节数据DS1302_CE 0; //除能片选信号return dat;
}
/* 用突发模式连续写入8个寄存器数据dat-待写入数据指针*/
void DS1302BurstWrite(uchar *dat)
{uchar i;DS1302_CE 1;DS1302ByteWrite(0xBE); //发送突发写寄存器指令for (i 0; i 8; i) //连续写入8字节数据{DS1302ByteWrite(dat[i]);}DS1302_CE 0;
}
/* 用突发模式连续读取8个寄存器的数据dat-读取数据的接收指针*/
void DS1302BurstRead(uchar *dat)
{uchar i;DS1302_CE 1;DS1302ByteWrite(0xBF); //发送突发读寄存器指令for (i 0; i 8; i) //连续读取8个字节{dat[i] DS1302ByteRead();}DS1302_CE 0;
}
/* 获取实时时间即读取DS1302当前时间并转换为时间结构体格式*/
void GetRealTime(struct sTime *time)
{uchar buf[8];DS1302BurstRead(buf);time-year buf[6] 0x2000;time-mon buf[4];time-day buf[3];time-hour buf[2];time-min buf[1];time-sec buf[0];time-week buf[5];
}
/* 设定实时时间时间结构体格式的设定时间转换为数组并写入DS1302*/
void SetRealTime(struct sTime *time)
{uchar buf[8];buf[7] 0;buf[6] time-year;buf[5] time-week;buf[4] time-mon;buf[3] time-day;buf[2] time-hour;buf[1] time-min;buf[0] time-sec;DS1302BurstWrite(buf);
}
/* DS1302初始化如发生掉电则重新设置初始时间*/
void InitDS1302()
{uchar dat;struct sTime code InitTime[] //2016年5月18日9:00:00 星期二{0x2016, 0x05, 0x18, 0x09, 0x00, 0x00, 0x02};DS1302_CE 0; //初始化DS1302通信引脚DS1302_CK 0;dat DS1302SingleRead(0); //读取秒寄存器if ((dat 0x80) ! 0) //由秒寄存器最高位CH的值判断DS1302是否已停止{DS1302SingleWrite(7, 0x00); //撤销写保护以允许写入数据SetRealTime(InitTime); //设置DS1302为默认的初始时间}
}