查看: 1020|回复: 0
打印 上一主题 下一主题

串口、外部中断、掉电存储、定时器同时应用程序

[复制链接]
跳转到指定楼层
沙发
发表于 2015-5-6 08:15:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/********************************************************************
                            汇诚科技

实现功能:STC15F104E系列单片机之串口、外部中断、掉电存储、定时器同时应用程序
使用芯片:STC15F104E系列单片机
晶振:11.0592MHZ
波特率:9600
编译环境:Keil
作者:zhangxinchun
网站:www.ourhc.cn
淘宝店:
汇诚科技 http://ourhc.taobao.com
郑兴电子直销部 http://shop68451856.taobao.com
【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!     

*********************************************************************/
/********************************************************************
单片机与PC机采用9针串口,MAX232通讯,波特率默认为9600.
单片机接收PC机发送的数据码表如下:

01、开:PC发送'A';
02、关:PC发送'B';
03、输出状态查询:PC发送C;单片机返回输出状态‘A’表示开 ‘B’表示关;
04、继电器状态取反:PC发送D        继电器状态取反
*********************************************************************/
#include "reg52.h"
#include <intrins.H>
#define uchar unsigned char //宏定义字符型变量
#define uint  unsigned int        //宏定义整型变量
/********************************************************************
                       eeprom函数声明
*********************************************************************/
extern void IapIdle();                                              //操作函数
extern uchar IapReadByte(uint addr);              //读取函数
extern void IapProgramByte(uint addr,uchar dat);  //写入函数
extern void IapEraseSector(uint addr);                  //擦除函数
/********************************************************************
                            波特率设定
*********************************************************************/
//#define BAUD 0XF400  //1200bps@ 11.0592MHZ
//#define BAUD 0XFA00  //2400bps@ 11.0592MHZ
//#define BAUD 0XFD00  //4800bps@ 11.0592MHZ
#define BAUD 0XFE80  //9600bps@ 11.0592MHZ
//#define BAUD 0XFF40  //19200bps@ 11.0592MHZ
//#define BAUD 0XFFA0  //38400bps@ 11.0592MHZ
uchar miao,fen,times;
uchar dat;      //用于存储单片机接收发送缓冲寄存器SBUF里面的内容
sbit P33=P3^3;  //定义输出脚

/********************************************************************
                            定义特殊寄存器
*********************************************************************/
sfr AUXR  =  0x8E;    //辅助寄存器
sbit RXB=P3^0;
sbit TXB=P3^1;
/********************************************************************
                           定义数据类型
*********************************************************************/
uchar TBUF,RBUF;
uchar TDAT,RDAT;
uchar TCNT,RCNT;
uchar TBIT,RBIT;
uint TING,RING;
uint TEND,REND;

void UART_INIT(); //声明函数

uchar t,r;                  //定义数据类型
uchar but[16];          //数据存储数组
/********************************************************************
                            寄存器设置
*********************************************************************/
sfr IAP_DATA  =0xc2;         //数据寄存器
sfr IAP_ADDRH =0xc3;         //地址寄存器
sfr IAP_ADDRL =0xc4;         //地址寄存器
sfr IAP_CMD   =0xc5;     //命令寄存器
sfr IAP_TRIG  =0xc6;          //触发寄存器
sfr IAP_CONTR =0xc7;     //擦除寄存器
/********************************************************************
                            命令定义
*********************************************************************/
#define CMD_IDLE     0         //EEPROM无操作
#define CMD_READ     1         //读取字节
#define CMD_PROGRAM  2         //写入字节
#define CMD_ERASE    3         //擦除字节
/********************************************************************
                       编程周期由晶振决定
*********************************************************************/
//#define ENABLE_IAP 0X80         //编程周期由晶振决定(如果<30MHZ选用此项)
//#define ENABLE_IAP 0X81         //编程周期由晶振决定(如果<24MHZ选用此项)
//#define ENABLE_IAP 0X82         //编程周期由晶振决定(如果<20MHZ选用此项)
  #define ENABLE_IAP 0X83         //编程周期由晶振决定(如果<12MHZ选用此项)
//#define ENABLE_IAP 0X84         //编程周期由晶振决定(如果<6MHZ选用此项)
//#define ENABLE_IAP 0X85         //编程周期由晶振决定(如果<3MHZ选用此项)
//#define ENABLE_IAP 0X86         //编程周期由晶振决定(如果<2MHZ选用此项)
//#define ENABLE_IAP 0X87         //编程周期由晶振决定(如果<1MHZ选用此项)

#define IAP_ADDRESS 0X0000                      //内部EEPROM地址
/********************************************************************
                            延时函数
*********************************************************************/
void delay(uchar t)
{
  uchar i,j;
   for(i=0;i<t;i++)
   {
            for(j=13;j>0;j--);
         { ;
         }
   }
}
/********************************************************************
                            定时器0初始化函数
*********************************************************************/
void TIMER0_INIT(void)
{
        TMOD=0X00;           //定时器T0设定
        AUXR|=0X80;           //辅助寄存器
        TL0=BAUD;           //十六位寄存器
        TH0=BAUD>>8;   //十六位寄存器
        TR0=1;                   //开定时器
        ET0=1;
        PT0=1;
}
/********************************************************************
                            定时器1初始化函数
*********************************************************************/
void TIMER1_INIT(void)
{
           TH1=(65536-10000)/256;   //对TH1 TL1赋值
        TL1=(65536-10000)%256;
        ET1=1;
           TR1=1;                   //开始定时
}                       
/********************************************************************
                            外部中断0初始化
*********************************************************************/
void Init_exint(void)
{
   INT0=1;   //下降沿触发
   IT0=1;
   EX0=1;
}
/********************************************************************
              功能:串口初始化,波特率9600,方式1
*********************************************************************/
void UART_INIT()
{
        TING=0;
        RING=0;
       
        TEND=1;
        REND=0;
       
        TCNT=0;
        RCNT=0;
}

/********************************************************************
                       函数初始化
*********************************************************************/
void IapIdle();                                              //操作函数
uchar IapReadByte(uint addr);             //读取函数
void IapProgramByte(uint addr,uchar dat); //写入函数
void IapEraseSector(uint addr);                  //擦除函数

/********************************************************************
                            操作函数
*********************************************************************/
void IapIdle()
{
IAP_CONTR=0;
IAP_CMD=0;
IAP_TRIG=0;
IAP_ADDRH=0X80;
IAP_ADDRL=0;
}

/********************************************************************
                            读取一个字节函数
*********************************************************************/
uchar IapReadByte(uint addr)
{
uchar dat;  
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_READ;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
_nop_();
_nop_();
_nop_();
dat=IAP_DATA;
IapIdle();
return dat;
}

/********************************************************************
                            写入一个字节函数
*********************************************************************/
void IapProgramByte(uint addr,uchar dat)
{

IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_PROGRAM;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_DATA=dat;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
_nop_();
_nop_();
_nop_();
IapIdle();
}
/********************************************************************
                            擦除一个字节函数
*********************************************************************/
void IapEraseSector(uint addr)
{
IAP_CONTR=ENABLE_IAP;
IAP_CMD=CMD_ERASE;
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
_nop_();
_nop_();
_nop_();
IapIdle();
}

/********************************************************************
                            主函数
*********************************************************************/
void main()
{

    TIMER0_INIT(); //定时器0初始化模拟串口用
        TIMER1_INIT(); //定时器1初始化
        Init_exint();
        times=IapReadByte(0);              //读取函数
        EA=1;                   //开总中断
        UART_INIT();   //串口初始化

        while(1)          
        {
         if(REND)
         {
           REND=0;
           r++;
           //but[r++&0x0f]=RBUF;
           dat=RBUF;
         }
         if(TEND)
         {
           if(t!=r)
           {
                TEND=0;
            //TBUF=dat;
                switch(dat) //接收数据判断
                {
                        uchar k;
                        k=10;
                        case 'A': P33=1;delay(k);TBUF = dat;dat=0xee;break;           //  开
                        case 'B': P33=0;delay(k);TBUF = dat;dat=0xee;break;           //  关
                        case 'C': if(P33==1)
                                    TBUF = 'A';                                                                   //  串口读输出口状态
                                          if(P33==0)
                                            TBUF = 'B';
                                          delay(k);
                                          dat=0xee;
                                          break;                                           
                        case 'D': P33=!P33;delay(k);TBUF = dat;dat=0xee;break;  //  输出口取反
                        case 'E': delay(k);TBUF = times;dat=0xee;break;         //  串口读取当前设定值
                        default:break;                                          
                 }
                t++;
                 //TBUF=but[t++&0x0f];
            TING=1;
           }
   }
/********************************************************************
                            接收数据判断函数
*********************************************************************/

   }
}


/********************************************************************
                            定时器T0中断服务函数
*********************************************************************/
void tm0()interrupt 1 using 1
{
if(RING)
{
   if(--RCNT==0)
   {
        RCNT=3;
        if(--RBIT==0)
        {
         RBUF=RDAT;
         RING=0;
         REND=1;
        }
        else
        {
         RDAT>>=1;
         if(RXB)
          RDAT|=0X80;
        }

    }
  }

  else if(!RXB)
  {
         RING=1;
         RCNT=4;
         RBIT=9;
  }

if(--TCNT==0)
{
   TCNT=3;
   if(TING)
   {
     if(TBIT==0)
     {
          TXB=0;
          TDAT=TBUF;
          TBIT=9;
     }
         else
         {
           TDAT>>=1;
           if(--TBIT==0)
           {
             TXB=1;
             TING=0;
             TEND=1;
           }
       else
        TXB=CY;
                 
     }
  }
}
}

/********************************************************************
                            外部中断0服务函数
*********************************************************************/
void Extern0 (void) interrupt 0 using 0
{
  times++;
  if(times==20)                          //最大设定时间40秒
  times=0;
  IapEraseSector(0);                  //擦除0地址数据
  IapProgramByte(0,times);        //写入0地址数据

}
/********************************************************************
                            定时1中断服务函数
*********************************************************************/
void t1(void) interrupt 3 using 2
{

  miao++;
  if(miao==200)        //2秒
  {
   miao=0;
   fen++;
   if(fen==times) // times秒
   {
     fen=0;
         P33=!P33;         //IO口输出电平取反
   }
  }
}
/********************************************************************
                            结束
*********************************************************************/




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?加入中科因仑

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入中科因仑

本版积分规则

快速回复 返回顶部 返回列表