GPIO 模拟I2C

 
/*---------------------------------------------------------------------*/
/* --- STC MCU International Limited ----------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
/* --- Web: www.GXWMCU.com --------------------------------------------*/
/* --- QQ:  800003751 -------------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
/*---------------------------------------------------------------------*/
 
 
 
 
/*************    本程序功能说明    **************
 
读写RTC, IC为PCF8563.
 
用STC的MCU的IO方式控制74HC595驱动8位数码管。
 
用户可以修改宏来选择时钟频率.
使用Timer0的16位自动重装来产生1ms节拍,程序运行于这个节拍下, 用户修改MCU主时钟频率时,自动定时于1ms.
 
用户可以在显示函数里修改成共阴或共阳.推荐尽量使用共阴数码管.
 
8位数码管显示时间(小时-分钟-秒).
 
行列扫描按键键码为17~32.
 
按键只支持单键按下, 不支持多键同时按下, 那样将会有不可预知的结果.
 
键按下超过1秒后,将以10键/秒的速度提供重键输出. 用户只需要检测KeyCode是否非0来判断键是否按下.
 
调整时间键:
键码17: 小时+.
键码18: 小时-.
键码19: 分钟+.
键码20: 分钟-.
 
 
******************************************/
 
 
#define MAIN_Fosc        22118400L    //定义主时钟
 
#include    "STC15Fxxxx.H"
 
 
 
/***********************************************************/
 
#define DIS_DOT        0x20
#define DIS_BLACK    0x10
#define DIS_        0x11
 
 
/****************************** 用户定义宏 ***********************************/
 
 
#define    Timer0_Reload    (65536UL -(MAIN_Fosc / 1000))        //Timer 0 中断频率, 1000次/秒
 
/*****************************************************************************/
 
 
 
 
 
 
/*************    本地常量声明    **************/
u8 code t_display[]={                        //标准字库
//     0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black     -     H    J     K      L       N    o   P     U     t    G    Q    r   M    y
    0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
    0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
 
u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};        //位码
 
 
/*************    IO口定义    **************/
sbit    P_HC595_SER   = P4^0;    //pin 14    SER        data input
sbit    P_HC595_RCLK  = P5^4;    //pin 12    RCLk    store (latch) clock
sbit    P_HC595_SRCLK = P4^3;    //pin 11    SRCLK    Shift data clock
 
 
/*************    本地变量声明    **************/
 
u8     LED8[8];        //显示缓冲
u8    display_index;    //显示位索引
bit    B_1ms;            //1ms标志
 
u8 IO_KeyState, IO_KeyState1, IO_KeyHoldCnt;    //行列键盘变量
u8    KeyHoldCnt;    //键按下计时
u8    KeyCode;    //给用户使用的键码, 1~16有效
u8    cnt50ms;
 
u8    hour,minute,second;    //RTC变量
u16    msecond;
 
 
/*************    本地函数声明    **************/
void    CalculateAdcKey(u16 adc);
void    IO_KeyScan(void);    //50ms call
void    WriteNbyte(u8 addr, u8 *p, u8 number);
void    ReadNbyte( u8 addr, u8 *p, u8 number);
void    DisplayRTC(void);
void    ReadRTC(void);
void    WriteRTC(void);
 
 
/****************  外部函数声明和外部变量声明 *****************/
 
 
/**********************************************/
void main(void)
{
    u8    i;
 
    P0M1 = 0;    P0M0 = 0;    //设置为准双向口
    P1M1 = 0;    P1M0 = 0;    //设置为准双向口
    P2M1 = 0;    P2M0 = 0;    //设置为准双向口
    P3M1 = 0;    P3M0 = 0;    //设置为准双向口
    P4M1 = 0;    P4M0 = 0;    //设置为准双向口
    P5M1 = 0;    P5M0 = 0;    //设置为准双向口
    P6M1 = 0;    P6M0 = 0;    //设置为准双向口
    P7M1 = 0;    P7M0 = 0;    //设置为准双向口
    
    display_index = 0;
    
    AUXR = 0x80;    //Timer0 set as 1T, 16 bits timer auto-reload,  
    TH0 = (u8)(Timer0_Reload / 256);
    TL0 = (u8)(Timer0_Reload % 256);
    ET0 = 1;    //Timer0 interrupt enable
    TR0 = 1;    //Tiner0 run
    EA = 1;        //打开总中断
    
    for(i=0; i<8; i++)    LED8[i] = 0x10;    //上电消隐
 
    
    ReadRTC();
    F0 = 0;
    if(second >= 60)    F0 = 1;    //错误
    if(minute >= 60)    F0 = 1;    //错误
    if(hour   >= 24)    F0 = 1;    //错误
    if(F0)    //有错误, 默认12:00:00
    {
        second = 0;
        minute = 0;
        hour  = 12;
        WriteRTC();
    }
 
    DisplayRTC();
    LED8[2] = DIS_;
    LED8[5] = DIS_;
 
    KeyHoldCnt = 0;    //键按下计时
    KeyCode = 0;    //给用户使用的键码, 1~16有效
 
    IO_KeyState = 0;
    IO_KeyState1 = 0;
    IO_KeyHoldCnt = 0;
    cnt50ms = 0;
    
    while(1)
    {
        if(B_1ms)    //1ms到
        {
            B_1ms = 0;
            if(++msecond >= 1000)    //1秒到
            {
                msecond = 0;
                ReadRTC();
                DisplayRTC();
            }
 
            if(++cnt50ms >= 50)        //50ms扫描一次行列键盘
            {
                cnt50ms = 0;
                IO_KeyScan();
            }
            
            if(KeyCode != 0)        //有键按下
            {
                if(KeyCode == 17)    //hour +1
                {
                    if(++hour >= 24)    hour = 0;
                    WriteRTC();
                    DisplayRTC();
                }
                if(KeyCode == 18)    //hour -1
                {
                    if(--hour >= 24)    hour = 23;
                    WriteRTC();
                    DisplayRTC();
                }
                if(KeyCode == 19)    //minute +1
                {
                    second = 0;
                    if(++minute >= 60)    minute = 0;
                    WriteRTC();
                    DisplayRTC();
                }
                if(KeyCode == 20)    //minute -1
                {
                    second = 0;
                    if(--minute >= 60)    minute = 59;
                    WriteRTC();
                    DisplayRTC();
                }
 
                KeyCode = 0;
            }
 
        }
    }
}  
/**********************************************/
 
/********************** 显示时钟函数 ************************/
void    DisplayRTC(void)
{
    if(hour >= 10)    LED8[0] = hour / 10;
    else            LED8[0] = DIS_BLACK;
    LED8[1] = hour % 10;
    LED8[2] = DIS_;
    LED8[3] = minute / 10;
    LED8[4] = minute % 10;
    LED8[6] = second / 10;
    LED8[7] = second % 10;
}
 
/********************** 读RTC函数 ************************/
void    ReadRTC(void)
{
    u8    tmp[3];
 
    ReadNbyte(2, tmp, 3);
    second = ((tmp[0] >> 4) & 0x07) * 10 + (tmp[0] & 0x0f);
    minute = ((tmp[1] >> 4) & 0x07) * 10 + (tmp[1] & 0x0f);
    hour   = ((tmp[2] >> 4) & 0x03) * 10 + (tmp[2] & 0x0f);
}
 
/********************** 写RTC函数 ************************/
void    WriteRTC(void)
{
    u8    tmp[3];
 
    tmp[0] = ((second / 10) << 4) + (second % 10);
    tmp[1] = ((minute / 10) << 4) + (minute % 10);
    tmp[2] = ((hour / 10) << 4) + (hour % 10);
    WriteNbyte(2, tmp, 3);
}
 
 
/*****************************************************
    行列键扫描程序
    使用XY查找4x4键的方法,只能单键,速度快
 
   Y     P04      P05      P06      P07
          |        |        |        |
X         |        |        |        |
P00 ---- K00 ---- K01 ---- K02 ---- K03 ----
          |        |        |        |
P01 ---- K04 ---- K05 ---- K06 ---- K07 ----
          |        |        |        |
P02 ---- K08 ---- K09 ---- K10 ---- K11 ----
          |        |        |        |
P03 ---- K12 ---- K13 ---- K14 ---- K15 ----
          |        |        |        |
******************************************************/
 
 
u8 code T_KeyTable[16] = {0,1,2,0,3,0,0,0,4,0,0,0,0,0,0,0};
 
void IO_KeyDelay(void)
{
    u8 i;
    i = 60;
    while(--i)    ;
}
 
void    IO_KeyScan(void)    //50ms call
{
    u8    j;
 
    j = IO_KeyState1;    //保存上一次状态
 
    P0 = 0xf0;    //X低,读Y
    IO_KeyDelay();
    IO_KeyState1 = P0 & 0xf0;
 
    P0 = 0x0f;    //Y低,读X
    IO_KeyDelay();
    IO_KeyState1 |= (P0 & 0x0f);
    IO_KeyState1 ^= 0xff;    //取反
    
    if(j == IO_KeyState1)    //连续两次读相等
    {
        j = IO_KeyState;
        IO_KeyState = IO_KeyState1;
        if(IO_KeyState != 0)    //有键按下
        {
            F0 = 0;
            if(j == 0)    F0 = 1;    //第一次按下
            else if(j == IO_KeyState)
            {
                if(++IO_KeyHoldCnt >= 20)    //1秒后重键
                {
                    IO_KeyHoldCnt = 18;
                    F0 = 1;
                }
            }
            if(F0)
            {
                j = T_KeyTable[IO_KeyState >> 4];
                if((j != 0) && (T_KeyTable[IO_KeyState& 0x0f] != 0))  
                    KeyCode = (j - 1) * 4 + T_KeyTable[IO_KeyState & 0x0f] + 16;    //计算键码,17~32
            }
        }
        else    IO_KeyHoldCnt = 0;
    }
    P0 = 0xff;
}
 
 
 
 
/**************** 向HC595发送一个字节函数 ******************/
void Send_595(u8 dat)
{        
    u8    i;
    for(i=0; i<8; i++)
    {
        dat <<= 1;
        P_HC595_SER   = CY;
        P_HC595_SRCLK = 1;
        P_HC595_SRCLK = 0;
    }
}
 
/********************** 显示扫描函数 ************************/
void DisplayScan(void)
{    
    Send_595(~T_COM[display_index]);                //输出位码
    Send_595(t_display[LED8[display_index]]);    //输出段码
 
    P_HC595_RCLK = 1;
    P_HC595_RCLK = 0;                            //锁存输出数据
    if(++display_index >= 8)    display_index = 0;    //8位结束回0
}
 
 
/********************** Timer0 1ms中断函数 ************************/
void timer0 (void) interrupt TIMER0_VECTOR
{
    DisplayScan();    //1ms扫描显示一位
    B_1ms = 1;        //1ms标志
}
 
 
 
#define SLAW    0xA2
#define SLAR    0xA3
 
sbit    SDA    = P1^1;    //定义SDA  PIN5
sbit    SCL    = P1^0;    //定义SCL  PIN6
 
/****************************/
void    I2C_Delay(void)    //for normal MCS51,    delay (2 * dly + 4) T, for STC12Cxxxx delay (4 * dly + 10) T
{
    u8    dly;
    dly = MAIN_Fosc / 2000000UL;        //按2us计算
    while(--dly)    ;
}
 
/****************************/
void I2C_Start(void)               //start the I2C, SDA High-to-low when SCL is high
{
    SDA = 1;
    I2C_Delay();
    SCL = 1;
    I2C_Delay();
    SDA = 0;
    I2C_Delay();
    SCL = 0;
    I2C_Delay();
}        
 
 
void I2C_Stop(void)                    //STOP the I2C, SDA Low-to-high when SCL is high
{
    SDA = 0;
    I2C_Delay();
    SCL = 1;
    I2C_Delay();
    SDA = 1;
    I2C_Delay();
}
 
void S_ACK(void)              //Send ACK (LOW)
{
    SDA = 0;
    I2C_Delay();
    SCL = 1;
    I2C_Delay();
    SCL = 0;
    I2C_Delay();
}
 
void S_NoACK(void)           //Send No ACK (High)
{
    SDA = 1;
    I2C_Delay();
    SCL = 1;
    I2C_Delay();
    SCL = 0;
    I2C_Delay();
}
        
void I2C_Check_ACK(void)         //Check ACK, If F0=0, then right, if F0=1, then error
{
    SDA = 1;
    I2C_Delay();
    SCL = 1;
    I2C_Delay();
    F0  = SDA;
    SCL = 0;
    I2C_Delay();
}
 
/****************************/
void I2C_WriteAbyte(u8 dat)        //write a byte to I2C
{
    u8 i;
    i = 8;
    do
    {
        if(dat & 0x80)    SDA = 1;
        else            SDA    = 0;
        dat <<= 1;
        I2C_Delay();
        SCL = 1;
        I2C_Delay();
        SCL = 0;
        I2C_Delay();
    }
    while(--i);
}
 
/****************************/
u8 I2C_ReadAbyte(void)            //read A byte from I2C
{
    u8 i,dat;
    i = 8;
    SDA = 1;
    do
    {
        SCL = 1;
        I2C_Delay();
        dat <<= 1;
        if(SDA)        dat++;
        SCL  = 0;
        I2C_Delay();
    }
    while(--i);
    return(dat);
}
 
/****************************/
void WriteNbyte(u8 addr, u8 *p, u8 number)            /*    WordAddress,First Data Address,Byte lenth    */
                                                             //F0=0,right, F0=1,error
{
    I2C_Start();
    I2C_WriteAbyte(SLAW);
    I2C_Check_ACK();
    if(!F0)
    {
        I2C_WriteAbyte(addr);
        I2C_Check_ACK();
        if(!F0)
        {
            do
            {
                I2C_WriteAbyte(*p);        p++;
                I2C_Check_ACK();
                if(F0)    break;
            }
            while(--number);
        }
    }
    I2C_Stop();
}
 
 
/****************************/
     ReadNbyte(2, tmp, 3);
void ReadNbyte(u8 addr, u8 *p, u8 number)        /*    WordAddress,First Data Address,Byte lenth    */
{
    I2C_Start();
    I2C_WriteAbyte(SLAW);
    I2C_Check_ACK();
    if(!F0)
    {
        I2C_WriteAbyte(addr);
        I2C_Check_ACK();
        if(!F0)
        {
            I2C_Start();
            I2C_WriteAbyte(SLAR);
            I2C_Check_ACK();
            if(!F0)
            {
                do
                {
                    *p = I2C_ReadAbyte();    p++;
                    if(number != 1)        S_ACK();    //send ACK
                }
                while(--number);
                S_NoACK();            //send no ACK
            }
        }
    }
    I2C_Stop();
}
 
 
/****************************/
 

头文件

 
/*---------------------------------------------------------------------*/
/* --- STC MCU International Limited ----------------------------------*/
/* --- STC 1T Series MCU Demo Programme -------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ------------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966 ------------------------*/
/* --- Web: www.GXWMCU.com --------------------------------------------*/
/* --- QQ:  800003751 -------------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序   */
/*---------------------------------------------------------------------*/
 
 
 
#ifndef    _STC15Fxxxx_H
#define    _STC15Fxxxx_H
 
#include
 
/*  BYTE Registers  */
sfr P0   = 0x80;
sfr SP   = 0x81;
sfr DPL  = 0x82;
sfr DPH  = 0x83;
sfr    S4CON = 0x84;
sfr    S4BUF = 0x85;
sfr PCON = 0x87;
 
sfr TCON = 0x88;
sfr TMOD = 0x89;
sfr TL0  = 0x8A;
sfr TL1  = 0x8B;
sfr TH0  = 0x8C;
sfr TH1  = 0x8D;
sfr    AUXR = 0x8E;
sfr WAKE_CLKO = 0x8F;
sfr INT_CLKO = 0x8F;
sfr    AUXR2    = 0x8F;
 
sfr RL_TL0  = 0x8A;
sfr RL_TL1  = 0x8B;
sfr RL_TH0  = 0x8C;
sfr RL_TH1  = 0x8D;
 
 
sfr P1   = 0x90;
sfr P1M1 = 0x91;    //P1M1.n,P1M0.n     =00--->Standard,    01--->push-pull        实际上1T的都一样
sfr P1M0 = 0x92;    //                    =10--->pure input,    11--->open drain
sfr P0M1 = 0x93;    //P0M1.n,P0M0.n     =00--->Standard,    01--->push-pull
sfr P0M0 = 0x94;    //                    =10--->pure input,    11--->open drain
sfr P2M1 = 0x95;    //P2M1.n,P2M0.n     =00--->Standard,    01--->push-pull
sfr P2M0 = 0x96;    //                    =10--->pure input,    11--->open drain
sfr CLK_DIV = 0x97;
sfr PCON2   = 0x97;
 
sfr SCON  = 0x98;
sfr SBUF  = 0x99;
sfr S2CON = 0x9A;    //
sfr S2BUF = 0x9B;    //
sfr P1ASF = 0x9D;    //只写,模拟输入(AD或LVD)选择
 
sfr P2    = 0xA0;
sfr BUS_SPEED = 0xA1;
sfr AUXR1 = 0xA2;
sfr P_SW1 = 0xA2;
 
sfr IE    = 0xA8;
sfr SADDR = 0xA9;
sfr WKTCL = 0xAA;    //唤醒定时器低字节
sfr WKTCH = 0xAB;    //唤醒定时器高字节
sfr    S3CON = 0xAC;
sfr S3BUF = 0xAD;
sfr IE2   = 0xAF;    //STC12C5A60S2系列
 
sfr P3    = 0xB0;
sfr P3M1  = 0xB1;    //P3M1.n,P3M0.n     =00--->Standard,    01--->push-pull
sfr P3M0  = 0xB2;    //                    =10--->pure input,    11--->open drain
sfr P4M1  = 0xB3;    //P4M1.n,P4M0.n     =00--->Standard,    01--->push-pull
sfr P4M0  = 0xB4;    //                    =10--->pure input,    11--->open drain
sfr IP2   = 0xB5;    //STC12C5A60S2系列
sfr IPH2  = 0xB6;    //STC12C5A60S2系列
sfr IPH   = 0xB7;
 
sfr IP        = 0xB8;
sfr SADEN     = 0xB9;
sfr    P_SW2     = 0xBA;
sfr ADC_CONTR = 0xBC;    //带AD系列
sfr ADC_RES   = 0xBD;    //带AD系列
sfr ADC_RESL  = 0xBE;    //带AD系列
 
sfr P4        = 0xC0;
sfr WDT_CONTR = 0xC1;
sfr IAP_DATA  = 0xC2;
sfr IAP_ADDRH = 0xC3;
sfr IAP_ADDRL = 0xC4;
sfr IAP_CMD   = 0xC5;
sfr IAP_TRIG  = 0xC6;
sfr IAP_CONTR = 0xC7;
 
sfr ISP_DATA  = 0xC2;
sfr ISP_ADDRH = 0xC3;
sfr ISP_ADDRL = 0xC4;
sfr ISP_CMD   = 0xC5;
sfr ISP_TRIG  = 0xC6;
sfr ISP_CONTR = 0xC7;
 
sfr P5     = 0xC8;    //
sfr P5M1   = 0xC9;    //    P5M1.n,P5M0.n     =00--->Standard,    01--->push-pull
sfr P5M0   = 0xCA;    //                    =10--->pure input,    11--->open drain
sfr P6M1   = 0xCB;    //    P5M1.n,P5M0.n     =00--->Standard,    01--->push-pull
sfr P6M0   = 0xCC;    //                    =10--->pure input,    11--->open drain
sfr SPSTAT = 0xCD;    //
sfr SPCTL  = 0xCE;    //
sfr SPDAT  = 0xCF;    //
 
sfr PSW  = 0xD0;
sfr    T4T3M = 0xD1;
sfr    T4H  = 0xD2;
sfr    T4L  = 0xD3;
sfr    T3H  = 0xD4;
sfr    T3L  = 0xD5;
sfr    T2H  = 0xD6;
sfr    T2L  = 0xD7;
 
sfr    TH4  = 0xD2;
sfr    TL4  = 0xD3;
sfr    TH3  = 0xD4;
sfr    TL3  = 0xD5;
sfr    TH2  = 0xD6;
sfr    TL2  = 0xD7;
 
sfr    RL_T4H  = 0xD2;
sfr    RL_T4L  = 0xD3;
sfr    RL_T3H  = 0xD4;
sfr    RL_T3L  = 0xD5;
sfr    RL_T2H  = 0xD6;
sfr    RL_T2L  = 0xD7;
 
sfr CCON = 0xD8;    //
sfr CMOD = 0xD9;    //
sfr CCAPM0 = 0xDA;    //PCA模块0的工作模式寄存器。
sfr CCAPM1 = 0xDB;    //PCA模块1的工作模式寄存器。
sfr CCAPM2 = 0xDC;    //PCA模块2的工作模式寄存器。
 
sfr ACC    = 0xE0;
sfr    P7M1   = 0xE1;
sfr    P7M0   = 0xE2;
 
sfr    P6     = 0xE8;
sfr CL     = 0xE9;    //
sfr CCAP0L = 0xEA;    //PCA模块0的捕捉/比较寄存器低8位。
sfr CCAP1L = 0xEB;    //PCA模块1的捕捉/比较寄存器低8位。
sfr CCAP2L = 0xEC;    //PCA模块2的捕捉/比较寄存器低8位。
 
sfr B      = 0xF0;
sfr PCA_PWM0 = 0xF2;    //PCA模块0 PWM寄存器。
sfr PCA_PWM1 = 0xF3;    //PCA模块1 PWM寄存器。
sfr PCA_PWM2 = 0xF4;    //PCA模块2 PWM寄存器。
 
sfr    P7     = 0xF8;
sfr CH     = 0xF9;
sfr CCAP0H = 0xFA;        //PCA模块0的捕捉/比较寄存器高8位。
sfr CCAP1H = 0xFB;        //PCA模块1的捕捉/比较寄存器高8位。
sfr CCAP2H = 0xFC;        //PCA模块2的捕捉/比较寄存器高8位。
 
 
/*  BIT Registers  */
/*  PSW   */
sbit CY   = PSW^7;
sbit AC   = PSW^6;
sbit F0   = PSW^5;
sbit RS1  = PSW^4;
sbit RS0  = PSW^3;
sbit OV   = PSW^2;
sbit F1   = PSW^1;
sbit P    = PSW^0;
 
/*  TCON  */
sbit TF1  = TCON^7;    //定时器1溢出中断标志位
sbit TR1  = TCON^6;    //定时器1运行控制位
sbit TF0  = TCON^5;    //定时器0溢出中断标志位
sbit TR0  = TCON^4;    //定时器0运行控制位
sbit IE1  = TCON^3;    //外中断1标志位
sbit IT1  = TCON^2;    //外中断1信号方式控制位,1:下降沿中断,0:上升下降均中断。
sbit IE0  = TCON^1;    //外中断0标志位
sbit IT0  = TCON^0;    //外中断0信号方式控制位,1:下降沿中断,0:上升下降均中断。
 
/*  P0  */
sbit  P00 = P0^0;
sbit  P01 = P0^1;
sbit  P02 = P0^2;
sbit  P03 = P0^3;
sbit  P04 = P0^4;
sbit  P05 = P0^5;
sbit  P06 = P0^6;
sbit  P07 = P0^7;
 
/*  P1  */
sbit  P10 = P1^0;
sbit  P11 = P1^1;
sbit  P12 = P1^2;
sbit  P13 = P1^3;
sbit  P14 = P1^4;
sbit  P15 = P1^5;
sbit  P16 = P1^6;
sbit  P17 = P1^7;
 
sbit  RXD2      = P1^0;
sbit  TXD2      = P1^1;
sbit  CCP1      = P1^0;
sbit  CCP0      = P1^1;
sbit  SPI_SS    = P1^2;
sbit  SPI_MOSI  = P1^3;
sbit  SPI_MISO  = P1^4;
sbit  SPI_SCLK  = P1^5;
 
/*  P2  */
sbit  P20 = P2^0;
sbit  P21 = P2^1;
sbit  P22 = P2^2;
sbit  P23 = P2^3;
sbit  P24 = P2^4;
sbit  P25 = P2^5;
sbit  P26 = P2^6;
sbit  P27 = P2^7;
 
/*  P3  */
sbit  P30 = P3^0;
sbit  P31 = P3^1;
sbit  P32 = P3^2;
sbit  P33 = P3^3;
sbit  P34 = P3^4;
sbit  P35 = P3^5;
sbit  P36 = P3^6;
sbit  P37 = P3^7;
 
sbit RXD  = P3^0;
sbit TXD  = P3^1;
sbit INT0 = P3^2;
sbit INT1 = P3^3;
sbit T0   = P3^4;
sbit T1   = P3^5;
sbit WR   = P3^6;
sbit RD   = P3^7;
sbit CCP2  = P3^7;
 
sbit CLKOUT0   = P3^5;
sbit CLKOUT1   = P3^4;
 
/*  P4  */
sbit  P40 = P4^0;
sbit  P41 = P4^1;
sbit  P42 = P4^2;
sbit  P43 = P4^3;
sbit  P44 = P4^4;
sbit  P45 = P4^5;
sbit  P46 = P4^6;
sbit  P47 = P4^7;
 
/*  P5  */
sbit  P50 = P5^0;
sbit  P51 = P5^1;
sbit  P52 = P5^2;
sbit  P53 = P5^3;
sbit  P54 = P5^4;
sbit  P55 = P5^5;
sbit  P56 = P5^6;
sbit  P57 = P5^7;
 
/*  SCON  */
sbit SM0  = SCON^7;    //SM0/FE        SM0 SM1 = 00 ~ 11: 方式0~3
sbit SM1  = SCON^6;    //
sbit SM2  = SCON^5;    //多机通讯
sbit REN  = SCON^4;    //接收允许
sbit TB8  = SCON^3;    //发送数据第8位
sbit RB8  = SCON^2;    //接收数据第8位
sbit TI   = SCON^1;    //发送中断标志位
sbit RI   = SCON^0;    //接收中断标志位
 
/*  IE   */
sbit EA   = IE^7;    //中断允许总控制位
sbit ELVD = IE^6;    //低压监测中断允许位
sbit EADC = IE^5;    //ADC 中断 允许位
sbit ES   = IE^4;    //串行中断 允许控制位
sbit ET1  = IE^3;    //定时中断1允许控制位
sbit EX1  = IE^2;    //外部中断1允许控制位
sbit ET0  = IE^1;    //定时中断0允许控制位
sbit EX0  = IE^0;    //外部中断0允许控制位
 
 
/*  IP   */  
/*
sbit PPCA = IP^7;    //PCA 中断 优先级设定位
sbit PLVD = IP^6;     //低压中断 优先级设定位
sbit PADC = IP^5;     //ADC 中断 优先级设定位
sbit PS   = IP^4;    //串行中断0优先级设定位
sbit PT1  = IP^3;    //定时中断1优先级设定位
sbit PX1  = IP^2;    //外部中断1优先级设定位
sbit PT0  = IP^1;    //定时中断0优先级设定位
sbit PX0  = IP^0;    //外部中断0优先级设定位
*/
 
sbit ACC0 = ACC^0;
sbit ACC1 = ACC^1;
sbit ACC2 = ACC^2;
sbit ACC3 = ACC^3;
sbit ACC4 = ACC^4;
sbit ACC5 = ACC^5;
sbit ACC6 = ACC^6;
sbit ACC7 = ACC^7;
 
sbit B0 = B^0;
sbit B1 = B^1;
sbit B2 = B^2;
sbit B3 = B^3;
sbit B4 = B^4;
sbit B5 = B^5;
sbit B6 = B^6;
sbit B7 = B^7;
 
 
//                            7     6     5    4    3    2    1     0    Reset Value
//sfr IE2       = 0xAF;        -     -     -    -    -    -   ESPI  ES2   0000,0000B    //Auxiliary Interrupt    
#define        SPI_INT_ENABLE()        IE2 |=  2    //允许SPI中断
#define        SPI_INT_DISABLE()        IE2 &= ~2    //允许SPI中断
#define        UART2_INT_ENABLE()        IE2 |=  1    //允许串口2中断
#define        UART2_INT_DISABLE()        IE2 &= ~1    //允许串口2中断
 
//                                          7     6     5    4    3    2    1    0    Reset Value
//sfr IP      = 0xB8; //中断优先级低位      PPCA  PLVD  PADC  PS   PT1  PX1  PT0  PX0   0000,0000
//--------
sbit PPCA    = IP^7;    //PCA 模块中断优先级
sbit PLVD    = IP^6;    //低压监测中断优先级
sbit PADC    = IP^5;    //ADC 中断优先级
sbit PS       = IP^4;    //串行中断0优先级设定位
sbit PT1    = IP^3;    //定时中断1优先级设定位
sbit PX1    = IP^2;    //外部中断1优先级设定位
sbit PT0    = IP^1;    //定时中断0优先级设定位
sbit PX0    = IP^0;    //外部中断0优先级设定位
 
//                                           7      6      5     4     3     2    1     0        Reset Value
//sfr IPH   = 0xB7; //中断优先级高位       PPCAH  PLVDH  PADCH  PSH  PT1H  PX1H  PT0H  PX0H   0000,0000
//sfr IP2   = 0xB5; //                       -      -      -     -     -     -   PSPI   PS2   xxxx,xx00
//sfr IPH2  = 0xB6; //                       -      -      -     -     -     -   PSPIH  PS2H  xxxx,xx00
#define        PPCAH    0x80
#define        PLVDH    0x40
#define        PADCH    0x20
#define        PSH        0x10
#define        PT1H    0x08
#define        PX1H    0x04
#define        PT0H    0x02
#define        PX0H    0x01
 
#define        PCA_InterruptFirst()    PPCA = 1
#define        LVD_InterruptFirst()    PLVD = 1
#define        ADC_InterruptFirst()    PADC = 1
#define        UART1_InterruptFirst()    PS   = 1
#define        Timer1_InterruptFirst()    PT1  = 1
#define        INT1_InterruptFirst()    PX1  = 1
#define        Timer0_InterruptFirst()    PT0  = 1
#define        INT0_InterruptFirst()    PX0  = 1
 
 
 
/*************************************************************************************************/
#define        S1_DoubleRate()        PCON |= 0x80
#define        S1_SHIFT()            SCON &= 0x3f
#define        S1_8bit()            SCON |= 0x40
#define        S1_9bit()            SCON |= 0xc0
#define        S1_RX_Enable()        SCON |= 0x10
#define        S1_USE_P30P31()        P_SW1 &=  ~0xc0                    //UART1 使用P30 P31口    默认
#define        S1_USE_P36P37()        P_SW1 = (P_SW1 & ~0xc0) | 0x40    //UART1 使用P36 P37口
#define        S1_USE_P16P17()        P_SW1 = (P_SW1 & ~0xc0) | 0x80    //UART1 使用P16 P17口
#define        S1_TXD_RXD_SHORT()    PCON2 |= (1<<4)    //将TXD与RXD连接中继输出
#define        S1_TXD_RXD_OPEN()    PCON2 |= (1<<4)    //将TXD与RXD连接中继断开    默认
#define     S1_BRT_UseTimer2()    AUXR |=  1;
#define     S1_BRT_UseTimer1()    AUXR &= ~1;
 
//                          7      6      5      4      3      2     1     0        Reset Value
//sfr S2CON = 0x9A;        S2SM0    -    S2SM2  S2REN  S2TB8  S2RB8  S2TI  S2RI      00000000B         //S2 Control
 
#define        S2_8bit()            S2CON &= ~(1<<7)        //串口2模式0,8位UART,波特率 = 定时器2的溢出率 / 4
#define        S2_9bit()            S2CON |=  (1<<7)        //串口2模式1,9位UART,波特率 = 定时器2的溢出率 / 4
#define        S2_RX_Enable()        S2CON |=  (1<<4)        //允许串2接收
 
#define        S2_MODE0()            S2CON &= ~(1<<7)        //串口2模式0,8位UART,波特率 = 定时器2的溢出率 / 4
#define        S2_MODE1()            S2CON |=  (1<<7)        //串口2模式1,9位UART,波特率 = 定时器2的溢出率 / 4
#define        S2_RX_EN()            S2CON |=  (1<<4)                            //允许串2接收
#define        S2_RX_Disable()        S2CON &= ~(1<<4)                            //禁止串2接收
#define        TI2                    (S2CON & 2) != 0
#define        RI2                    (S2CON & 1) != 0
#define        SET_TI2()            S2CON |=  2
#define        CLR_TI2()            S2CON &= ~2
#define        CLR_RI2()            S2CON &= ~1
#define        S2TB8_SET()            S2CON |=  8
#define        S2TB8_CLR()            S2CON &= ~8
#define        S2_Int_en()            IE2   |=  1        //串口2允许中断
#define        S2_USE_P10P11()        P_SW2 &= ~1        //UART2 使用P1口    默认
#define        S2_USE_P46P47()        P_SW2 |=  1        //UART2 使用P4口
 
#define        S3_USE_P00P01()        P_SW2 &= ~2        //UART3 使用P0口    默认
#define        S3_USE_P50P51()        P_SW2 |=  2        //UART3 使用P5口
#define        S4_USE_P02P03()        P_SW2 &= ~4        //UART4 使用P0口    默认
#define        S4_USE_P52P53()        P_SW2 |=  4        //UART4 使用P5口
 
 
/**********************************************************/
 
#define        Timer0_16bitAutoReload()    TMOD &= ~0x03                    //16位自动重装
#define        Timer0_16bit()                TMOD  = (TMOD & ~0x03) | 0x01    //16位
#define        Timer0_8bitAutoReload()        TMOD  = (TMOD & ~0x03) | 0x02    //8位自动重装
#define        Timer0_16bitAutoRL_NoMask()    TMOD |=  0x03        //16位自动重装不可屏蔽中断
#define        Timer0_AsCounterP32()        TMOD |=  4        //时器0用做计数器
#define        Timer0_AsTimer()            TMOD &= ~4        //时器0用做定时器
#define        Timer0_ExtControlP34()        TMOD |=  4        //时器0由外部INT0高电平允许定时计数
#define     Timer0_Run()                 TR0 = 1                //允许定时器0计数
#define     Timer0_Stop()                 TR0 = 0                //禁止定时器0计数
#define     Timer0_InterruptEnable()    ET0 = 1                //允许Timer1中断.
#define     Timer0_InterruptDisable()    ET0 = 0                //禁止Timer1中断.
 
#define        Timer1_16bitAutoReload()    TMOD &= ~0x30                    //16位自动重装
#define        Timer1_16bit()                TMOD  = (TMOD & ~0x30) | 0x10    //16位
#define        Timer1_8bitAutoReload()        TMOD  = (TMOD & ~0x30) | 0x20    //8位自动重装
#define        Timer1_16bitAutoRL_NoMask()    TMOD |=  0x30        //16位自动重装不可屏蔽中断
#define        Timer1_AsCounterP33()        TMOD |=  (1<<6)        //时器1用做计数器
#define        Timer1_AsTimer()            TMOD &= ~(1<<6)        //时器1用做定时器
#define        Timer1_ExtControlP35()        TMOD |=  (1<<7)        //时器1由外部INT1高电平允许定时计数
#define     Timer1_Run()                 TR1 = 1                //允许定时器1计数
#define     Timer1_Stop()                 TR1 = 0                //禁止定时器1计数
#define     Timer1_InterruptEnable()    ET1 = 1                //允许Timer1中断.
#define     Timer1_InterruptDisable()    ET1 = 0                //禁止Timer1中断.
 
 
//                           7     6       5      4     3      2      1      0    Reset Value
//sfr AUXR  = 0x8E;        T0x12 T1x12 UART_M0x6  BRTR S2SMOD BRTx12 EXTRAM S1BRS  0000,0000    //Auxiliary Register  
 
#define     Timer0_1T()                    AUXR |=  (1<<7)    //Timer0 clodk = fo
#define     Timer0_12T()                AUXR &= ~(1<<7)    //Timer0 clodk = fo/12    12分频,    default
#define     Timer1_1T()                    AUXR |=  (1<<6)    //Timer1 clodk = fo
#define     Timer1_12T()                AUXR &= ~(1<<6)    //Timer1 clodk = fo/12    12分频,    default
#define        S1_M0x6()                    AUXR |=  (1<<5)    //UART Mode0 Speed is 6x Standard
#define        S1_M0x1()                    AUXR &= ~(1<<5)    //default,    UART Mode0 Speed is Standard
#define     Timer2_Run()                 AUXR |=  (1<<4)    //允许定时器2计数
#define     Timer2_Stop()                 AUXR &= ~(1<<4)    //禁止定时器2计数
#define        Timer2_AsCounterP31()        AUXR |=  (1<<3)    //时器2用做计数器
#define        Timer2_AsTimer()            AUXR &= ~(1<<3)    //时器2用做定时器
#define     Timer2_1T()                    AUXR |=  (1<<2)    //Timer0 clodk = fo
#define     Timer2_12T()                AUXR &= ~(1<<2)    //Timer0 clodk = fo/12    12分频,    default
#define     Timer2_InterruptEnable()    IE2  |=  (1<<2)    //允许Timer2中断.
#define     Timer2_InterruptDisable()    IE2  &= ~(1<<2)    //禁止Timer2中断.
 
#define     ExternalRAM_enable()        AUXR |=  2        //允许外部XRAM,禁止使用内部1024RAM
#define     InternalRAM_enable()        AUXR &= ~2        //禁止外部XRAM,允许使用内部1024RAM
 
#define        T0_pulseP34_enable()        AUXR2 |=  1        //允许 T0 溢出脉冲在T0(P3.5)脚输出,Fck0 = 1/2 T0 溢出率,T0可以1T或12T。
#define        T0_pulseP34_disable()        AUXR2 &= ~1
#define        T1_pulseP35_enable()        AUXR2 |=  2        //允许 T1 溢出脉冲在T1(P3.4)脚输出,Fck1 = 1/2 T1 溢出率,T1可以1T或12T。
#define        T1_pulseP35_disable()        AUXR2 &= ~2
#define        T2_pulseP30_enable()        AUXR2 |=  4        //允许 T2 溢出脉冲在T1(P3.0)脚输出,Fck2 = 1/2 T2 溢出率,T2可以1T或12T。
#define        T2_pulseP30_disable()        AUXR2 &= ~4
 
#define        T0_pulseP35(n)        ET0=0,Timer0_AsTimer(),Timer0_1T(),Timer0_16bitAutoReload(),TH0=(65536-(n/2+MAIN_Fosc/2)/(n))/256,TL0=(65536-(n/2+MAIN_Fosc/2)/(n))%256,AUXR2 |= bit0,TR0=1        //fx=fosc/(2*M)/n,  M=1 or M=12
#define        T1_pulseP34(n)        ET1=0,Timer1_AsTimer(),Timer1_1T(),Timer1_16bitAutoReload(),TH1=(65536-(n/2+MAIN_Fosc/2)/(n))/256,TL1=(65536-(n/2+MAIN_Fosc/2)/(n))%256,AUXR2 |= bit1,TR1=1        //fx=fosc/(2*M)/n,  M=1 or M=12
#define        T2_pulseP30(n)        Timer2_InterruptDisable(),Timer2_AsTimer(),Timer2_1T(),TH2=(65536-(n/2+MAIN_Fosc/2)/(n))/256,TL2=(65536-(n/2+MAIN_Fosc/2)/(n))%256,AUXR2 |= bit2,Timer2_Run()    //fx=fosc/(2*M)/n,  M=1 or M=12
 
#define        Timer0_Load(n)        TH0 = (n) / 256,    TL0 = (n) % 256
#define        Timer1_Load(n)        TH1 = (n) / 256,    TL1 = (n) % 256
#define        Timer2_Load(n)        TH2 = (n) / 256,    TL2 = (n) % 256
 
#define        Timer0_Load_us(n)    TH0=(65536-MainFosc_KHZ*(n)/1000)/256,TL0=(65536-MainFosc_KHZ*(n)/1000)%256
#define        Timer1_Load_us(n)    TH1=(65536-MainFosc_KHZ*(n)/1000)/256,TL1=(65536-MainFosc_KHZ*(n)/1000)%256
#define        Timer2_Load_us(n)    TH2=(65536-MainFosc_KHZ*(n)/1000)/256,TL2=(65536-MainFosc_KHZ*(n)/1000)%256
 
 
//sfr WDT_CONTR = 0xC1; //Watch-Dog-Timer Control register
//                                      7     6     5      4       3      2   1   0     Reset Value
//                                  WDT_FLAG  -  EN_WDT CLR_WDT IDLE_WDT PS2 PS1 PS0    xx00,0000
#define D_WDT_FLAG            (1<<7)
#define D_EN_WDT            (1<<5)
#define D_CLR_WDT            (1<<4)    //auto clear
#define D_IDLE_WDT            (1<<3)    //WDT counter when Idle
#define D_WDT_SCALE_2        0
#define D_WDT_SCALE_4        1
#define D_WDT_SCALE_8        2        //T=393216*N/fo
#define D_WDT_SCALE_16        3
#define D_WDT_SCALE_32        4
#define D_WDT_SCALE_64        5
#define D_WDT_SCALE_128        6
#define D_WDT_SCALE_256        7
 
#define    WDT_reset(n)    WDT_CONTR = D_EN_WDT + D_CLR_WDT + D_IDLE_WDT + (n)        //初始化WDT,喂狗
 
 
//                          7     6      5    4     3      2    1     0     Reset Value
//sfr PCON   = 0x87;    SMOD  SMOD0  LVDF  POF   GF1    GF0   PD   IDL    0001,0000     //Power Control  
//SMOD        //串口双倍速
//SMOD0
#define        LVDF        (1<<5)    //P4.6低压检测标志
//POF
//GF1
//GF0
//#define     D_PD        2        //set 1, power down mode
//#define     D_IDLE        1        //set 1, idle mode
#define        MCU_IDLE()            PCON |= 1    //MCU 进入 IDLE 模式
#define        MCU_POWER_DOWN()    PCON |= 2    //MCU 进入 睡眠 模式
 
 
//sfr ISP_CMD   = 0xC5;
#define        ISP_STANDBY()    ISP_CMD = 0        //ISP空闲命令(禁止)
#define        ISP_READ()        ISP_CMD = 1        //ISP读出命令
#define        ISP_WRITE()        ISP_CMD = 2        //ISP写入命令
#define        ISP_ERASE()        ISP_CMD = 3        //ISP擦除命令
 
//sfr ISP_TRIG  = 0xC6;
#define     ISP_TRIG()    ISP_TRIG = 0x5A,    ISP_TRIG = 0xA5        //ISP触发命令
 
//                              7    6    5      4    3    2    1     0    Reset Value
//sfr IAP_CONTR = 0xC7;        IAPEN SWBS SWRST CFAIL  -   WT2  WT1   WT0   0000,x000    //IAP Control Register
#define ISP_EN            (1<<7)
#define ISP_SWBS        (1<<6)
#define ISP_SWRST        (1<<5)
#define ISP_CMD_FAIL    (1<<4)
#define ISP_WAIT_1MHZ    7
#define ISP_WAIT_2MHZ    6
#define ISP_WAIT_3MHZ    5
#define ISP_WAIT_6MHZ    4
#define ISP_WAIT_12MHZ    3
#define ISP_WAIT_20MHZ    2
#define ISP_WAIT_24MHZ    1
#define ISP_WAIT_30MHZ    0
 
#if (MAIN_Fosc >= 24000000L)
    #define        ISP_WAIT_FREQUENCY    ISP_WAIT_30MHZ
#elif (MAIN_Fosc >= 20000000L)
    #define        ISP_WAIT_FREQUENCY    ISP_WAIT_24MHZ
#elif (MAIN_Fosc >= 12000000L)
    #define        ISP_WAIT_FREQUENCY    ISP_WAIT_20MHZ
#elif (MAIN_Fosc >= 6000000L)
    #define        ISP_WAIT_FREQUENCY    ISP_WAIT_12MHZ
#elif (MAIN_Fosc >= 3000000L)
    #define        ISP_WAIT_FREQUENCY    ISP_WAIT_6MHZ
#elif (MAIN_Fosc >= 2000000L)
    #define        ISP_WAIT_FREQUENCY    ISP_WAIT_3MHZ
#elif (MAIN_Fosc >= 1000000L)
    #define        ISP_WAIT_FREQUENCY    ISP_WAIT_2MHZ
#else
    #define        ISP_WAIT_FREQUENCY    ISP_WAIT_1MHZ
#endif
 
 
 
/* ADC Register */
//                                7       6      5       4         3      2    1    0   Reset Value
//sfr ADC_CONTR = 0xBC;        ADC_POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0 0000,0000    //AD 转换控制寄存器  
//sfr ADC_RES  = 0xBD;        ADCV.9 ADCV.8 ADCV.7 ADCV.6 ADCV.5 ADCV.4 ADCV.3 ADCV.2      0000,0000    //A/D 转换结果高8位  
//sfr ADC_RESL = 0xBE;                                                  ADCV.1 ADCV.0      0000,0000    //A/D 转换结果低2位
//sfr ADC_CONTR  = 0xBC;    //直接用MOV操作,不要用与或
 
 
//sfr SPCTL  = 0xCE;    SPI控制寄存器
//   7       6       5       4       3       2       1       0        Reset Value
//    SSIG    SPEN    DORD    MSTR    CPOL    CPHA    SPR1    SPR0        0x00
 
#define    SPI_SSIG_None()        SPCTL |=  (1<<7)        //1: 忽略SS脚
#define    SPI_SSIG_Enable()    SPCTL &= ~(1<<7)        //0: SS脚用于决定主从机
#define    SPI_Enable()        SPCTL |=  (1<<6)        //1: 允许SPI
#define    SPI_Disable()        SPCTL &= ~(1<<6)        //0: 禁止SPI
#define    SPI_LSB_First()        SPCTL |=  (1<<5)        //1: LSB先发
#define    SPI_MSB_First()        SPCTL &= ~(1<<5)        //0: MSB先发
#define    SPI_Master()        SPCTL |=  (1<<4)        //1: 设为主机
#define    SPI_Slave()            SPCTL &= ~(1<<4)        //0: 设为从机
#define    SPI_SCLK_NormalH()    SPCTL |=  (1<<3)        //1: 空闲时SCLK为高电平
#define    SPI_SCLK_NormalL()    SPCTL &= ~(1<<3)        //0: 空闲时SCLK为低电平
#define    SPI_PhaseH()        SPCTL |=  (1<<2)        //1:  
#define    SPI_PhaseL()        SPCTL &= ~(1<<2)        //0:  
#define    SPI_Speed(n)        SPCTL = (SPCTL & ~3) | (n)    //设置速度, 0 -- fosc/4, 1 -- fosc/16, 2 -- fosc/64, 3 -- fosc/128
 
//sfr SPDAT  = 0xCF; //SPI Data Register                                                     0000,0000
//sfr SPSTAT  = 0xCD;    //SPI状态寄存器
//   7       6      5   4   3   2   1   0        Reset Value
//    SPIF    WCOL    -    -    -    -    -    -
#define    SPIF    0x80        //SPI传输完成标志。写入1清0。
#define    WCOL    0x40        //SPI写冲突标志。写入1清0。
 
#define        SPI_USE_P12P13P14P15()    AUXR1 &= 0x0c    //将SPI切换到P12(SS) P13(MOSI) P14(MISO) P15(SCLK)(上电默认)。
#define        SPI_USE_P24P23P22P21()    AUXR1 = (AUXR1 & ~0x0c) | 0x04    //将SPI切换到P24(SS) P23(MOSI) P22(MISO) P21(SCLK)。
#define        SPI_USE_P54P40P41P43()    AUXR1 = (AUXR1 & ~0x0c) | 0x08    //将SPI切换到P54(SS) P40(MOSI) P41(MISO) P43(SCLK)。
 
 
/*
;PCA_PWMn:    7       6     5   4   3   2     1       0
;            EBSn_1    EBSn_0    -    -    -    -    EPCnH    EPCnL
;B5-B2:        保留
;B1(EPCnH):    在PWM模式下,与CCAPnH组成9位数。
;B0(EPCnL):    在PWM模式下,与CCAPnL组成9位数。
*/
#define        PWM0_NORMAL()    PCA_PWM0 &= ~3                //PWM0正常输出(默认)
#define        PWM0_OUT_0()    PCA_PWM0 |=  3                //PWM0一直输出0
#define        PWM0_OUT_1()    PCA_PWM0 &= ~3, CCAP0H = 0;    //PWM0一直输出1
 
#define        PWM1_NORMAL()    PCA_PWM1 &= ~3                //PWM0正常输出(默认)
#define        PWM1_OUT_0()    PCA_PWM1 |=  3                //PWM0一直输出0
#define        PWM1_OUT_1()    PCA_PWM1 &= ~3, CCAP1H = 0;    //PWM1一直输出1
 
#define        PWM2_NORMAL()    PCA_PWM2 &= ~3                //PWM1正常输出(默认)
#define        PWM2_OUT_0()    PCA_PWM2 |=  3                //PWM2一直输出0
#define        PWM2_OUT_1()    PCA_PWM2 &= ~3, CCAP2H = 0;    //PWM2一直输出1
 
 
//                        7     6     5     4     3     2     1     0     Reset Value
//sfr CCON   = 0xD8;    CF    CR    -     -     -    CCF2  CCF1  CCF0   00xx,xx00    //PCA 控制寄存器。
sbit CCF0  = CCON^0;    //PCA 模块0中断标志,由硬件置位,必须由软件清0。
sbit CCF1  = CCON^1;    //PCA 模块1中断标志,由硬件置位,必须由软件清0。
sbit CCF2  = CCON^2;    //PCA 模块2中断标志,由硬件置位,必须由软件清0。
sbit CR    = CCON^6;    //1: 允许PCA计数器计数,必须由软件清0。
sbit CF    = CCON^7;    //PCA计数器溢出(CH,CL由FFFFH变为0000H)标志。PCA计数器溢出后由硬件置位,必须由软件清0。
 
//                     7     6     5     4     3     2     1     0    Reset Value
//sfr CMOD  = 0xD9;    CIDL   -     -     -   CPS2   CPS1  CPS0  ECF   0xxx,0000    //PCA 工作模式寄存器。
#define PCA_IDLE_OFF()        CMOD |=  (1<<7)                //IDLE状态PCA停止计数。
#define PCA_IDLE_ON()        CMOD &= ~(1<<7)                //IDLE状态PCA继续计数。
#define PCA_CLK_12T()        CMOD &= ~0x0E                //PCA计数脉冲选择外部晶振/12。    fosc/12
#define PCA_CLK_2T()        CMOD = (CMOD & ~0x0E) + 2    //PCA计数脉冲选择外部晶振/2。    fosc/2
#define PCA_CLK_T0()        CMOD = (CMOD & ~0x0E) + 4    //PCA计数脉冲选择Timer0中断,Timer0可通过AUXR寄存器设置成工作在12T或1T模式。
#define PCA_CLK_ECI()        CMOD = (CMOD & ~0x0E) + 6    //PCA计数脉冲选择从ECI/P3.4脚输入的外部时钟,最大 fosc/2。
#define PCA_CLK_1T()        CMOD = (CMOD & ~0x0E) + 8    //PCA计数脉冲选择外部晶振。        Fosc/1
#define PCA_CLK_4T()        CMOD = (CMOD & ~0x0E) + 10    //PCA计数脉冲选择外部晶振/4。    Fosc/4
#define PCA_CLK_6T()        CMOD = (CMOD & ~0x0E) + 12    //PCA计数脉冲选择外部晶振/6。    Fosc/6
#define PCA_CLK_8T()        CMOD = (CMOD & ~0x0E) + 14    //PCA计数脉冲选择外部晶振/8。    Fosc/8
#define PCA_INT_ENABLE()    CMOD |=  1                    //PCA计数器溢出中断允许位,1---允许CF(CCON.7)产生中断。
#define PCA_INT_DISABLE()    CMOD &= ~1                    //PCA计数器溢出中断禁止。
 
//                        7      6       5        4       3       2       1      0    Reset Value
//sfr AUXR1 = 0xA2;      S1_S1  S1_S0  CCP_S1   CCP_S0  SPI_S1   SPI_S0    -     DPS   0100,0000    //Auxiliary Register 1
 
#define        PCA_USE_P12P11P10P37()    AUXR1 &= ~0x30        //将PCA/PWM切换到P12(ECI) P11(CCP0) P10(CCP1) P37(CCP2)(上电默认)。
#define        PCA_USE_P34P35P36P37()    AUXR1 = (AUXR1 & ~0x30) | 0x10    //将PCA/PWM切换到P34(ECI) P35(CCP0) P36(CCP1) P37(CCP2)。
#define        PCA_USE_P24P25P26P27()    AUXR1 = (AUXR1 & ~0x30) | 0x20    //将PCA/PWM切换到P24(ECI) P25(CCP0) P26(CCP1) P27(CCP2)。
 
#define        DPS_SEL1()        AUXR1 |=  1        //1:选择DPTR1。
#define        DPS_SEL0()        AUXR1 &= ~1        //0:选择DPTR0(上电默认)。
 
 
/*                                    7     6      5      4     3     2     1     0     Reset Value
//sfr CCAPM0 = 0xDA;    PWM 寄存器  -   ECOM0  CAPP0  CAPN0  MAT0  TOG0  PWM0  ECCF0   x000,0000    //PCA 模块0  
//sfr CCAPM1 = 0xDB;    PWM 寄存器  -   ECOM1  CAPP1  CAPN1  MAT1  TOG1  PWM1  ECCF1   x000,0000    //PCA 模块1
//sfr CCAPM2 = 0xDC;    PWM 寄存器  -   ECOM2  CAPP2  CAPN2  MAT2  TOG2  PWM2  ECCF2   x000,0000    //PCA 模块2
;ECOMn = 1:    允许比较功能。
;CAPPn = 1:    允许上升沿触发捕捉功能。
;CAPNn = 1:    允许下降沿触发捕捉功能。
;MATn  = 1:    当匹配情况发生时,允许CCON中的CCFn置位。
;TOGn  = 1:    当匹配情况发生时,CEXn将翻转。(CEX0/PCA0/PWM0/P3.7,CEX1/PCA1/PWM1/P3.5)
;PWMn  = 1:    将CEXn设置为PWM输出。
;ECCFn = 1:    允许CCON中的CCFn触发中断。
;ECOMn CAPPn CAPNn MATn TOGn PWMn ECCFn
;  0     0     0    0    0    0     0        00H    未启用任何功能。
;  x     1     0    0    0    0     x         20H    16位CEXn上升沿触发捕捉功能。
;  x     0     1    0    0    0     x         10H    16位CEXn下降沿触发捕捉功能。
;  x     1     1    0    0    0     x         30H    16位CEXn/PCAn边沿(上、下沿)触发捕捉功能。
;  1     0     0    1    0    0     x         48H    16位软件定时器。
;  1     0     0    1    1    0     x         4CH    16位高速脉冲输出。
;  1     0     0    0    0    1     0        42H    8位PWM。无中断
;  1     1     0    0    0    1     1        63H    8位PWM。低变高可产生中断
;  1     0     1    0    0    1     1        53H    8位PWM。高变低可产生中断
;  1     1     1    0    0    1     1        73H    8位PWM。低变高或高变低均可产生中断
;*******************************************************************
;*******************************************************************/
#define        PCA0_none()                CCAPM0 = 0
#define        PCA0_PWM(nbit)            CCAPM0 = 0x42,PCA_PWM0 = (PCA_PWM0 & 0x0c) | ((8-nbit)<<6)
#define        PCA0_PWM_rise_int(nbit) CCAPM0 = 0x63,PCA_PWM0 = (PCA_PWM0 & 0x0c) | ((8-nbit)<<6)
#define        PCA0_PWM_fall_int(nbit) CCAPM0 = 0x53,PCA_PWM0 = (PCA_PWM0 & 0x0c) | ((8-nbit)<<6)
#define        PCA0_PWM_edge_int(nbit) CCAPM0 = 0x73,PCA_PWM0 = (PCA_PWM0 & 0x0c) | ((8-nbit)<<6)
#define        PCA0_capture_rise()        CCAPM0 = (0x20 + 1)
#define        PCA0_capture_fall()        CCAPM0 = (0x10 + 1)
#define        PCA0_capture_edge()        CCAPM0 = (0x30 + 1)
#define        PCA0_16bit_Timer()        CCAPM0 = (0x48 + 1)
#define        PCA0_High_Pulse()        CCAPM0 = (0x4C + 1)
 
#define        PCA1_none()                CCAPM1 = 0
#define        PCA1_PWM(nbit)            CCAPM1 = 0x42,PCA_PWM1 = (PCA_PWM1 & 0x0c) | ((8-nbit)<<6)
#define        PCA1_PWM_rise_int(nbit) CCAPM1 = 0x63,PCA_PWM1 = (PCA_PWM1 & 0x0c) | ((8-nbit)<<6)
#define        PCA1_PWM_fall_int(nbit) CCAPM1 = 0x53,PCA_PWM1 = (PCA_PWM1 & 0x0c) | ((8-nbit)<<6)
#define        PCA1_PWM_edge_int(nbit) CCAPM1 = 0x73,PCA_PWM1 = (PCA_PWM1 & 0x0c) | ((8-nbit)<<6)
#define        PCA1_capture_rise()        CCAPM1 = (0x20 + 1)
#define        PCA1_capture_fall()        CCAPM1 = (0x10 + 1)
#define        PCA1_capture_edge()        CCAPM1 = (0x30 + 1)
#define        PCA1_16bit_Timer()        CCAPM1 = (0x48 + 1)
#define        PCA1_High_Pulse()        CCAPM1 = (0x4C + 1)
 
#define        PCA2_none()                CCAPM2 = 0
#define        PCA2_PWM(nbit)            CCAPM2 = 0x42,PCA_PWM2 = (PCA_PWM2 & 0x0c) | ((8-nbit)<<6)
#define        PCA2_PWM_rise_int(nbit) CCAPM2 = 0x63,PCA_PWM2 = (PCA_PWM2 & 0x0c) | ((8-nbit)<<6)
#define        PCA2_PWM_fall_int(nbit) CCAPM2 = 0x53,PCA_PWM2 = (PCA_PWM2 & 0x0c) | ((8-nbit)<<6)
#define        PCA2_PWM_edge_int(nbit) CCAPM2 = 0x73,PCA_PWM2 = (PCA_PWM2 & 0x0c) | ((8-nbit)<<6)
#define        PCA2_capture_rise()        CCAPM2 = (0x20 + 1)
#define        PCA2_capture_fall()        CCAPM2 = (0x10 + 1)
#define        PCA2_capture_edge()        CCAPM2 = (0x30 + 1)
#define        PCA2_16bit_Timer()        CCAPM2 = (0x48 + 1)
#define        PCA2_High_Pulse()        CCAPM2 = (0x4C + 1)
 
/* Above is STC additional SFR or change */
 
 
 
 
/**********************************************************/
typedef     unsigned char    u8;
typedef     unsigned int    u16;
typedef     unsigned long    u32;
 
/**********************************************************/
#define NOP1()  _nop_()
#define NOP2()  NOP1(),NOP1()
#define NOP3()  NOP2(),NOP1()
#define NOP4()  NOP3(),NOP1()
#define NOP5()  NOP4(),NOP1()
#define NOP6()  NOP5(),NOP1()
#define NOP7()  NOP6(),NOP1()
#define NOP8()  NOP7(),NOP1()
#define NOP9()  NOP8(),NOP1()
#define NOP10() NOP9(),NOP1()
#define NOP11() NOP10(),NOP1()
#define NOP12() NOP11(),NOP1()
#define NOP13() NOP12(),NOP1()
#define NOP14() NOP13(),NOP1()
#define NOP15() NOP14(),NOP1()
#define NOP16() NOP15(),NOP1()
#define NOP17() NOP16(),NOP1()
#define NOP18() NOP17(),NOP1()
#define NOP19() NOP18(),NOP1()
#define NOP20() NOP19(),NOP1()
#define NOP21() NOP20(),NOP1()
#define NOP22() NOP21(),NOP1()
#define NOP23() NOP22(),NOP1()
#define NOP24() NOP23(),NOP1()
#define NOP25() NOP24(),NOP1()
#define NOP26() NOP25(),NOP1()
#define NOP27() NOP26(),NOP1()
#define NOP28() NOP27(),NOP1()
#define NOP29() NOP28(),NOP1()
#define NOP30() NOP29(),NOP1()
#define NOP31() NOP30(),NOP1()
#define NOP32() NOP31(),NOP1()
#define NOP33() NOP32(),NOP1()
#define NOP34() NOP33(),NOP1()
#define NOP35() NOP34(),NOP1()
#define NOP36() NOP35(),NOP1()
#define NOP37() NOP36(),NOP1()
#define NOP38() NOP37(),NOP1()
#define NOP39() NOP38(),NOP1()
#define NOP40() NOP39(),NOP1()
#define NOP(N)  NOP##N()
 
 
/**********************************************/
 
 
/****************************************************************/
 
 
//sfr INT_CLKO = 0x8F;    //附加的 SFR WAKE_CLKO (地址:0x8F)
/*
    7   6    5    4   3     2        1       0         Reset Value
    -  EX4  EX3  EX2  -   T2CLKO   T1CLKO  T0CLKO      0000,0000B
b6 -  EX4      : 外中断INT4允许
b5 -  EX3      : 外中断INT3允许
b4 -  EX2      : 外中断INT2允许
b2 - T1CLKO    : 允许 T2 溢出脉冲在P3.0脚输出,Fck1 = 1/2 T1 溢出率
b1 - T1CLKO    : 允许 T1 溢出脉冲在P3.4脚输出,Fck1 = 1/2 T1 溢出率
b0 - T0CLKO    : 允许 T0 溢出脉冲在P3.5脚输出,Fck0 = 1/2 T0 溢出率
*/
 
#define        LVD_InterruptEnable()        ELVD = 1
#define        LVD_InterruptDisable()        ELVD = 0
 
 
//sfr WKTCL = 0xAA;    //STC11F\10和STC15系列 唤醒定时器低字节
//sfr WKTCH = 0xAB;    //STC11F\10和STC15系列 唤醒定时器高字节
//    B7        B6    B5    B4    B3    B2    B1    B0        B7    B6    B5    B4    B3    B2    B1    B0
//    WKTEN                S11    S10    S9    S8        S7    S6    S5    S4    S3    S2    S1    S0    n * 560us
#define        WakeTimerDisable()        WKTCH &= 0x7f    //WKTEN = 0        禁止睡眠唤醒定时器
#define        WakeTimerSet(scale)        WKTCL = (scale) % 256,WKTCH = (scale) / 256 | 0x80    //WKTEN = 1    允许睡眠唤醒定时器
 
 
//sfr CLK_DIV = 0x97; //Clock Divder 系统时钟分频  -     -      -       -     -  CLKS2 CLKS1 CLKS0 xxxx,x000
#define        SYSTEM_CLK_1T()        CLK_DIV &= ~0x07    //default
#define        SYSTEM_CLK_2T()        CLK_DIV = (CLK_DIV & ~0x07) | 1
#define        SYSTEM_CLK_4T()        CLK_DIV = (CLK_DIV & ~0x07) | 2
#define        SYSTEM_CLK_8T()        CLK_DIV = (CLK_DIV & ~0x07) | 3
#define        SYSTEM_CLK_16T()    CLK_DIV = (CLK_DIV & ~0x07) | 4
#define        SYSTEM_CLK_32T()    CLK_DIV = (CLK_DIV & ~0x07) | 5
#define        SYSTEM_CLK_64T()    CLK_DIV = (CLK_DIV & ~0x07) | 6
#define        SYSTEM_CLK_128T()    CLK_DIV =  CLK_DIV          | 7
 
#define        MCLKO_P54_None()    CLK_DIV &= ~0xc0                    //主时钟不输出
#define        MCLKO_P54_DIV1()    CLK_DIV  = (CLK_DIV & ~0xc0) | 0x40    //主时钟不分频输出
#define        MCLKO_P54_DIV2()    CLK_DIV  = (CLK_DIV & ~0xc0) | 0x80    //主时钟2分频输出
#define        MCLKO_P54_DIV4()    CLK_DIV  =  CLK_DIV | 0xc0            //主时钟4分频输出
 
#define        MCLKO_P34_None()    CLK_DIV &= ~0xc0                    //主时钟不输出
#define        MCLKO_P34_DIV1()    CLK_DIV  = (CLK_DIV & ~0xc0) | 0x40    //主时钟不分频输出
#define        MCLKO_P34_DIV2()    CLK_DIV  = (CLK_DIV & ~0xc0) | 0x80    //主时钟2分频输出
#define        MCLKO_P34_DIV4()    CLK_DIV  =  CLK_DIV | 0xc0            //主时钟4分频输出
 
//sfr BUS_SPEED = 0xA1; //Stretch register      -   -  -  -   -   -  EXRTS1  EXRTSS0 xxxx,xx10
#define        BUS_SPEED_1T()    BUS_SPEED = 0
#define        BUS_SPEED_2T()    BUS_SPEED = 1
#define        BUS_SPEED_4T()    BUS_SPEED = 2
#define        BUS_SPEED_8T()    BUS_SPEED = 3
 
/*   interrupt vector */
#define        INT0_VECTOR        0
#define        TIMER0_VECTOR    1
#define        INT1_VECTOR        2
#define        TIMER1_VECTOR    3
#define        UART1_VECTOR    4
#define        ADC_VECTOR        5
#define        LVD_VECTOR        6
#define        PCA_VECTOR        7
#define        UART2_VECTOR    8
#define        SPI_VECTOR        9
#define        INT2_VECTOR        10
#define        INT3_VECTOR        11
#define        TIMER2_VECTOR    12
#define        INT4_VECTOR        16
#define        UART3_VECTOR    17
#define        UART4_VECTOR    18
#define        TIMER3_VECTOR    19
#define        TIMER4_VECTOR    20
 
 
#define    TRUE    1
#define    FALSE    0
 
//=============================================================
 
//========================================
 
#define    PolityLow            0    //低优先级中断
#define    PolityHigh            1    //高优先级中断
 
//========================================
 
#define        MCLKO_None    0
#define        MCLKO_DIV1    1
#define        MCLKO_DIV2    2
#define        MCLKO_DIV4    3
 
#define        ENABLE        1
#define        DISABLE        0
 
#define        STC15F_L2K08S2    8
#define        STC15F_L2K16S2    16
#define        STC15F_L2K24S2    24
#define        STC15F_L2K32S2    32
#define        STC15F_L2K40S2    40
#define        STC15F_L2K48S2    48
#define        STC15F_L2K56S2    56
#define        STC15F_L2K60S2    60
#define        IAP15F_L2K61S2    61
 
#endif

你可能感兴趣的:(嵌入式Linux)