为什么用PIC16F677运行C语言不行?

2020-02-08 12:22发布

为什么我用PIC16F677运行C语言不行?是不是MPLAB IDE软件include文件夹中没有"PIC16F677.h"的原因?我看了是没有的。请教一下如何才能运行起来。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
10条回答
zhj555
2020-02-09 05:16
回复【3楼】role_2099
用pic16f685.h这个报错吗?如果源程序短你贴上来,我编译一下试试
-----------------------------------------------------------------------

用PIC16F685也试了不行.

#include <pic16f685.h>        //头文件引用
//大LED数码管显示代码表
const unsigned char LEDCODE[]=
{
  0x3F,0x06,0x5B,0x4F,//0,1,2,3
  0x66,0x6D,0x7D,0x07,//4,5,6,7
  0x7F,0x6F,                  //8,9
};
//宏定义
#define TRUE  1
#define FALsE 0

//-------------------------------------------------------------
//---定义软件定时器定时1s和0.5秒结构体变量
struct TIMER_sTRUCT
{
  unsigned int Interval;
  unsigned char Enable;       
};
struct TIMER_sTRUCT second_1s,second_Halfs;
//-------------------------------------------------------------

//-------------------------------------------------------------
//---定义实时带温度与闹铃功能的日历/时钟结构体变量
struct REALCLOCK_sTRUCT
{
  unsigned char Year;                //年份
  unsigned char Month;                //月份
  unsigned char Day;                //日
  unsigned char Week;                //星期
  unsigned char Hour;                //时
  unsigned char Minute;                //分
  unsigned char second;                //秒
  unsigned char Temp;                //温度
};
struct REALCLOCK_sTRUCT RealClock;
//-------------------------------------------------------------

//-------------------------------------------------------------
//---定义定时闹钟结构体变量
struct ALARMCLOCK_sTRUCT
{  
  unsigned char Day;                //日
  unsigned char Week;                //星期
  unsigned char Hour;                //时
  unsigned char Minute;                //分
  unsigned char second;                //秒
  unsigned char status;          //状态
};
struct ALARMCLOCK_sTRUCT AlarmClock;
//-------------------------------------------------------------

//-------------------------------------------------------------
//---定义PIC单片机与74HC595芯片接口连接关系
#define HC595_sER LATCbits.LATC0
#define HC595_RCLK LATCbits.LATC1
#define HC595_sRCLK LATCbits.LATC2
#define HC595_sRCLR LATCbits.LATC3
#define HC595_OE LATCbits.LATC4

//---定义LED数码管显示缓冲区
unsigned char LEDBuffer[16];

//---定义大LED数码管初始化函数
void InitizeLED(void)
{
  HC595_OE=1;//并行输出为高阻状态
  HC595_sRCLR=0;//清空移位寄存器
  HC595_sER=0;//清零
  HC595_RCLK=0;//移位时钟初始为低
  HC595_sRCLK=0;//存储器时钟初始为低
  HC595_OE=0;//允许并行输出
  HC595_sRCLR=1;//结束复位状态
}

//---定义大LED显示驱动函数
//*LedData指针,DataLength数据长度
void sendDataToLED(unsigned char *LedData,unsigned char DataLength)
{
  unsigned char i,j,temp;
  
  for(j=0;j<DataLength;j++)
    {
          temp=LEDCODE[*LedData];//取出LED显示的代码表送入变量中
          for(i=0;i<8;i++)
            {
                  if(0x80==(temp & 0x80))HC595_sER=1;//将字节按位移出
                    else HC595_sER=0;
                  HC595_RCLK=1;//将数据送入移位寄存器中
                  HC595_RCLK=0;
                  temp<<=1;//当前指针的内容左移一位
                }
          LedData++;//指针指向下一个数据
        }
  HC595_sRCLK=1;//将移位寄存器中的内容送到并行输出口
  HC595_sRCLK=0;
}
//-------------------------------------------------------------

//-------------------------------------------------------------
//---定义PIC单片机与Ds1302引脚之间的连接关系
#define Ds1302CE_1 LATCbits.LATC5=1
#define Ds1302CE_0 LATCbits.LATC5=0
#define Ds1302CE_O TRIsC &=0xDF

#define Ds1302IO_O TRIsC &=0xBF
#define Ds1302IO_I TRIsC |=0x20
#define Ds1302IO_1 LATCbits.LATC6=1
#define Ds1302IO_0 LATCbits.LATC6=0
#define Ds1302IO_D PORTC & 0x40

#define Ds1302CK_1 LATCbits.LATC7=1
#define Ds1302CK_0 LATCbits.LATC7=0
#define Ds1302CK_O TRIsC &=0x7F

//---Ds1302初始化函数
void Init_Ds1302_RTC(void)
{
  Ds1302CK_O;//置CK为输出
  Ds1302CE_O;//置CE为输出
  Ds1302CE_0;//输出为0
  Ds1302CK_0;//输出为0
  Ds1302IO_1;//置IO为输入
  Ds1302IO_I;
}

//---读取Ds1302日历函数
unsigned char Read_Ds1302_RTC(unsigned char RTC_Address)
{
  unsigned char i;
  unsigned int temp;
  
  Ds1302CE_0;//CE=0
  Ds1302CK_0;//CK=0
  Ds1302IO_O;//Ds1302为IO为输出
          _asm//简短延时
           NOP
           NOP
          _endasm
  Ds1302CE_1;//CE=1
          _asm//简短延时
           NOP
           NOP
          _endasm
  for(i=8;i>0;i--)//CPU送出访问Ds1302的地址
    { //以串行方式从PIC单片机的RC6引脚输出
      if(RTC_Address & 0x01)Ds1302IO_1;
        else Ds1302IO_0;
          _asm//简短延时
           NOP
           NOP
          _endasm
      Ds1302CK_1;//CK=1
          _asm//简短延时
           NOP
           NOP
          _endasm
      Ds1302CK_0;//CK=0
          _asm//简短延时
           NOP
           NOP
          _endasm
          RTC_Address>>=1;//右移一位
    }
  Ds1302IO_1;//PIC单片机的RC7为输入状态
  _asm//简短延时
   NOP
   NOP
  _endasm
  Ds1302IO_I;
  _asm//简短延时
   NOP
   NOP
  _endasm
  temp=0;
  if(Ds1302IO_D)temp|=0x8000;
  temp>>=1;//右移一位
  for(i=7;i>0;i--)
    {      
          _asm//简短延时
           NOP
           NOP
          _endasm
      Ds1302CK_1;//CK=1
          _asm//简短延时
           NOP
           NOP
          _endasm
      Ds1302CK_0;//CK=0
          _asm//简短延时
           NOP
           NOP
          _endasm
      if(Ds1302IO_D)temp|=0x8000;//RC7引脚上的电平并保存到变量中
          temp>>=1;//右移一位
    }       
  Ds1302CE_0;//CE=0
  temp<<=1;//左移一位
  return(temp/256);//返回读取到的内容
}

//---写入Ds1302日历函数
void Write_Ds1302_RTC(unsigned char RTC_Address,unsigned char RTC_Data)
{
  unsigned char i;
  
  Ds1302CE_0;//CE为输出
  Ds1302CK_0;//CK为输出
  Ds1302IO_O;//IO为输出
  _asm//简短延时
   NOP
   NOP
  _endasm
  Ds1302CE_1;//CE=1
  _asm//简短延时
   NOP
   NOP
  _endasm
  for(i=8;i>0;i--)
    { //送地址给Ds1302     
      if(RTC_Address & 0x01)Ds1302IO_1;
      else Ds1302IO_0;
          _asm//简短延时
           NOP
           NOP
          _endasm
      Ds1302CK_1;//CK=1
          _asm//简短延时
           NOP
           NOP
          _endasm
      Ds1302CK_0;//CK=0
          _asm//简短延时
           NOP
           NOP
          _endasm
      RTC_Address>>=1;//右移一位
    }
  for(i=8;i>0;i--)
    { //送数据给Ds1302     
      if(RTC_Data & 0x01)Ds1302IO_1;
      else Ds1302IO_0;      
          _asm//简短延时
           NOP
           NOP
          _endasm
      Ds1302CK_1;//CK=1
          _asm//简短延时
           NOP
           NOP
          _endasm
      Ds1302CK_0;//CK=0
          _asm//简短延时
           NOP
           NOP
          _endasm
      RTC_Data>>=1;//右移一位  
    }
  Ds1302CE_0;//CE=0
}
//-------------------------------------------------------------

//-------------------------------------------------------------
//---定义ADC缓冲区,和指针变量
unsigned char ADCBuffer[5];                                //ADC采集缓冲区
unsigned char ADCBufferPointer;                        //ADC采集缓冲区指针
unsigned char TemperatureDisplayFlag;        //当缓冲区满时,处理完后标志

//---ADC初始化函数定义
void ADC_Initize(void)
{
  unsigned char i;
  ADCON1=0x07;//初始化ADC的参考电压取VCC,GND
  ADCON2=0x00;//左对齐,0TAD,FOsC/2
  ADCON0=0x03;//选择通道0,启动A/D转换开始
  //初始化ADCBuffer变量指针和缓冲区
  ADCBufferPointer=0;
  for(i=0;i<sizeof(ADCBuffer);i++)ADCBuffer=0;
}
//-------------------------------------------------------------

//-------------------------------------------------------------
//---初始化PIC18F单片机工作于内部时钟8MHz状态下
void INTOsC_Initize(void)
{
  OsCCON=0x70;//选择内部8MHz的主振荡器       
}
//-------------------------------------------------------------

//-------------------------------------------------------------
//---TMR0定时器初始化函数
void TMR0_Initize(void)
{
  T0CONbits.TMR0ON=FALsE;//TMR0停止运行
  T0CON=0x12;//TMR0初始化为8位定时,预分频比为1:8
  TMR0L=256-25;//定时100ms初值
  T0CONbits.TMR0ON=TRUE;
}
//-------------------------------------------------------------

//-------------------------------------------------------------
//---延时函数的定义
void Delay(unsigned int t)
{
  while(t--);       
}
//-------------------------------------------------------------

//-------------------------------------------------------------
//---按键引脚的定义
#define DATEKEY PORTBbits.RA1
#define TIMEKEY PORTBbits.RA2
#define ALARMKEY PORTBbits.RA5
#define NUMBERADDKEY PORTBbits.RA3
#define NUMBERsUBKEY PORTBbits.RA4
//---功能按键状态变量定义
unsigned char DateKeyID;
unsigned char TimeKeyID;
unsigned char AlarmKeyID;
//-------------------------------------------------------------

//-------------------------------------------------------------
//定时器低优先级中断入口函数声明
void TMR0_TMR1_IsR(void);
#pragma code low_vector=0x18
void low_interrupt(void)
{
  _asm goto TMR0_TMR1_IsR _endasm       
}
#pragma code
//-------------------------------------------------------------

//-------------------------------------------------------------
//---主程序 main函数
void main(void)
{
  unsigned char i,j;
  unsigned long temp;
  
  INTOsC_Initize();                //初始化时钟源
  TMR0_Initize();                //初始化TMR0定时器
  ADC_Initize();                //初始化A/D模块
  InitizeLED();                        //初始化LED数码管显示
  INTCONbits.GIE=1;                //CPU开中断
  INTCONbits.PEIE=1;        //CPU的第二梯队中断允许
  
  while(1)
    {
          //-------------------------------------------------------
          //---功能键及数字调节键识别与处理过程
          //---
          //-------------------------------------------------------
          //---闹铃设置功能键
          if(0==ALARMKEY)        //闹铃设置键是否按下
            {
                  Delay(1000);        //去抖动
                  if(0==ALARMKEY)//是真得按下了吗
                    {
                          AlarmKeyID++;        //闹铃设置状态变量加1
                          if(1==AlarmKeyID)//在闹铃设置状态为1的情况下,复制当前日历的内容到闹铃变量中
                            {
                                  AlarmClock.second=RealClock.second;        //复制秒
                                  AlarmClock.Minute=RealClock.Minute;        //复制分
                                  AlarmClock.Hour=RealClock.Hour;                //复制时
                                  AlarmClock.Week=RealClock.Week;                //复制日
                                  AlarmClock.Day=RealClock.Day;                        //复制星期
                                }
                          if(0==AlarmClock.status)//如果闹铃是关闭的,则
                            {
                                  if(2==AlarmKeyID)AlarmKeyID=0;//直接回到正常状态
                                }
                            else//如果是闹铃是打开的,则
                              {
                                    if(5==AlarmKeyID)AlarmKeyID=0;//可以设置时分秒闹铃时间
                                  }
                        }
                  while(0==ALARMKEY);        //等待按键释放
                }
          //-------------------------------------------------------
          //---校准日期的功能键
          if(0==DATEKEY)//日期校准按键是否按下
            {
                  Delay(1000);//去按键抖动
                  if(0==DATEKEY)//再判断是否真得按下
                    {
                          TimeKeyID=0;//其它校准或设置变量状态为正常状态
                          AlarmKeyID=0;
                          DateKeyID++;//校准日期状态变量加1
                          if(5==DateKeyID)DateKeyID=0;//所有校准完毕,回到正常状态                          
                        }
                  while(0==DATEKEY);//等待按键释放
                }
          //-------------------------------------------------------
          
          //-------------------------------------------------------
          //---校准时间的功能键
          if(0==TIMEKEY)
            {
                  Delay(1000);
                  if(0==TIMEKEY)
                    {
                          DateKeyID=0;//其它校准或设置变量状态为正常状态
                          AlarmKeyID=0;
                          TimeKeyID++;
                          if(4==TimeKeyID)TimeKeyID=0;                          
                        }
                  while(0==TIMEKEY);
                }
          //-------------------------------------------------------
          
          //-------------------------------------------------------
          //---数字加调节键
          if(0==NUMBERADDKEY)//数字增调节键按下了
            {
                  Delay(1000);//去抖动
                  if(0==NUMBERADDKEY)//再判断是否真得按下
                    {
                          if(AlarmKeyID>0)//如果闹铃设置状态是处于设置条件下,则
                            {
                                  switch(AlarmKeyID)//根据闹铃状态变量来分析调节哪个功能
                                    {
                                          case 1://闹铃打开/关闭设置状态
                                                //如果闹铃关闭则打开,否则关闭
                                            if(0==AlarmClock.status)AlarmClock.status=1;
                                              else AlarmClock.status=0;
                                            break;
                                          case 2://设置闹铃的时状态
                                            if(0!=AlarmClock.status) //如果闹铃是打开的,则
                                              {
                                                    AlarmClock.Hour++;//闹铃的时变量加1
                                                    if(24==AlarmClock.Hour)AlarmClock.Hour=0;//到24归0
                                                  }
                                            break;
                                          case 3://设置闹铃的分状态
                                            if(0!=AlarmClock.status)//如果闹铃是打开的,则
                                              {
                                                    AlarmClock.Minute++;//闹铃的分变量加1
                                                    if(60==AlarmClock.Minute)AlarmClock.Minute=0;//到60归0
                                                  }                                          
                                            break;
                                          case 4://设置闹铃的秒状态
                                            if(0!=AlarmClock.status) //如果闹铃是打开的,则
                                              {
                                                    AlarmClock.second++;//闹铃的秒变量加1
                                                    if(60==AlarmClock.second)AlarmClock.second=0;//到60归0
                                                  }                                          
                                            break;                                          
                                        }
                                  if((AlarmKeyID>1)&&((0==DateKeyID)||(0==TimeKeyID)))
                                    {
                                        //将调整的结果送到LED显示缓冲区
                                        LEDBuffer[0]=AlarmClock.second%10;
                                   LEDBuffer[1]=AlarmClock.second/10;
                                   LEDBuffer[2]=AlarmClock.Minute%10;
                                   LEDBuffer[3]=AlarmClock.Minute/10;
                                   LEDBuffer[4]=AlarmClock.Hour%10;
                                   LEDBuffer[5]=AlarmClock.Hour/10;
                                        }
                                }
                          if(TimeKeyID>0)//如果时间设置状态是处于设置状态条件下,则
                            {
                                  switch(TimeKeyID)//根据时间设置状态变量的数值来决定
                                    {
                                          case 1://时间设置的时状态
                                            RealClock.Hour++;//时间设置时加1
                                            if(24==RealClock.Hour)RealClock.Hour=0;//到24归0
                                                //将其转换成16进制,以方便写入Ds1302的时寄存器单元
                                            i=((RealClock.Hour/10)<<4)|(RealClock.Hour%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x84,i);//写入Ds1302的时寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                          case 2://时间设置的分状态
                                            RealClock.Minute++;//时间设置的分加1
                                            if(60==RealClock.Minute)RealClock.Minute=0;//到60归0
                                                //将其转换成16进制,以方便写入Ds1302的分寄存器单元
                                            i=((RealClock.Minute/10)<<4)|(RealClock.Minute%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x82,i);//写入Ds1302的分寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                          case 3://时间设置的秒状态
                                            RealClock.second++;//时间设置的秒变量加1
                                            if(60==RealClock.second)RealClock.second=0;//到60归0
                                                //将其转换成16进制,以方便写入Ds1302的秒寄存器单元
                                            i=((RealClock.second/10)<<4)|(RealClock.second%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x80,i);//写入Ds1302的秒寄存器单元
                                           Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;   
                                        }   
                                }
                          if(DateKeyID>0)//如果日期设置状态变量处于设置状态条件下,则
                            {
                                  switch(DateKeyID)//根据日期设置状态变量的内容来决定
                                    {
                                          case 1://年份校准状态
                                            RealClock.Year++;//设置的年变量加1
                                            if(99<RealClock.Year)RealClock.Year=0;//到100归0
                                            //将其转换成16进制,以方便写入Ds1302的年寄存器单元
i=((RealClock.Year/10)<<4)|(RealClock.Year%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x8c,i);//写入Ds1302的年寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                          case 2://月份校准状态
                                            RealClock.Month++;//设置的月变量加1
                                            if(12<RealClock.Month)RealClock.Month=1;//到12归1
                                                //将其转换成16进制,以方便写入Ds1302的月寄存器单元
                                            i=((RealClock.Month/10)<<4)|(RealClock.Month%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x88,i);//设置Ds1302的月寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                          case 4://星期校准状态
                                            RealClock.Week++;//设置星期变量加1
                                            if(7<RealClock.Week)RealClock.Week=1;//到8归1
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x8a,RealClock.Week);//写入Ds1302的星期
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                          case 3://日期校准状态
                                            RealClock.Day++;//设置日的变量加1
                                            switch(RealClock.Month)//根据月份来调整日期最大值
                                              {
                                                    case 1://属于一个月中有31天的调整
                                                    case 3:
                                                    case 5:
                                                    case 7:
                                                    case 8:
                                                    case 10:
                                                    case 12:                                                     
                                                      if(31<RealClock.Day)RealClock.Day=1;//到32归1
                                                      break;
                                                    case 4://属于一个月中有30天的调整
                                                    case 6:
                                                    case 9:
                                                    case 11:
                                                      if(30<RealClock.Day)RealClock.Day=1;//到31归1
                                                      break;   
                                                    case 2://属于2月份根据是平的还是闰年来调整
                                                      if(0==(RealClock.Year%4))//如果是闰年.则
                                                            {
                                                                  if(29<RealClock.Day)RealClock.Day=1;//到30归1
                                                                }
                                                            else//是平年,则
                                                                  {
                                                                        if(28<RealClock.Day)RealClock.Day=1;//到29归1
                                                                  }
                                                          break;
                                                  }
                                                //将其转换成16进制,以方便写入Ds1302的日寄存器单元
                                            i=((RealClock.Day/10)<<4)|(RealClock.Day%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x86,i);//写入Ds1302的日寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                        }
                                }
                          //在设置状态下将所调节的内容装入显示缓冲区
                          if(((DateKeyID>0)||(TimeKeyID>0))&&(0==AlarmKeyID))
                            {
                              //将调整的结果送到LED显示缓冲区
                              LEDBuffer[0]=RealClock.second%10;        //秒的个位
                              LEDBuffer[1]=RealClock.second/10;        //秒的十位
                              LEDBuffer[2]=RealClock.Minute%10;        //分的个位
                              LEDBuffer[3]=RealClock.Minute/10;        //分的十位
                              LEDBuffer[4]=RealClock.Hour%10;        //时的个位
                              LEDBuffer[5]=RealClock.Hour/10;        //时的十位
                              LEDBuffer[6]=RealClock.Week;                //星期
                              LEDBuffer[7]=RealClock.Day%10;        //日的个位
                              LEDBuffer[8]=RealClock.Day/10;        //日的十位
                              LEDBuffer[9]=RealClock.Month%10;        //月的个位
                              LEDBuffer[10]=RealClock.Month/10;        //月的十位
                              LEDBuffer[11]=RealClock.Year%10;        //年的个位
                              LEDBuffer[12]=RealClock.Year/10;        //年的十位
                            }
                        }
                  while(0==NUMBERADDKEY);//等待数字增调节键释放
                }
          //-------------------------------------------------------
          
          //-------------------------------------------------------
          //---数字减调节键程序段
          if(0==NUMBERsUBKEY)//数字减调节键按下
            {
                  Delay(1000);//去抖动
                  if(0==NUMBERsUBKEY)//再判断是否真得按下
                    {
                          if(TimeKeyID>0)//如果时间设置状态变量是处于设置状态条件下,则
                            {
                                  switch(TimeKeyID)//根据时间设置状态变量来决定
                                    {
                                          case 1://时间设置的时状态
                                            RealClock.Hour--;//时减1
                                            if(0xFF==RealClock.Hour)RealClock.Hour=23;//到-1则归23
                                                //将其转换成16进制,以方便写入Ds1302的时寄存器单元
                                            i=((RealClock.Hour/10)<<4)|(RealClock.Hour%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x84,i);//写入Ds1302的时寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                          case 2://时间设置的分状态
                                            RealClock.Minute--;//分减1
                                            if(0xFF==RealClock.Minute)RealClock.Minute=59;//到-1归59
                                                //将其转换成16进制,以方便写入Ds1302的分寄存器单元
                                            i=((RealClock.Minute/10)<<4)|(RealClock.Minute%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x82,i);//写入Ds1302的分寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                          case 3://时间设置的秒状态
                                            RealClock.second--;//秒减1
                                            if(0xFF==RealClock.second)RealClock.second=59;//到-1归59
                                                //将其转换成16进制,以方便写入Ds1302的秒寄存器单元
                                            i=((RealClock.second/10)<<4)|(RealClock.second%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x80,i);//写入Ds1302的秒寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;   
                                        }   
                                }
                          if(DateKeyID>0)//日期设置状态变量是处于设置条件下,则
                            {
                                  switch(DateKeyID)//根据日期设置状态变量来决定
                                    {
                                          case 1://日期设置的年份
                                            RealClock.Year--;//年变量减1
                                            if(0xFF==RealClock.Year)RealClock.Year=99;//到-1归99
                                                //将其转换成16进制,以方便写入Ds1302的年寄存器单元
                                            i=((RealClock.Year/10)<<4)|(RealClock.Year%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x8c,i);//写入Ds1302的年寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                          case 2://日期设置的月份
                                            RealClock.Month--;//月变量减1
                                            if(0==RealClock.Month)RealClock.Month=1;//到0归1
                                                //将其转换成16进制,以方便写入Ds1302的月寄存器单元
                                            i=((RealClock.Month/10)<<4)|(RealClock.Month%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x88,i);//写入Ds1302的月寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                          case 3://日期设置的日
                                            RealClock.Day--;//日变量减1
                                            if(0==RealClock.Day)RealClock.Day=1;//到0归1
                                                //将其转换成16进制,以方便写入Ds1302的日寄存器单元
                                            i=((RealClock.Day/10)<<4)|(RealClock.Day%10);
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x86,i);//写入Ds1302的天寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                          case 4://日期设置的星期
                                            RealClock.Week--;//星期减1
                                            if(0==RealClock.Week)RealClock.Week=1;//到0归1
                                                //将其转换成16进制,以方便写入Ds1302的星期寄存器单元
                                            i=RealClock.Week%10;
                                            Write_Ds1302_RTC(0x8e,0x00);//Ds1302的允许写打开
                                            Write_Ds1302_RTC(0x8a,i);//写入Ds1302的星期寄存器单元
                                            Write_Ds1302_RTC(0x8e,0x80);//Ds1302的禁止写禁止
                                            break;
                                }
                        }
                          //在设置状态下将所调节的内容装入显示缓冲区
                          if(((DateKeyID>0)||(TimeKeyID>0))&&(0==AlarmKeyID))
                            {
                              //将调整的结果送到LED显示缓冲区
                              LEDBuffer[0]=RealClock.second%10;        //秒的个位
                              LEDBuffer[1]=RealClock.second/10;        //秒的十位
                              LEDBuffer[2]=RealClock.Minute%10;        //分的个位
                              LEDBuffer[3]=RealClock.Minute/10;        //分的十位
                              LEDBuffer[4]=RealClock.Hour%10;        //时的个位
                              LEDBuffer[5]=RealClock.Hour/10;        //时的十位
                              LEDBuffer[6]=RealClock.Week;                //星期
                              LEDBuffer[7]=RealClock.Day%10;        //日的个位
                              LEDBuffer[8]=RealClock.Day/10;        //日的十位
                              LEDBuffer[9]=RealClock.Month%10;        //月的个位
                              LEDBuffer[10]=RealClock.Month/10;        //月的十位
                              LEDBuffer[11]=RealClock.Year%10;        //年的个位
                              LEDBuffer[12]=RealClock.Year/10;        //年的十位
                            }
                }
              while(0==NUMBERsUBKEY);//等待数字减调节释放
        }
      //-------------------------------------------------------
      
      //-------------------------------------------------------
      //---温度数据采集和滤波完毕,将结果送到显示缓冲区
          if(TRUE==TemperatureDisplayFlag)
            {
                  TemperatureDisplayFlag=FALsE;
                  temp=RealClock.Temp;
                  temp*=500;
                  temp/=256;
                  temp-=273;//将A/D转换的数据根据AD590计算公式转换成温度值
                  LEDBuffer[15]=16;//数码管灭
                  if(0x80000000==(temp & 0x80000000))//测量温度为负
                    {
                      temp=~temp;//取反
                          temp++;//加1
                        }
                  LEDBuffer[15]=17;//数码管显示负号
                  LEDBuffer[14]=temp/10;//将温度值存储到缓冲区
                  LEDBuffer[13]=temp%10;
                }
          //-------------------------------------------------------
          
          //-------------------------------------------------------
          //---定时半秒时间到,读取Ds1302日历和闪烁现象产生
          if(TRUE==second_Halfs.Enable)
            {
                  second_Halfs.Enable=FALsE;
                  if((0==DateKeyID)&&(0==TimeKeyID)&&(0==AlarmKeyID))
                    {
                      i=Read_Ds1302_RTC(0x81);//读取Ds1302的秒
                      RealClock.second=(i/16)*10+(i%16);
              i=Read_Ds1302_RTC(0x83);//读取Ds1302的分
              RealClock.Minute=(i/16)*10+(i%16);
                      i=Read_Ds1302_RTC(0x85);//读取Ds1302的时
                      RealClock.Hour=(i/16)*10+(i%16);
              i=Read_Ds1302_RTC(0x87);//读Ds1302的日
              RealClock.Day=(i/16)*10+(i%16);
              i=Read_Ds1302_RTC(0x89);//读Ds1302的月
              RealClock.Month=(i/16)*10+(i%16);
              i=Read_Ds1302_RTC(0x8b);//读Ds1302的星期
              RealClock.Week=i%16;
              i=Read_Ds1302_RTC(0x8d);//读Ds1302的年
              RealClock.Year=(i/16)*10+(i%16);
            }
                  //---------------------------------------------------
                  if(AlarmKeyID>0)
                    {
                          switch(AlarmKeyID)
                            {
                                  case 1:
                                    if(0==AlarmClock.status)
                                      {
                                            LEDBuffer[12]=10;//"A"
                                            LEDBuffer[11]=18;//"L"
                                            LEDBuffer[10]=19;//"r"
                                            LEDBuffer[9] =20;//"O"
                                            LEDBuffer[8] =15;//"F"
                                            LEDBuffer[7] =15;//"F"
                                          }
                                          else
                                            {
                                              LEDBuffer[12]=10;//"A"
                                              LEDBuffer[11]=18;//"L"
                                              LEDBuffer[10]=19;//"r"
                                              LEDBuffer[9] =16;//" "
                                              LEDBuffer[8] =20;//"O"
                                              LEDBuffer[7] =21;//"N"       
                                                }
                                    break;
                                  case 2:
                                    if((16==LEDBuffer[4])&&(16==LEDBuffer[5]))//灭状态
                                      {
                                            LEDBuffer[4]=AlarmClock.Hour%10;//装入闹铃时钟内容
                                            LEDBuffer[5]=AlarmClock.Hour/10;
                                          }
                                          else
                                            {
                                                  LEDBuffer[4]=16;//装入LED灭的内容
                                                  LEDBuffer[5]=16;
                                                }                                    
                                    break;
                                  case 3:
                                    if((16==LEDBuffer[2])&&(16==LEDBuffer[3]))//灭状态
                                      {
                                            LEDBuffer[2]=AlarmClock.Minute%10;//装入闹铃分钟内容
                                            LEDBuffer[3]=AlarmClock.Minute/10;
                                          }
                                          else
                                            {
                                                  LEDBuffer[2]=16;//装入LED灭的内容
                                                  LEDBuffer[3]=16;
                                                }                                  
                                    break;
                                  case 4:
                                    if((16==LEDBuffer[0])&&(16==LEDBuffer[1]))//灭状态
                                      {
                                            LEDBuffer[0]=AlarmClock.Day%10;//装入闹铃秒钟内容
                                            LEDBuffer[1]=AlarmClock.Day/10;
                                          }
                                          else
                                            {
                                                  LEDBuffer[0]=16;//装入LED灭的内容
                                                  LEDBuffer[1]=16;
                                                }                                  
                                    break;   
                                }
                        }
                  //---------------------------------------------------
                  
                  //---------------------------------------------------
                  //---校准日期和星期时,以闪烁现象提示
                  if(DateKeyID>0)
                    {
                          switch(DateKeyID)
                            {
                                  case 1:
                                    if((16==LEDBuffer[11])&&(16==LEDBuffer[12]))//灭状态
                                      {
                                            LEDBuffer[11]=RealClock.Year%10;//装入年份内容
                                            LEDBuffer[12]=RealClock.Year/10;
                                          }
                                          else
                                            {
                                                  LEDBuffer[11]=16;//装入LED灭的内容
                                                  LEDBuffer[12]=16;
                                                }
                                    break;
                                  case 2:
                                    if((16==LEDBuffer[9])&&(16==LEDBuffer[10]))//灭状态
                                      {
                                            LEDBuffer[9]=RealClock.Month%10;//装入月份内容
                                            LEDBuffer[10]=RealClock.Month/10;
                                          }
                                          else
                                            {
                                                  LEDBuffer[9]=16;//装入LED灭的内容
                                                  LEDBuffer[10]=16;
                                                }                                  
                                    break;
                                  case 3:
                                    if((16==LEDBuffer[7])&&(16==LEDBuffer[8]))//灭状态
                                      {
                                            LEDBuffer[7]=RealClock.Day%10;//装入年份内容
                                            LEDBuffer[8]=RealClock.Day/10;
                                          }
                                          else
                                            {
                                                  LEDBuffer[7]=16;//装入LED灭的内容
                                                  LEDBuffer[8]=16;
                                                }                                  
                                    break;
                                  case 4:
                                    if(16==LEDBuffer[6])LEDBuffer[6]=RealClock.Week;
                                          else LEDBuffer[6]=16;
                                    break;   
                                }
                        }
                  //---------------------------------------------------
                  
                  //---------------------------------------------------
                  //---校准时间时,以闪烁现象提示
              if(TimeKeyID>0)
                {
                      switch(TimeKeyID)
                        {
                              case 1:
                                    if((16==LEDBuffer[4])&&(16==LEDBuffer[5]))//灭状态
                                      {
                                            LEDBuffer[4]=RealClock.Hour%10;//装入时钟内容
                                            LEDBuffer[5]=RealClock.Hour/10;
                                          }
                                          else
                                            {
                                                  LEDBuffer[4]=16;//装入LED灭的内容
                                                  LEDBuffer[5]=16;
                                                }                             
                                break;
                              case 2:
                                    if((16==LEDBuffer[2])&&(16==LEDBuffer[3]))//灭状态
                                      {
                                            LEDBuffer[2]=RealClock.Minute%10;//装入分钟内容
                                            LEDBuffer[3]=RealClock.Minute/10;
                                          }
                                          else
                                            {
                                                  LEDBuffer[2]=16;//装入LED灭的内容
                                                  LEDBuffer[3]=16;
                                                }                                                               
                                break;
                              case 3:
                                    if((16==LEDBuffer[0])&&(16==LEDBuffer[1]))//灭状态
                                      {
                                            LEDBuffer[0]=RealClock.Day%10;//装入秒钟内容
                                            LEDBuffer[1]=RealClock.Day/10;
                                          }
                                          else
                                            {
                                                  LEDBuffer[0]=16;//装入LED灭的内容
                                                  LEDBuffer[1]=16;
                                                }                             
                                break;   
                            }
                    }
                  //---------------------------------------------------
                  
                  //---------------------------------------------------
                  //---将闪烁现象送到LED数码管显示
                  if((DateKeyID>0)||(TimeKeyID>0)||(AlarmKeyID>0))
                    sendDataToLED(LEDBuffer,sizeof(LEDBuffer));
                  //---------------------------------------------------
                }
          
          //-------------------------------------------------------
          //---定时1s时间到,送出显示
          if(TRUE==second_1s.Enable)
            {
                  second_1s.Enable=FALsE;
                  if((0==DateKeyID)&&(0==TimeKeyID)&&(0==AlarmKeyID))
                    sendDataToLED(LEDBuffer,sizeof(LEDBuffer));
                }
          //-------------------------------------------------------
    }

}

//-------------------------------------------------------------
//---低优先中断服务程序
#pragma interruptlow TMR0_TMR1_IsR
void TMR0_TMR1_IsR(void)
{
  unsigned char i,j,temp;
  
  if(TRUE==INTCONbits.TMR0IF)//定时100ms溢出
    {
          INTCONbits.TMR0IF=FALsE;//清TMR0溢出中断标志
          TMR0L=256-25;//装入新的初值
          
          second_Halfs.Interval++;
          if(5==second_Halfs.Interval)//每0.5秒读Ds1302和闪烁
            {
                  second_Halfs.Interval=0;
                  second_Halfs.Enable=TRUE;
                }
                    
          second_1s.Interval++;
          if(10==second_1s.Interval)
            {
                  second_1s.Interval=0;
                  second_1s.Enable=TRUE;   
                }
               
          if(0==ADCON0bits.DONE)//判断A/D转换是否完毕
            {
              ADCBuffer[ADCBufferPointer]=ADREsH;//装入当前缓冲区
              ADCON0bits.GO=1;//重新启动A/D开始转换
              ADCBufferPointer++;//指针加1
              if(ADCBufferPointer==sizeof(ADCBuffer))//缓冲区装满否
                {
                  ADCBufferPointer=0;//指针初始化
                  //将缓冲区的内容按从大到小排序
                  for(i=0;i<sizeof(ADCBuffer);i++)
                    for(j=i;j<sizeof(ADCBuffer);j++)
                      {
                            if(ADCBuffer<ADCBuffer[j])
                              {
                                    temp=ADCBuffer;
                                    ADCBuffer=ADCBuffer[j];
                                    ADCBuffer[j]=temp;
                                  }   
                          }
                      //取缓冲区中间的数值作为当前测量到的温度值数据
                      RealClock.Temp=ADCBuffer[sizeof(ADCBuffer)/2];
                      TemperatureDisplayFlag=TRUE;
                    }
            }
        }
}

一周热门 更多>