魔将の贽cg:基于proteus的51单片机仿真实例八十三 - PROTEUS技术交流区 - PROTE...

来源:百度文库 编辑:九乡新闻网 时间:2024/05/02 07:30:17

基于proteus的51单片机仿真实例八十三

proteus, 单片机, 实例, 仿真 1、SPI总线器件与单片机的连接需要3跟线:时钟线SCK,数据线MOSI(主机发送,从机接收)和MISO(主机接收,从机发送)。
X5045是一种集合了看门狗、电压监控和串行EEPROM三种功能于一身的器件。
下载 (8.78 KB)
2010-5-13 19:59
上电复位功能:在系统上电时产生一个足够长时间的复位信号,以确保单片机正常工作前,系统电路已处于稳定状态。
看门狗功能:如果在规定的时间内单片机没有在CS引脚产生规定的电平变化(喂狗信号),芯片内的看门狗电路将产生复位信号。利用该功能,可让单片机死机后自动复位并开始工作。
电压检测:当电源电压下降到一定的值后,虽然单片机仍能工作,但可能已经不能稳定工作了,此时X5045将产生复位信号,直到电压恢复正常后,才能正常工作。
串行EEPROM:X5045自带512字节的数据存储空间,数据可掉电保存。

2、x5045的引脚及功能
CS/WDI:片选输入端。低电平时选中该芯片
SO:串行数据输出端,数据在sck的下降沿输出
WP:写保护端,该脚接地,写操作被禁止,接高电平,所有功能正常
VSS:电源地
SI:串行数据输入端,数据在sck的上升沿写入(高位在前)
SCK:串行时钟端,
RESET:复位输出端,用于电源监测和看门狗超时输出
VCC:电源

3、使用方法
1)上电复位:当器件通电并超过规定值时,X5045内部的复位电路将会产生一个约200ms的复位脉冲,使单片机正常复位。
2)电压检测:工作过程中,X5045能不断检测VCC端的电压,在电压下降到一定值后,将产生一个复位脉冲,使单片机停止工作,这个复位脉冲一直有效,直到VCC下降到1V以下,整个系统停止工作。如果VCC在下降后又升高,则当超过规定值后200ms,复位信号消失,单片机可以继续工作。
3)看门狗定时器:看门狗定时器电路通过检测WDI端的输入来判断单片机工作是否正常,在规定的时间内,单片机必须在WDI端口产生一个由高到低的电平变化。否则,X5045将产生一个复位信号。
4)SPI总线串行EEPROM,EEPROM除了可以由WP引脚置高电平保护外,还可以通过软件保护,通过设置X5045的状态寄存器可以改变看门狗定时器的定时周期和被保护块的大小。
在写操作之前,先要检测WIP标志位,WIP=1表示X5045正忙于向EEPROM写数据,此时不能向X5045写数据,WIP= 0表示可以向X5045写数据。WEL为写使能锁存器的状态位。WEL=1表示允许写,WEL=0表示禁止写。
5)芯片操作:X5045有6条操作指令,所有的指令、地址和数据都是以高位在前的方式传送的,输入的数据在CS变为低电平后的第一个上升沿被采样。
向存储器写入数据的协议:首先将CS拉低以选中芯片,然后写入WREN(写允许)指令,接着将CS拉高,然后再次将CS拉低,随后写入WRITE指令。WRITE指令的第3位用于确定存储器的上半区和下半区。如果没有在WREN和WRITE两个指令之间将CS的信号变为低电平,WRITE指令将被忽略。最后需要将CD的信号变为高电平。
从存储器读出数据的协议:首先将CS拉低以选中该芯片,然后写入READ(读出)指令,READ指令的第3位用于确定存储器的上半区和下半区。在读操作指令和地址码发送完毕后,所选中地址单元的数据将通过引脚SO送出,最后须将CS拉高。

4、在keil c51中新建工程ex71,编写如下程序代码,编译并生成ex71.hex文件
//将一字节数据写入X5045再读出,然后送送P1口显示
#include    //包含单片机寄存器的头文件
#include  //包含_nop_()函数定义的头文件
//x5045引脚定义
sbit SCK=P3^4;       //将SCK位定义为P3.4引脚
sbit SI=P3^5;        //将SI位定义为P3.5引脚
sbit SO=P3^6;        //将SO位定义为P3.6引脚
sbit CS=P3^7;        //将SCK位定义为P3.7引脚
//功能变量定义
#define WREN 0x06    //写使能锁存器允许
#define WRDI 0x04    //写使能锁存器禁止
#define WRSR 0x01    //写状态寄存器
#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    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中的各二进位向左移一位,因为首先写入的是字节的最高位
  }
}
/*****************************************************
函数功能:写状态寄存器 ,可以设置看门狗的溢出时间及数据保护
入口参数:rs;  //储存寄存器状态值
***************************************************/
void WriteSR(unsigned char rs)
{
  CS=0;                 //拉低CS,选中X5045
  WriteCurrent(WREN);   //写使能锁存器允许
  CS=1;                 //拉高CS
  CS=0;                 //重新拉低CS,否则下面的写寄存器状态指令将被丢弃
  WriteCurrent(WRSR);   //写状态寄存器
  WriteCurrent(rs);     //写入新设定的寄存器状态值
  CS=1;                 //拉高CS
}
/*****************************************************
函数功能:写数据到X5045的指定地址
入口参数:addr
***************************************************/
void WriteSet(unsigned char dat,unsigned char addr)
{
   SCK=0;                 //将SCK置于已知状态
   CS=0;                  //拉低CS,选中X5045
WriteCurrent(WREN);    //写使能锁存器允许
CS=1;                  //拉高CS
   CS=0;                  //重新拉低CS,否则下面的写入指令将被丢弃
WriteCurrent(WRITE);   //写入指令
WriteCurrent(addr);    //写入指定地址
WriteCurrent(dat);     //写入数据
CS=1;                  //拉高CS
   SCK=0;                 //将SCK置于已知状态
}
/*****************************************************
函数功能:从X5045的指定地址读出数据
入口参数:addr
出口参数:dat
***************************************************/
unsigned char ReadSet(unsigned char addr)
{
unsigned char dat;
SCK=0;                 //将SCK置于已知状态
CS=0;                  //拉低CS,选中X5045
WriteCurrent(READ);   //开始读
WriteCurrent(addr);   //写入指定地址
dat=ReadCurrent();    //读出数据
CS=1;                 //拉高CS
SCK=0;                //将SCK置于已知状态
return dat;           //返回读出的数据
}
/*****************************************************
函数功能:看门狗复位程序
***************************************************/
void WatchDog(void)
{
CS=1;    //拉高CS
CS=0;    //CS引脚的一个下降沿复位看门狗定时器
CS=1;    //拉高CS
}
/*****************************************************
函数功能:主程序
***************************************************/
void main(void)
{
  WriteSR(0x12);        //写状态寄存器(设定看门狗溢出时间为600ms,写不保护)  
  delaynms(10);         //X5045的写入周期约为10ms
  while(1)
  {
  WriteSet(0xaa,0x10);  //将数据“0xaa”写入指定地址“0x10”
  delaynms(10);         //X5045的写入周期约为10ms
   P0=ReadSet(0x10);      //将数据读出送P1口显示
    WatchDog();           //复位看门狗
  }
}


5、在proteus中新建仿真文件ex71.dsn,电路原理图如下所示
下载 (682 Bytes)
2010-5-13 19:59 下载 (67.11 KB)
2010-5-13 19:59


6、将ex71.hex文件载入at89c51中,注意将晶振频率改为11.0592MHz,启动仿真,察运行结果。下图是某一时刻程序运行结果
下载 (68.57 KB)
2010-5-13 19:59

zoom.gif (682 Bytes)

下载次数:1

2010-5-13 19:59

 

收藏 分享0