对SPI总线上挂接多个X5045的读写操作

#include<reg51.h>    //包含单片机寄存器的头文件
#include<intrins.h>  //包含_nop_()函数定义的头文件
sbit SCK=P3^4;       //将SCK位定义为P3.4引脚
sbit SI=P3^5;        //将SI位定义为P3.5引脚
sbit SO=P3^6;        //将SO位定义为P3.6引脚
sbit CS1=P3^7;        //将CS定义为P3.7引脚
sbit CS2=P3^3;        //将CS1位定义为P3.7引脚
#define WREN 0x06    //写使能锁存器允许
#define WRDI 0x04    //写使能锁存器禁止
#define READ 0x03    //读出
#define WRITE 0x02   //写入
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay1ms()
{
   unsigned char i,j;    
     for(i=0;i<10;i++)
      for(j=0;j<33;j++)
       ;         
 }
 /*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
 void delaynms(unsigned char n)
 {
   unsigned char i;
    for(i=0;i<n;i++)
       delay1ms();
 }
/*****************************************************
函数功能:从X5045的当前地址读出数据
出口参数:x
***************************************************/
unsigned char ReadCurrent(void)
{
      unsigned char i;
    unsigned char x=0x00;      //储存从X5045中读出的数据
    SCK=1;                     //将SCK置于已知的高电平状态
   for(i = 0; i < 8; i++)
    {
       SCK=1;                 //拉高SCK
       SCK=0;                 //在SCK的下降沿输出数据    
       x<<=1;  //将x中的各二进位向左移一位,因为首先读出的是字节的最高位数据       
        x|=(unsigned char)SO;  //将SO上的数据通过按位“或“运算存入 x      
    }
    return(x);   //将读取的数据返回
 }
/*****************************************************
函数功能:写数据到X5045的当前地址
入口参数:dat
***************************************************/
void WriteCurrent(unsigned char dat)
{
   unsigned char i;
    SCK=0;                 //将SCK置于已知的低电平状态
  for(i = 0; i < 8; i++)  // 循环移入8个位
    {
     SI=(bit)(dat&0x80);   //通过按位“与”运算将最高位数据送到S
                            //因为传送时高位在前,低位在后
     SCK=0;
     SCK=1;               //在SCK上升沿写入数据
    dat<<=1;   //将y中的各二进位向左移一位,因为首先写入的是字节的最高位
  }
}
/*****************************************************
函数功能:写数据到第一个X5045的指定地址
入口参数:addr
***************************************************/
void WriteSet1(unsigned char dat,unsigned char addr)
{
   CS2=1;                 //使第二个X5045的片选无效
   SCK=0;                 //将SCK置于已知状态
   CS1=0;                  //拉低CS,选中X5045
    WriteCurrent(WREN);    //写使能锁存器允许
    CS1=1;                  //拉高CS
   CS1=0;                  //重新拉低CS,否则下面的写入指令将被丢弃
    WriteCurrent(WRITE);   //写入指令
    WriteCurrent(addr);    //写入指定地址
    WriteCurrent(dat);     //写入数据
    CS1=1;                  //拉高CS
   SCK=0;                 //将SCK置于已知状态
}
/*****************************************************
函数功能:写数据到第二个X5045的指定地址
入口参数:addr
***************************************************/
void WriteSet2(unsigned char dat,unsigned char addr)
{
   CS1=1;                 //使第一个X5045的片选无效
   SCK=0;                 //将SCK置于已知状态
   CS2=0;                  //拉低CS,选中X5045
    WriteCurrent(WREN);    //写使能锁存器允许
    CS2=1;                  //拉高CS
   CS2=0;                  //重新拉低CS,否则下面的写入指令将被丢弃
    WriteCurrent(WRITE);   //写入指令
    WriteCurrent(addr);    //写入指定地址
    WriteCurrent(dat);     //写入数据
    CS2=1;                  //拉高CS
   SCK=0;                 //将SCK置于已知状态
}

/*****************************************************
函数功能:从第一个X5045的指定地址读出数据
入口参数:addr
出口参数:dat
***************************************************/
unsigned char ReadSet1(unsigned char addr)
{
 unsigned char dat;
 CS2=1;                 //使第二个X5045的片选无效
 SCK=0;                 //将SCK置于已知状态
 CS1=0;                  //拉低CS,选中X5045
 WriteCurrent(READ);   //开始读
 WriteCurrent(addr);   //写入指定地址
 dat=ReadCurrent();    //读出数据
 CS1=1;                 //拉高CS
 SCK=0;                //将SCK置于已知状态
 return dat;           //返回读出的数据
 }
/*****************************************************
函数功能:从第二个X5045的指定地址读出数据
入口参数:addr
出口参数:dat
***************************************************/
unsigned char ReadSet2(unsigned char addr)
{
 unsigned char dat;
 CS1=1;                 //使第一个X5045的片选无效
 SCK=0;                 //将SCK置于已知状态
 CS2=0;                 //拉低CS,选中X5045
 WriteCurrent(READ);   //开始读
 WriteCurrent(addr);   //写入指定地址
 dat=ReadCurrent();    //读出数据
 CS2=1;                //拉高CS
 SCK=0;                //将SCK置于已知状态
 return dat;           //返回读出的数据
 }
/*****************************************************
函数功能:看门狗复位程序
***************************************************/
void WatchDog1(void)
{
 CS1=1;    //拉高CS
 CS1=0;    //CS引脚的一个下降沿复位看门狗定时器
 CS1=1;    //拉高CS
}
/*****************************************************
函数功能:看门狗复位程序
***************************************************/
void WatchDog2(void)
{
 CS2=1;    //拉高CS
 CS2=0;    //CS引脚的一个下降沿复位看门狗定时器
 CS2=1;    //拉高CS
}

/*****************************************************
函数功能:主程序
***************************************************/
void main(void)

  unsigned char x;
  while(1)
  {
      WriteSet1(0xf0,0x10);   //将数据“0xaa”写入第一个X5045的指定地址“0x10”
      delaynms(10);           //X5045的写入周期为约10ms
      x=ReadSet1(0x10);       //将数据从第一个X5045中的指定地址读出来
      WriteSet2(x,0x20);     //将数据x写入第二个X5045的指定地址“0x20
      delaynms(10);          //X5045的写入周期为约10ms
      P1=ReadSet2(0x20);     //将数据从第二个X5045中的指定地址读出来,送P1口显示
      delaynms(100);         //延时100ms
      WatchDog1();          //复位第一个X5045的看门狗   
      WatchDog2();          //复位第二个X5045的看门狗   
  } 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2662333.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Linux中磁盘管理与文件系统

目录 一.磁盘基础&#xff1a; 1.磁盘的结构&#xff1a; 2.硬盘的数据结构&#xff1a; 3.硬盘存储容量 &#xff1a; 4.硬盘接口类型&#xff1a; 二.MBR与磁盘分区&#xff1a; 1.MBR的概念&#xff1a; 2.硬盘的分区&#xff1a; 为什么分区&#xff1a; 2.表示&am…

光电耦合器:什么是隔离放大器

隔离放大器是现代电子系统中的关键组件&#xff0c;在维持信号完整性和确保敏感设备的安全方面发挥着关键作用。隔离放大器采用的关键技术之一是光耦合器&#xff0c;这是一种设计用于传输信号同时电隔离输入和输出电路的器件。在本文中&#xff0c;我们深入研究隔离放大器领域…

Python之类方法、__new__方法和__init__方法介绍

在编程语言中创建一个类&#xff0c;有构造方法这样的一个术语。而在Python中&#xff0c;通常大家都认为__init__是构造方法&#xff0c;其实并不完全等同。在构建类中&#xff0c;有一个特殊的方法__new__&#xff0c;这个才能等同为构造方法。 __new__是一个类方法&#xff…

UniApp微信小程序使用echarts图标教程(附源码)

在项目中直接使用echarts时&#xff0c;H5端是OK的&#xff0c;但微信小程序会报错&#xff0c;所以来看一下如何在微信小程序中使用echarts 1.打开链接&#xff0c;下载第一个 下载链接 注意看 此时这个版本是5.3.3 2.官网在线定制&#xff0c;下载下来 注意与版本 等待下载…

10、RabbitMQ高频面试题

1、你们项目中哪里用到了RabbitMQ RabbitMQ是我们项目中服务通信的主要方式之一 , 我们项目中服务通信主要有二种方式实现 : 通过Feign实现服务的同步调用通过MQ实现服务的异步通信 下面要结合自己的项目中功能来说两个地方 xxx xxx 2、为什么会选择使用RabbitMQ 我们项…

k8s搭建(四、k8s集群创建)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

一篇文章掌握 NestJS 所有的生命周期以及生命周期的执行时机

前言 NestJS 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的框架&#xff0c;它使用 TypeScript 作为开发语言&#xff0c;也支持原生的 JavaScript。在 NestJS 中&#xff0c;生命周期事件是一个重要的概念。在我们构建和管理应用程序时&#xff0c;有时需要在特定…

Fiori Launchpad Error Unable to load groups

进入launchpad 报错如上 输入事务代码 /IWFND/ERROR_LOG 查看错误日志 输入事务代码&#xff1a;/N/IWFND/MAINT_SERVICE 设置filter 如下 选中服务点击添加系统别名--》 点击 新条目 输入如下&#xff1a; 我这个问题还有一个报错处理方法相同 完成上述操作之后&#xf…

Typora使用PicGo+Gitee上传图片报错403 Forbidden

Typora使用PicGoGitee上传图片报错403 Forbidden Typora使用PicGoGitee上传图片&#xff0c;上传失败了&#xff0c;错误信息如下 打开PicGo的日志文件查看&#xff0c;可以看到错误详情如下 换了一个插件github-plus重新配置&#xff0c;解决了这个问题 再打开日志查看&…

Git 浅入浅出

前提 最近和同事分模块联合开发代码&#xff0c;自然而然就要用到 Git 管理代码&#xff1b;借此机会&#xff0c;对 Git 进行简单介绍。 Git 的特征 文件系统 我们都知道 Git 是个版本控制系统&#xff0c;但是如果你深入了解其原理&#xff0c;就不难发现它更像一个文件管…

快速解决找不到msvcp120.dll的五个方法,dll文件修复方法

本文将详细介绍msvcr120.dll文件的相关知识&#xff0c;并提供五种解决msvcr120.dll缺失的方法。 一、msvcr120.dll是什么文件和msvcr120.dll的作用是什么介绍 msvcr120.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;它是运行许多基于Windows操作系统…

【js自定义鼠标样式】【js自定义鼠标动画】

文章目录 前言一、效果图二、实现步骤1. 去除原有鼠标样式2. 自定义鼠标样式3. 使用 总结 前言 自定义鼠标形状&#xff0c;自定义鼠标的动画&#xff0c;可以让我们的页面更加有设计感。 当前需求&#xff1a;吧鼠标自定义成一个正方形&#xff0c;鼠标的效果有&#xff1a;和…

sysbench

一、sysbench介绍 1、sysbench简介 sysBench是一个模块化的、跨平台、多线程基准测试工具&#xff0c;主要用于评估测试各种不同系统参数下的数据库负载情况。sysbench提供如下测试&#xff1a; &#xff08;1&#xff09;CPU性能 &#xff08;2&#xff09;磁盘IO性能 &…

SourceTree的安装和使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、安装&#xff1a;二、使用步骤1.获取地址2.放入sourceTree 3.点击推送 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 简单讲解一…

Vue - 实现文件导出文件保存下载

1 文件导出&#xff1a;使用XLSX插件 需求背景&#xff1a;纯前端导出&#xff0c;如 在前端页面勾选部分表格数据&#xff0c;点击"导出"按钮导出Excel文件。 实现思路&#xff1a; 1.通过XLSX插件的 XLSX.utils.book_new()方法&#xff0c;创建excel工作蒲对象wb…

既然前端工程师可以进腾讯字节阿里等大厂,为什么要高薪进小公司?

前言 前不久后台有一个粉丝给我留言&#xff1a;为什么很多人参加校招的时候&#xff0c;宁愿低薪也要进大厂&#xff0c;而不选择更高薪的小公司呢&#xff1f; &#xff08;文末有惊喜&#xff01;文末有惊喜&#xff01;&#xff09; 我想了一下&#xff0c;大概是有3个原因…

6130 树的最长路

思路&#xff1a;树的最长路问题可以通过两次 DFS 求解&#xff0c;具体思路如下&#xff1a; 1.第一次 DFS 求树的直径 以任意一个点为起点进行深度优先遍历&#xff08;DFS&#xff09;&#xff0c;找到与该点距离最远的点 u 。 以 u 为起点进行 DFS &#xff0c;找到与 u 距…

win10系统gpu本地部署chatglm3-6b,从0开始安装

开源地址&#xff1a; GitHub - THUDM/ChatGLM3: ChatGLM3 series: Open Bilingual Chat LLMs | 开源双语对话语言模型 前言&#xff1a;ChatGLM2与ChatGLM3区别 ChatGLM2与ChatGLM3模型架构是完全一致的&#xff0c;ChatGLM与后继者结构不同。可见ChatGLM3相对于ChatGLM2没…

LabVIEW在电机噪声与振动探测的应用

LabVIEW在电机噪声与振动探测的应用 硬件部分是电机噪声和振动测试分析系统的基础&#xff0c;主要由三大核心组件构成&#xff1a;高灵敏度振动传感器、先进的信号调理电路和高性能数据采集卡。这些设备协同工作&#xff0c;确保了从电机捕获的噪声和振动信号的准确性和可靠性…

盲盒电商:重塑消费者行为与市场格局

一、什么是盲盒电商&#xff1f; 盲盒电商是一种新型的电子商务模式&#xff0c;它通过将商品隐藏在盲盒中&#xff0c;让消费者在购买时无法知道具体商品&#xff0c;只能通过猜测和期待来体验购物的乐趣。这种模式在年轻人中非常受欢迎&#xff0c;因为它提供了一种全新的购…