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

📄 slave_main.c

📁 PIC18F6720同PIC18F6720之间进行I2C通讯,调试通过.
💻 C
字号:
#if defined(__PCH__)
#include <18F6720.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP  //HS:使用外部晶振10MHz;
                                 //NOWDT:不使用看门狗
                                 //NOPROTECT程序不保护
#use delay(clock=10000000)       //使能内部函数delay_ms()和delay_us()
//#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
//#define use_portb_lcd
#endif
char receive_string_buffer[]={'0','0','.','0','0'};
char receive_temp[5]={'0','0','.','0','0'};    //用来存放接收到的数据,以ASCII格式存放
#include "C:\A\EXT_INT1.C "
#include "C:\A\DAC7612U.C "
#include "C:\A\LCD1604.C "
#include "C:\A\PCF8563.C "


/*
long int AD_value_temp=0;  //声明长整型变量
long int AD_value=0;       //声明长整型变量
*/

void DAC7612U_test_program(){
   char string_pointer[]={'0','0','.','0','0'};
   char string_temp1[6];
   do{
      for(counter=0;counter<25;counter++){
        strcpy( string_temp1,string_pointer );//将string_pointer所指内容拷贝到string_temp1中;
        if(counter<10){string_temp1[1]=string_temp1[1]+counter;
                 string_temp1[0]='0';
                }
        else if(counter>9&&counter<20){string_temp1[1]=string_temp1[1]+counter-10;
                 string_temp1[0]='1';
                }
        else if(counter>19&&counter<25){string_temp1[1]=string_temp1[1]+counter-20;
                 string_temp1[0]='2';
                }
        write_string_to_DAC7612U(string_temp1,14);
        lcd1604_display(string_temp1);
        while( input(PIN_E3) );
        delay_ms(1000);
      }
   }while( input(PIN_E4));
}

/*
#int_ad
void ad_conversion_complete()
{ int32 FLOAT_ad_value;
  long int INT_ad_value;
  //char receive_temp[5];    //用来存放接收到的数据,以ASCII格式存放
  long int quotient;
  long int remainder;
  //int i=0;
  if(AD_value!=AD_value_temp)
  //if(AD_value==AD_value_temp)
    {AD_value=AD_value_temp;
     setup_adc( ADC_OFF );    //关掉AD转换
     FLOAT_ad_value=AD_value&0x3ff;
     //test
     //FLOAT_ad_value=0xcc;//相当于1V输入

     FLOAT_ad_value=FLOAT_ad_value*5000;
     //FLOAT_ad_value=FLOAT_ad_value/1023;//10位AD转换
     FLOAT_ad_value=FLOAT_ad_value/255; //8位AD转换
     INT_ad_value=(long int)(FLOAT_ad_value*6);

     quotient=INT_ad_value/1000;   //求整数部分;
     remainder=INT_ad_value%1000;  //求小数部分;

     receive_temp[0] =(int)(quotient/100); //求整数位的百位数
     quotient=quotient%100;      //
     receive_temp[1]=(int)(quotient/10); //求整数位的十位数
     receive_temp[2]=(int)(quotient%10); //求整数位的个位数

     receive_temp[3]=(int)(remainder/100); //求小数部分的最高位;
     remainder=remainder%100; //求小数部分的次高位以下部分;
     receive_temp[4]=(int)(remainder/10);
//   receive_temp[5]=(int)(remainder%10);
     if(receive_temp[0]==0)
       {receive_temp[0]=receive_temp[1]|'0';
        receive_temp[1]=receive_temp[2]|'0';
        receive_temp[2]='.';
        receive_temp[3]|='0';
        receive_temp[4]|='0';
        //receive_temp[5]|='0';
       }
     else{
          receive_temp[0]|='0';
          receive_temp[1]|='0';
          receive_temp[2]|='0';
          receive_temp[4]=receive_temp[3]|'0';
          receive_temp[3]='.';
          //receive_temp[5]|='0';
         }

     strcpy( receive_string_buffer,receive_temp );       //将receive_temp所指内容拷贝到receive_string_buffer中;
     write_string_to_DAC7612U(receive_string_buffer,14); //将接收到的5位ASCII码写入DAC7612U
     lcd1604_display(receive_string_buffer);             //将收到的ASCII码送去显示 
    }
    setup_adc( ADC_CLOCK_INTERNAL );                    //ADC采用内部指令时钟,重新启动AD转换
}
*/
#INT_EXT1
void ext_int1_service()
{
 BYTE j,SLAVE_address;
 //int1 receive_ok0;
 //int1 receive_ok1;
 char receive_temp[5]; //用来存放接收到的数据,以ASCII格式存放
 disable_interrupts(INT_EXT1);//不使能外部中断1
 if( input(slave_I2C_clk))  //若slave_I2C_clk=1时,在slave_I2C_data脚出现下降沿,表示I2C起动条件满足,则执行下面语句
   {if( wait_I2C_clk_low() )
      {SLAVE_address=read_IIC_byte(); //读到一个字节;
       if(SLAVE_address==0xaa)  //若地址相符合,则执行下面语句
         {iic_send_ack();       //本从机发送应答ACK;
          for(j=0;j<=4;j++)
             {receive_temp[j]=read_IIC_byte();//读到一个字节;
              if(j<4) iic_send_ack();         //本从机发送应答ACK;
              //if(receive_temp[j]!=0) receive_ok0=1;
              // else{receive_ok0=0; break;}
             }

          if(receive_temp[0]!=0x00)
            {if(receive_temp[1]!=0x00)
               {if(receive_temp[2]!=0x00)
                  {if(receive_temp[3]!=0x00)
                     {if(receive_temp[4]!=0x00)
                        {  delay_us(100);
                           strcpy( receive_string_buffer,receive_temp );//将receive_temp所指内容拷贝到receive_string_buffer中;
                           //write_string_to_DAC7612U(receive_string_buffer,14);  //将接收到的5位ASCII码写入DAC7612U
                           //lcd1604_display(receive_string_buffer);              //将接收到的5位ASCII码写入LCD显示;
                           //delay_us(100);
                        }
                     }
                  }
               }
            }

         }
      }
   }
 //恢复现场
enable_interrupts(INT_EXT1);//使能外部中断1
 //bit_set(*0xF93,1); //端口B的方向寄存器地址为0xF93,将RB1设置为输入
 //bit_set(*0xF93,2); //端口B的方向寄存器地址为0xF93,将RB2设置为输入
}

void main() {
   set_tris_e(0x78); //将RE0:RE2和RE7设置为输出口,RE3:RE6设置为输入口
   set_tris_f(0xfe); //将RF1:RF7设置为输入,RF0设置为输出;
   set_tris_a(0x13); //将RA0:RA1和RA4设置为输入,RA2:RA3和RA5:RA7设置为输出;


   ext_int1_init();  //外部中断1初始化;每次中断接到5个有效的ASCII码,则立即送去LCD显示,且写入DAC7612U 
   write_PCF8563_time(0x06,0x03,0x08,0x15,0x59,0x30); //将2006年3月8日,15点59分30秒写入PCF8563
   set_PCF8563_alarm(0x09, 0x58);                     //0x09分钟报警寄存器地址;设置在每小时零58分报警一次;
   
   DAC7612U_init();  //一次性初始化DAC7612U通道道1和通道0
   lcd_init();       //LCD初始化;
   //ext_int1_init();  //外部中断1初始化;每次中断接到5个有效的ASCII码,则立即送去LCD显示,且写入DAC7612U
    
   setup_adc_ports(ANALOG_AN0_TO_AN1); //将RA0和RA1设为模拟输入,所有其它脚为数字端口;
   //setup_adc( ADC_CLOCK_INTERNAL );    //ADC采用内部指令时钟
   //set_adc_channel( 0 );               //选择ADC端口0
   delay_us(10);//延时10us
   //enable_interrupts(int_ad);         //使能AD中断
   enable_interrupts(global);         //开总中断允许位
   do{delay_ms(100);//延时100ms
      //disable_interrupts(INT_EXT1);//不使能外部中断1
      write_string_to_DAC7612U(receive_string_buffer,14);  //将接收到的5位ASCII码写入DAC7612U
      lcd1604_display(receive_string_buffer);              //将接收到的5位ASCII码写入LCD显示;
      //AD_value_temp = Read_ADC();//读ADC端口0
      delay_ms(100);//延时100ms
      enable_interrupts(INT_EXT1);//不使能外部中断1
   }while(TRUE);

   while( input(PIN_E4));  //若按下S2键,则进入测试程序;
   DAC7612U_test_program();
}

/*INTCON2: 7 RBPU 当RBPU=0时,端口B上拉使能位
           6 INTEGE0 外部中断0边沿选择位,当INTEGE0=1,表示上升沿触发;
           5 INTEGE1 外部中断1边沿选择位,当INTEGE1=1,表示上升沿触发;
           4 INTEGE2 外部中断2边沿选择位,当INTEGE2=1,表示上升沿触发;
           3 INTEGE3 外部中断3边沿选择位,当INTEGE3=1,表示上升沿触发;
           2 TMROIP  RMR0溢出中断优先权选择位,当TMROIP=1时,TMR0有高优先权中断;
           1 INT3IP  外部中断3(INT3)中断优先权选择位;
           0 RBIP    端口B电平变化中断优先权选择位;
  INTCON3: 7 INT2IP  外部中断2(INT2)中断优先权选择位;
           6 INT1IP  外部中断1(INT1)中断优先权选择位;
           5 INT3IE  外部中断3(INT3)中断使能位;
           4 INT2IE  外部中断2(INT2)中断使能位;
           3 INT1IE  外部中断1(INT1)中断使能位;
           2 INT3IF  外部中断3(INT3)中断标志位;
           1 INT2IF  外部中断2(INT2)中断标志位;
           0 INT1IF  外部中断1(INT1)中断标志位;

  INTCON:7 GIE所有中断允许位;
         6 PEIE物理中断允许位;
         5 TMR0IE定时器0中断允许位;
         4 INT0IE外部中断0允许位;
         3 RBIE端口RB电平变化中断允许位;
         2 TMR0IF定时器0溢出标志位;
         1 INT0IF外部中断0的中断标志位;
         0 RBIF端口RB的RB4~RB7至少有一个产生中断标志位;
   PIR1: 7 PSPIF并口读写中断标志位;
         6 ADIF模拟转换AD口中断标志位;
         5 RC1IF串口1接收中断标志位;
         4 TX1IF串口1发送中断标志位;
         3 SSPIF串行SPI口中断标志位;
         2 CCP1IF比较器1中断标志位;
         1 TMR2IF定时器2溢出标志位;
         0 TNR1IF定时器1溢出标志位;
   PIE1: 7 PSPIE并口读写中断使能位;
         6 ADIE模拟转换AD口中断使能位;
         5 RC1IE串口1接收中断使能位;
         4 TX1IE串口1发送中断使能位;
         3 SSPIE串行SPI口中断使能位;
         2 CCP1IE比较器1中断使能位;
         1 TMR2IE定时器2溢出中断使能位;
         0 TMR1IE定时器1溢出中断使能位;
   PIR2: 7 未定义;
         6 CMIF比较器中断标志位;
         5 未定义;
         4 EEIF数据EEPROM或FLASH写操作中断标志位;
         3 BCLIF总线冲突中断标志位;
         2 LVDIF低电压检测中断标志位;
         1 TM3IF定时器3溢出标志位;
         0 CCP2IF比较器2中断标志位;
   PIE2  7 未定义;
         6 CMIEF比较器中断使能位;
         5 未定义;
         4 EEIE数据EEPROM或FLASH写操作中断使能位;
         3 BCLIE总线冲突中断使能位;
         2 LVDIE低电压检测中断使能位;
         1 TMR3IE定时器3溢出中断使能位;
         0 CCP2IE比较器2中断标使能位;
  ADCON0 7 未定义;
         6 未定义;
         5 CHS3 选择AD端口
         4 CHS2 选择AD端口
         3 CHS1 选择AD端口
         2 CHS0 选择AD端口
         1 GO/DONE模拟转换(AD)状态位
         0 ADON模拟转换(AD)使能位
  ADCON1 7 未定义;
         6 未定义;
         5 VCFG1 VCFG1:VCFG0=00表示Vref接VDD和VSS;VCFG1:VCFG0=01表示Vref接外部Vref+和VSS
         4 VCFG0 VCFG1:VCFG0=10表示Vref接VDD和外部Vref-;VCFG1:VCFG0=11表示Vref接外部Vref+和Vref-
         3 PCFG3配置为模拟端口还是数据端口?PCFG3:PCFG0=0000将所有配置为模拟端口;
         2 PCFG2 PCFG0=0001除了AN15和AN14外,所有其它通道配置为模拟端口;
         1 PCFG1
         0 PCFG0
   TRISA 端口A方向寄存器
   LATF  端口F锁存器
   TRISF 端口A方向寄存器
*/

⌨️ 快捷键说明

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