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

📄 sub_64.c

📁 一个单片机实现DA转换程序,程序实现了一个温度控制的数摸转换,并添加了去抖动处理!!
💻 C
字号:
#include "iom16.h"
#include "ioavr.h"
#include "inavr.h"
#include "avr_macros.h"

#include "userdef.h"
#include "userfun.h"
#include "userram.h"
#include "disdata.h"
//#include "usertype.h"


/******* 延时  *********/
void I2cWait(void)
{
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();

   __no_operation();  //tttt
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();

  __no_operation();  //tttt
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();

  __no_operation();  //tttt
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
   __no_operation();
}


/*************************  I2C通信启动  ***************************/
void I2cStart(void)
{
   SDA_HIGH;                 //数据线输出高电平
   I2cWait();                //tttt
   SCL_HIGH;                 //时钟线输出高电平
   I2cWait();                //延时
   I2cWait();                //tttt
   I2cWait();                //tttt
   I2cWait();                //tttt
   SDA_LOW;                  //数据线拉低
   I2cWait();                //延时
   SCL_LOW;                  //时钟线拉低
   I2cWait();                //tttt
}


/*******  I2C通信停止  *********/
void I2cStop(void)           //I2c停止信号
{
   SDA_LOW;                  //数据线拉低
   I2cWait();                //延时
   I2cWait();
   SCL_HIGH;                 //时钟线拉高
   I2cWait();                //延时
   SDA_HIGH;                 //数据线变高
}


/******  发送确认信号  ********/
void SendAck (unsigned char ack)
{
     if ( ack==0 )   {   SDA_LOW;  }    //发送 0
        else      {   SDA_HIGH; }       //发送 1
     I2cWait();                         //tttt
     SCL_HIGH;                          //时钟信号变高
     I2cWait();                         //延时
     SCL_LOW;                           //时钟信号变低
     I2cWait();
     SDA_HIGH;                          //数据线变高,为下次传送作准备
}


/******* 发送一个字节数据  *********/
void I2cSentByte(unsigned char bytedata)
{
   unsigned char i,ack;

   for(i=0;i<8;i++)                     //循环 8 次
   {
      if(bytedata & 0x80)
        {
        SDA_HIGH;
        }
      else
        {
        SDA_LOW;
        }
      bytedata <<= 1;                   //数据左移
      I2cWait();                        //延时
      SCL_HIGH;                         //时钟信号变高,模拟正脉冲
      I2cWait();                        //延时
      SCL_LOW;                          //时钟信号变低,为下一次输入做准备
      I2cWait();                        //延时
   }
   SDA_HIGH;                            //数据线变高,为接受响应信号作准备
//   I2cWait();                           //延时
//   I2cWait();                           //tttt
//   I2cWait();                           //tttt
   SCL_HIGH;                            //时钟信号变高
   I2cWait();                           //延时
//   I2cWait();                           //tttt
//   I2cWait();                           //tttt
   ack= !(PINB BIT3) ? 0:1 ;            //取得确认信号
   SCL_LOW;                             //时钟信号变低
   I2cWait();                           //延时

   if(ack==1)
     write_error=1;
}

/******* 接收一个字节数据  *********/
unsigned char I2cReceiveByte(void)
{
   unsigned char i,bytedata=0;
   SDA_HIGH;
   for(i=0;i<8;i++)                      //循环 8 次
   {
      SCL_HIGH;                          //时钟信号变高
      I2cWait();                         //延时

      bytedata <<= 1;                    //数据左移
      if( PINB BIT3 )   bytedata|=0x01;  //取得输入数据

      SCL_LOW;                           //时钟信号变低
      I2cWait();                         //延时
   }
   return bytedata;                      //返回接收数据
}


/******* 从LM77中读出温度数据  *********/
unsigned int  ReadLM77(void)
{
     unsigned int temp1;
     unsigned int  i;
	
     I2cStart();
     I2cSentByte(LM77Address);
     I2cSentByte(0x00);                 //SELECT TEMPERATURE REGISTER

     I2cStart();
     I2cSentByte(LM77Address+1);

//    while((PINB BIT3)!=0);             //test

     i=I2cReceiveByte();
     SendAck(0);

     temp1=I2cReceiveByte();
     SendAck(1);

     I2cStop();

     i=i<<8;
     i=i+temp1;
     i=i>>3;

     for(temp1=0;temp1<16000;temp1++);
     return i;
}


void Display_RX_Gain(void)
{
     disbuf[0]=BCDSEG_TAB[5];
     disbuf[1]=BCDSEG_TAB[17];
     disbuf[2]=NoDisplay;
     disbuf[3]=NoDisplay;
     disbuf[4]=BCDSEG_TAB[rx_gain/10];
     disbuf[5]=BCDSEG_TAB[rx_gain%10];
     disbcd(disbuf);
}


void Display_TX_Gain(void)
{
     disbuf[0]=BCDSEG_TAB[15];
     disbuf[1]=BCDSEG_TAB[10];
     disbuf[2]=NoDisplay;
     disbuf[3]=NoDisplay;
     disbuf[4]=BCDSEG_TAB[tx_gain/10];
     disbuf[5]=BCDSEG_TAB[tx_gain%10];
     disbcd(disbuf);
}




/*************************  I2C通信启动  ***************************/
void PCF_I2cStart(void)
{
   PCF_SDA_HIGH;               //数据线输出高电平
   PCF_SCL_HIGH;               //时钟线输出高电平
   I2cWait();                  //延时
   PCF_SDA_LOW;                //数据线拉低
   I2cWait();                  //延时
   PCF_SCL_LOW;                //时钟线拉低
}


/*******  I2C通信停止  *********/
void PCF_I2cStop(void)
{
   PCF_SDA_LOW;                //数据线拉低
   I2cWait();                  //延时
   I2cWait();
   PCF_SCL_HIGH;               //时钟线拉高
   I2cWait();                  //延时
   PCF_SDA_HIGH;               //数据线变高
}


/******* 发送一个字节数据  *********/
void PCF_I2cSentByte(unsigned char bytedata)
{
   unsigned char i,ack;

   for(i=0;i<8;i++)                     //循环 8 次
   {
      if(bytedata & 0x80)               // testpcf 注意,这里是先发第0位,最后发第7位
        {
        PCF_SDA_HIGH;
        }
      else
        {
        PCF_SDA_LOW;
        }
      bytedata <<= 1;                   // testpcf数据右移
      I2cWait();                        //延时
      PCF_SCL_HIGH;                     //时钟信号变高,模拟正脉冲
      I2cWait();                        //延时
      PCF_SCL_LOW;                      //时钟信号变低,为下一次输入做准备
      I2cWait();                        //延时
   }
   PCF_SDA_HIGH;                        //数据线变高,为接受响应信号作准备
// 输出转为输入
   DDRA = DDRA & 0XFD;

   I2cWait();                           //延时
   PCF_SCL_HIGH;                        //时钟信号变高
   I2cWait();                           //延时
   ack= !(PINA BIT1) ? 0:1 ;            //取得确认信号
   PCF_SCL_LOW;                         //时钟信号变低

// 输入转为输出
   DDRA = DDRA | 0X02;

   I2cWait();                           //延时

   if(ack==1)
     write_error=1;
}


void Write_PCF8575(void)
{
     unsigned int i;
     SET_PGC_LAH;
	
	   write_error=0;
	
     PCF_I2cStart();
     PCF_I2cSentByte(PCF8575Address);
//     PCF_I2cSentByte((~tx_gain<<3)+1);    //testpcf
//     PCF_I2cSentByte((~rx_gain<<3)+1);    //testpcf
//     PCF_I2cSentByte(tx_gain+0x80);
     PCF_I2cSentByte(rx_gain+0x80);
     PCF_I2cSentByte(tx_gain+0x80);         //PCF8575反接

     PCF_I2cStop();

     CLR_PGC_LAH;
     for(i=0;i<16000;i++);

     if(write_error!=0)
     {
       disbuf[0]=BCDSEG_TAB[14];
       disbuf[1]=BCDSEG_TAB[14];
       disbuf[2]=BCDSEG_TAB[14];
       disbuf[3]=BCDSEG_TAB[14];
       disbuf[4]=BCDSEG_TAB[14];
       disbuf[5]=BCDSEG_TAB[14];
       disbcd(disbuf);     		
     }
}




////////////////////////////////////////tttt

//////////////////写一页
void I2cPageWrite(void)
{
    unsigned int i;
    I2cStart();                                 //启动总线

    if(addr>=256)
      {
        I2cSentByte(DeviceCode_EEP+2);          //发送器件码
      }
    else
      {
        I2cSentByte(DeviceCode_EEP);            //发送器件码
      }
    I2cSentByte(addr%256);    	                //发送地址

    for(i=0;i<16;i++)                           //发送写入的数据
      {
      	if(addr>=256)
          I2cSentByte(240-addr%256);
        else
          I2cSentByte(addr);
      }
    I2cStop();                                  //总线停止
    for( i=0;i<6400;i++);                       //延时,等待写入
}



void clr_ram(void)
{
  unsigned char pages;
  addr=0x00;
  for(pages=0;pages<32;pages++)           //共有32页,每页16个数据
   {
     I2cPageWrite();                      //清除页内的内容
	   addr=addr+16;                        //地址指向下一页
   }
}



/****** 读出 一页数据  ********/
void I2cPageRead(void)
{
    unsigned char i,readdata;

    I2cStart();                                 //启动总线
    if(addr>=256)
        I2cSentByte(DeviceCode_EEP+2);          //发送器件码
    else
        I2cSentByte(DeviceCode_EEP);
    I2cSentByte(addr%256);                      //发送地址

    I2cStart();                                 //启动总线
    if(addr>=256)
        I2cSentByte(DeviceCode_EEP+3);          //发送器件码---读
    else
        I2cSentByte(DeviceCode_EEP+1);

    for(i=0;i<15;i++)                           //读取15 个数据
        {
          readdata=I2cReceiveByte();
          if(addr>=256)
            {
            	if(readdata!=(240-addr%256))
            	  read_error=1;
            }
          else
            {
            	if(readdata!=addr)
            	  read_error=1;
            }
          SendAck(0);                           //发送 确认信号 0
        }

    readdata=I2cReceiveByte();                  //读取最后1个数据
    if(addr>=256)
      {
      	if(readdata!=(240-addr%256))
      	  read_error=1;
      }
    else
      {
      	if(readdata!=addr)
      	  read_error=1;
      }

    SendAck(1);                                 //发送确认信号 1
    I2cStop();                                  //总线停止
}


///////////////校验内存////////////////////////////
void check_ram(void)
{
  unsigned char pages;
  addr=0x00;
  for(pages=0;pages<32;pages++)           //共有32页,每页16个数据
   {
     I2cPageRead();                       //清除页内的内容
       addr=addr+16;                      //地址指向下一页
   }
}

⌨️ 快捷键说明

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