⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 93c46.c

📁 Atmel的93C46、8位模式、C51语言。适合MCS-51单片机
💻 C
字号:
//AT93C46读写C51程序,关联芯片:AT892051,MAX7219
//完成人:慕振国   泰安优耐机械电子有限公司
//注:AT93C46的ORG引脚接地,即选择8位模式
//日期:2008.08.29  V1.0
//问题:串写入时Number不能大于16,未解决
#include <reg52.h>

#define uchar unsigned char
/*****************Max7219相关定义*********************/
#define  HIGH     1
#define  LOW      0
#define  TRUE      1
#define  FALSE      0
#define  ZERO      0
#define  MSB       0x80
#define  LSB       0x01

#define  DECODE_MODE   0x09
#define  INTENSITY     0x0A
#define  SCAN_LIMIT    0x0B
#define  SHUT_DOWN     0x0C
#define  DISPLAY_TEST  0x0F
/*******************************************************/
sbit AT93C46_CS=P1^6;   //AT93C46  片选信号 高电平有效
sbit AT93C46_SK=P1^5;   //AT93C46  时钟信号
sbit AT93C46_DI=P1^4;   //AT93C46  数据输入线
sbit AT93C46_DO=P1^3;   //AT93C46  数据输出线

sbit Max7219_LOAD=P3^5; //MAX7219    Load-Data Input:    rising edge  pin 12
sbit Max7219_DIN =P3^7; //MAX7219    Serial-Data Input:   rising edge  pin 1
sbit Max7219_CLK =P3^3; //MAX7219   Serial-Clock Input:  maximum 10MHz  pin 13
/********************************************************************************/
uchar string[50]={0xde,0xde,0xde,0xde,0xde,0xde}; //定义字符串,用于串读写
/********************************************************************************/
void delay1s(void)           //延时1s子程,用于数码显示延时
{
 unsigned int i,j,k;

 for(i=50;i>0;i--)           //100-->1s  50-->0.5s
   for(j=20;j>0;j--)
     for(k=248;k>0;k--)
     ;
}
/************************************************************************/
void Write_Max7219_byte(unsigned char temp)
{
 unsigned char i;
 for (i=0;i<8;i++)
  {
   Max7219_CLK=LOW;
     Max7219_DIN=(bit)(temp&MSB);
     temp<<=1;
     Max7219_CLK=HIGH;
   }
}
/***********************************************************************/
void Write_Max7219(unsigned char address,unsigned char dat)
{
 Max7219_LOAD=LOW;
   Write_Max7219_byte(address);
   Write_Max7219_byte(dat);
  Max7219_LOAD=HIGH;
}
/***********************************************************************/
void Init_Max7219(void)
{
 Write_Max7219(SHUT_DOWN, 0x01);   //Normal Operation XXXXXXX1 Shutdown Mode   XXXXXXXX0
 Write_Max7219(DISPLAY_TEST, 0x00);   //Normal Operation XXXXXXX0 Display Test Mode XXXXXXXX1
 Write_Max7219(DECODE_MODE, 0xff);   //Decode Mode Select D7~D0 1 B decode 0 No decode
 Write_Max7219(SCAN_LIMIT, 0x07);   //SCAN LIMIT 0~7 0xX0~0xX7
 Write_Max7219(INTENSITY, 0x04);   //Set Intensity   0xX0~0xXf
}
/***********************************************************************************************/
// Write enable must precede all programming modes.
void Ewen(void)                    //读写允许子函数
{
 unsigned char temp,InData;
 AT93C46_CS=0;
 AT93C46_SK=0;
 AT93C46_CS=1;
 InData=0x98; // 1 00 11XXXXX       //开始位:1,操作码:00,地址(8位模式):11XXXXX
 for(temp=10;temp!=0;temp--)
  {                  
   AT93C46_DI=InData&0x80;
   AT93C46_SK=1; AT93C46_SK=0;
   InData<<=1;
  }
 AT93C46_CS=0;
}
// Disables all programming instructions.
void Ewds(void)                  //读写禁止子函数
{
 unsigned char temp,InData;
 AT93C46_CS=0;
 AT93C46_SK=0;
 AT93C46_CS=1;
 InData=0x80; // 1 00 00XXXXX  //开始位:1,操作码:00,地址(8位模式):00XXXXX
 for(temp=10;temp!=0;temp--)
  { 
   AT93C46_DI=InData&0x80;
   AT93C46_SK=1; AT93C46_SK=0;
   InData<<=1;
  }
 AT93C46_CS=0;
}
// Reads data stored in memory, at specified address.
unsigned char Read(unsigned char address) // 从address读取一字节
{
  unsigned char temp;
  unsigned char result;
  uchar i=10;
  Ewen();
  AT93C46_SK=0; AT93C46_DI=1; //开始位:1,操作码:10,地址:A6-A0
  AT93C46_CS=0; AT93C46_CS=1;
  AT93C46_SK=1; AT93C46_SK=0; // 1
  AT93C46_DI=1; while(i--);
  AT93C46_SK=1;               // 1
  AT93C46_SK=0;
  address=address&0xef;       // 0 A6-A0
  for(temp=8;temp!=0;temp--)
   {
     AT93C46_DI=address&0x80;
     AT93C46_SK=1; AT93C46_SK=0;
     address<<=1;
   }
  AT93C46_DO=1;   //此处,Datasheet中说:接收到读指令和地址后,DO引脚先输出一个虚拟低电平,
                  //然后数据根据时钟信号移位输出,高位在前。
                  //我的理解:虚拟低电平存在时间很短且不受时钟信号控制,
                  //在编程时可在送入读指令和地址后,加入"AT93C46_DO=1",保证下一数据正常接受。
  for(temp=8;temp!=0;temp--)  //从93C46读出8位数据
   {
     AT93C46_SK=1;
     result=(result<<1)|AT93C46_DO;
     AT93C46_SK=0;
   }
  AT93C46_CS=0;
  Ewds();
  return(result);
}
// Writes memory location An - A0.
void Write(unsigned char address,unsigned char InData) //在address写入一字节InData
{
  unsigned char temp;
  uchar i=10;
  Ewen();
  AT93C46_SK=0; AT93C46_DI=1; // 101 A6-A0
  AT93C46_CS=0; AT93C46_CS=1;
  AT93C46_SK=1; AT93C46_SK=0; // 1
  AT93C46_DI=0; while(i--);
  AT93C46_SK=1;               // 0
  AT93C46_SK=0;
  address=address|0x80;       //把最高位置为1 A6-A0
  for(temp=8;temp!=0;temp--)
   {
     AT93C46_DI=address&0x80;
     AT93C46_SK=1; AT93C46_SK=0;
     address<<=1;
   }
  for(temp=8;temp!=0;temp--)
   {
     AT93C46_DI=InData&0x80;
     AT93C46_SK=1; AT93C46_SK=0;
     InData<<=1;
   }
  AT93C46_CS=0; AT93C46_DO=1;
  AT93C46_CS=1; AT93C46_SK=1;
  while(AT93C46_DO==0)          // busy test
   { 
     AT93C46_SK=0; AT93C46_SK=1;
   }
  AT93C46_SK=0; AT93C46_CS=0;
  Ewds();
}
// Erase memory location An - A0.
void Erase(unsigned char address)          //擦除地址address处字节数据,擦除后为0xff
{
   unsigned char temp;
   Ewen();
   AT93C46_SK=0; AT93C46_DI=1; // 111 A6-A0
   AT93C46_CS=0; AT93C46_CS=1;
   AT93C46_SK=1; AT93C46_SK=0; // 1
   AT93C46_DI=1;
   AT93C46_SK=1;AT93C46_SK=0;
   address|=0x80;
   for(temp=8;temp!=0;temp--)
   {
     AT93C46_DI=address&0x80;
     AT93C46_SK=1; AT93C46_SK=0;
     address<<=1;
   }
   AT93C46_CS=0; AT93C46_DO=1;
   AT93C46_CS=1; AT93C46_SK=1;
   while(AT93C46_DO==0)
   {
     AT93C46_SK=0; AT93C46_SK=1;
   }
   AT93C46_SK=0; AT93C46_CS=0;
   Ewds();
}
// Erases all memory locations. Valid only at VCC = 4.5V to 5.5V.
void Eral(void)                   //擦除所有数据,擦除后为0xff
{
   unsigned char temp,InData;
   Ewen();
   AT93C46_CS=0;
   AT93C46_SK=0;
   AT93C46_CS=1;
   InData=0x90;      // 10010XXXXX
   for(temp=10;temp!=0;temp--)
   {
     AT93C46_DI=InData&0x80;
     AT93C46_SK=1; AT93C46_SK=0;
     InData<<=1;
   }
   AT93C46_CS=0; AT93C46_DO=1;
   AT93C46_CS=1; AT93C46_SK=1;
   while(AT93C46_DO==0)
   {
     AT93C46_SK=0; AT93C46_SK=1;
   }
   AT93C46_SK=0; AT93C46_CS=0;
   Ewds();
}

// Writes all memory locations. Valid only at VCC = 4.5V to 5.5V.
void Wral(unsigned char InData)   //将InData写入所有地址
{
   unsigned char temp,address;
   Ewen();
   AT93C46_CS=0;
   AT93C46_SK=0;
   AT93C46_CS=1;
   address=0x88;       // 10001XXXXX
   for(temp=10;temp!=0;temp--)
   {
     AT93C46_DI=address&0x80;
     AT93C46_SK=1; AT93C46_SK=0;
     address<<=1;
   }
   for(temp=8;temp!=0;temp--)
   {
     AT93C46_DI=InData&0x80;
     AT93C46_SK=1; AT93C46_SK=0;
     InData<<=1;
   }
   AT93C46_CS=0; AT93C46_DO=1;
   AT93C46_CS=1; AT93C46_SK=1;
   while(AT93C46_DO==0)
   {
     AT93C46_SK=0; AT93C46_SK=1;
   }
   AT93C46_SK=0; AT93C46_CS=0;
   Ewds();
}
/*//用于16位模式,字节读写,其中的Read函数为字读取,Write为字写入函数
unsigned char ReadChar(unsigned char address)
{
 unsigned char temp=address>>1;
 if(address&0x01)
     return((unsigned char)(Read(temp)>>8));
 else
     return((unsigned char)(Read(temp)));
}
void WriteChar(unsigned char address,unsigned char InData)
{
  unsigned char temp=address>>1;
  if(address&0x01)
     Write(temp,(unsigned int)(Read(temp)&0x00ff|(InData<<8)));
  else
     Write(temp,(unsigned int)(Read(temp)&0xff00|InData));
}
*/
void ReadString(unsigned char data *RamAddress,unsigned char RomAddress,unsigned char Number)
{                        //读取从RomAddress开始的Number个字节到RamAddress指向的地址
  while(Number!=0)
  {
    *RamAddress=Read(RomAddress);
    RamAddress++;
    RomAddress++;
    Number--;
  }
}

void WriteString(unsigned char data *RamAddress,unsigned char RomAddress,unsigned char Number)
{             //将RamAddress指向地址的Number个数据写入EEPROM的RomAddress开始的地址
   while(Number!=0)
    {
      Write(RomAddress,*RamAddress);
      RamAddress++;
      RomAddress++;
      Number--;
    }
}
void display(void)  //MAX7219显示清零
{
 Write_Max7219(1,0);
 Write_Max7219(2,0);
 Write_Max7219(3,0);
 Write_Max7219(4,0);
 Write_Max7219(5,0);
 Write_Max7219(6,0);
 Write_Max7219(7,0);
 Write_Max7219(8,0);
}
void main(void)
{
  uchar i=0;
  Init_Max7219();
  Write(0x00,100);
  Write(0x01,110);
  Write(0x02,120);
  Write(0x03,130);
  Write(0x04,140);
  Write(0x05,150);
  Write(0x06,160);
  Write(0x07,170);
  Write(0x08,180);
  Write(0x09,190);
  Write(0x0a,100);
  Eral();
  //Wral(0xef);
  //Erase(0x00);
  //ReadString(string,0x00,20);
  WriteString(string,0x00,20);
  while(1)
  {
    display();
    delay1s();
 /*   i=Read(0x00);
    Write_Max7219(1,i);
    i=Read(0x01);
    Write_Max7219(2,i);
    i=Read(0x02);
    Write_Max7219(3,i);
    i=Read(0x03);
    Write_Max7219(4,i);
    i=Read(0x04);
    Write_Max7219(5,i);
    i=Read(0x05);
    Write_Max7219(6,i);
    i=Read(0x06);
    Write_Max7219(7,i);
    i=Read(0x07);
    Write_Max7219(8,i);
  */
   i=Read(0x00);
   Write_Max7219(1,i/100);
   Write_Max7219(2,i%100/10);
   Write_Max7219(3,i%100%10);
   i=Read(0x14);
   Write_Max7219(4,i/100);
   Write_Max7219(5,i%100/10);
   Write_Max7219(6,i%100%10);
   i=Read(0x1f);
   Write_Max7219(7,i/100);
   Write_Max7219(8,i%100/10);
 /*
   Write_Max7219(1,string[0]/100);
   Write_Max7219(2,string[0]%100/10);
   Write_Max7219(3,string[0]%100%10);
   Write_Max7219(4,string[19]/100);
   Write_Max7219(5,string[19]%100/10);
   Write_Max7219(6,string[19]%100%10);
   Write_Max7219(7,string[20]/100);
   Write_Max7219(8,string[20]%100/10);
 */  delay1s();
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -