对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://www.hqwc.cn/news/307608.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

day3双指针

输入一字符串&#xff0c;然后将该字符串中的单词分割开来 #include <iostream> #include <string.h> using namespace std; int main() {char str[1000];gets(str);int nstrlen(str);for(int i0;i<n;i){int ji;while(str[j]! &&j<n) j;for(int ki;k…

ROS仿真R2机器人之安装运行及MoveIt的介绍

R2(Robonaut 2)是NASA美国宇航局与GM通用联合推出的宇航人形机器人&#xff0c;能在国际空间站使用&#xff0c;可想而知其价格是非常昂贵&#xff0c;几百万美刀吧&#xff0c;还好NASA发布了一个R2机器人的Gazebo模型&#xff0c;使用模型就不需要花钱了&#xff0c;由于我们…

进行VMware日志管理

随着公司转向虚拟化其 IT 空间&#xff0c;虚拟环境日志监控正在占据日志管理的很大一部分,除了确保网络安全外&#xff0c;虚拟机日志监控还有助于管理虚拟化工具&#xff0c;这是最复杂的任务之一。 对虚拟环境日志的监控分析 当今公司中最受欢迎的虚拟平台之一是 VMware。…

LVM逻辑卷与扩容

目录 一.LVM&#xff1a; 1.什么是LVM&#xff1a; 2.LVM的基本核心组件&#xff1a; 3.LVM的基本命令&#xff1a; 二.逻辑卷的创建&#xff1a; 第一步&#xff0c;我们先要为虚拟机添加硬盘 然后我们要添加依赖包 然后我们要进行磁盘分区 再添加好分区后&#xff0…

雷军称小米汽车不可能卖 9 万 9;杭州破获重大勒索病毒案丨 RTE 开发者日报 Vol.116

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

Python中matplotlib库的使用1

1 matplotlib库简介 matplotlib是一个数学绘图库&#xff0c;可以将数据通过图形的方式显示出来&#xff0c;也就是数据可视化。 2 matplotlib库的安装 2.1 打开cmd窗口 点击键盘的“Win”“R”键&#xff0c;在弹出的“运行”对话框的“打开”栏中输入“cmd”&#xff0c;…

c语言-string.h库函数初识

目录 前言一、库函数strlen()1.1 strlen()介绍1.2 模拟实现strlen() 二、库函数strcpy()2.1 strcpy()介绍2.2 模拟实现strcpy() 三、库函数strcmp()3.1 strcmp()介绍3.3 模拟实现strcmp() 总结 前言 本篇文章介绍c语言<string.h>头文件中的库函数&#xff0c;包含strlen…

SpringBoot 2 集成Spark 3

前提条件: 运行环境&#xff1a;Hadoop 3.* Spark 3.* ,如果还未安装相关环境&#xff0c;请参考&#xff1a; Spark 初始 CentOS 7 安装Hadoop 3 单机版 SpringBoot 2 集成Spark 3 pom.xml <?xml version"1.0" encoding"UTF-8"?> <pro…

通用搜索的工作原理

了解 Google 的通用搜索结果为何如此重要&#xff0c;通用搜索的发展方向&#xff0c;以及它对您意味着什么。 让我们从回答一个显而易见的问题开始&#xff1a; 什么是通用搜索&#xff1f; 网络上有一些通用搜索的定义&#xff0c;但我更喜欢从马的嘴里听到这样的事情。 …

电商数据分析-03-电商数据采集

参考 最最最全数据仓库建设指南&#xff0c;速速收藏&#xff01;&#xff01; 第1章 数据仓库概念 数据仓库规划 1.1 数仓搭建 我们这里所说的数据仓库&#xff0c;是基于大数据体系的&#xff0c;里面包含标签类目&#xff0c;区别于传统的数据仓库。下面我们来将这张图分解…

openmediavault(OMV) (17)云相册(1)piwigo

简介 Piwigo是一种开源的在线照片库管理系统,它允许你创建和分享个人或团体的图像库。以下是关于Piwigo的一些特点: 图片管理:Piwigo提供了一个功能丰富的管理界面,用于上传、组织、标记和编辑图片。你可以通过文件夹结构或使用标签、关键字等方式来组织和分类你的照片。…

如何在 Linux 中配置 firewalld 规则

什么是FirewallD “firewalld”是firewall daemon。它提供了一个动态管理的防火墙&#xff0c;带有一个非常强大的过滤系统&#xff0c;称为 Netfilter&#xff0c;由 Linux 内核提供。 FirewallD 使用zones和services的概念&#xff0c;而 iptables 使用chain和rules。与 ip…