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

📄 计数器程序.c

📁 单片机计数器程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
***********************************************************
***********************************************************
*             项目 : 计数器程序
*             
*             Version : 1.0 (C Language)
*             Date : 2004-10-25
*    
*             All Rights Reserved
*             Note : volume 可保存
*             Mcu : 78E52
*             1. 增加软件狗
***********************************************************
***********************************************************
*/
#include <reg51.h>
#include <intrins.h>
#include <math.h>

/*-------- 类型定义----------*/
#define uchar    unsigned char
#define uint     unsigned short int
#define ulint    unsigned long int

/*---------I2C接口地址----------*/
#define EEPROM_W_ADDR   0xA0       /* EEPROM 的I2C配置地址(写) */
#define EEPROM_R_ADDR   0xA1       /* EEPROM 的I2C配置地址(读) */

/*--------功能管脚定义----------*/
sbit P_SCL    = P1^0;     /* IIC总线之时钟 */
sbit P_SDA    = P1^1;     /* IIC总线之数据 */
sbit P_SWITCH = P1^2;     /* 控制电机 */
sbit P_SPEAK  = P1^3;
sbit P_KEY4   = P1^4;     /* KEY 4 */
sbit P_KEY3   = P1^5;     /* KEY 3 */
sbit P_KEY2   = P1^6;     /* KEY 2 */
sbit P_KEY1   = P1^7;     /* KEY 1 */

sbit P_A1     = P2^0;     /* LED1 ADDRESS */
sbit P_A2     = P2^1;     /* LED2 ADDRESS */
sbit P_A3     = P2^2;     /* LED3 ADDRESS */
sbit P_A4     = P2^3;     /* LED4 ADDRESS */
sbit P_A5     = P2^4;     /* LED5 ADDRESS */

sbit P_LAMP   = P3^2;     /* SET指示灯 */
sbit P_CON    = P3^3;     /* 脉冲输入检测 */

sfr  WDOG     = 0x8F;

#define Wdog_Enable WDOG = 0xe7;
#define Wdog_Unenable WDOG = 0x47;

#define Speake3 Speake(30);DelayMs(100);Speake(30);DelayMs(100);Speake(30);

#define P0ROM           0x10         /* P0口设置保存 */
#define P1ROM           0x11         /* P1口设置保存 */
#define P2ROM           0x12         /* P2口设置保存 */
#define STATUS          0x13         /* 状态保存 */
#define PAR_FLAG        0x15         /* 参数改变标志位 */
#define A_FLAG1         0x20
#define A_FLAG2         0x21
#define A_FLAG3         0x22
#define A_FLAG4         0x23
#define A_FLAG5         0x24
#define A_FLAG6         0x25
#define A_SETDATA       0x30

/*--- 返回值定义----*/
#define OK              1
#define FAIL            0

#define V_K_NULL        0            /* 按键无效 */
#define V_K1            1
#define V_K2            2
#define V_K3            3
#define V_K4            4
#define V_K5            5

/*  */
#define S7LED_OFF       0xff

#define S7LED_0         0xc0
#define S7LED_1         0xf9
#define S7LED_2         0xa4
#define S7LED_3         0xb0
#define S7LED_4         0x99
#define S7LED_5         0x92
#define S7LED_6         0x82
#define S7LED_7         0xf8
#define S7LED_8         0x80
#define S7LED_9         0x90
#define S7LED_P         0x7f

uchar ucKey;                         /* 键值,无键按下,返回值为0 */

bit bKeyDown;

/*------------串行协议4个字节--------------*/
#define SER_ID          0x7e         /* 帧头 */
#define SER_END         0x0d         /* 帧尾 */

/* 设备地址定义:PANEL-0;MAINBOARD-1;PC-2;PROJECTOR:3 */
#define ADR_PM          0x21         /* PC TO MAINBOARD */
#define ADR_MP          0x12         /* MAINBOARD TO PC */

/*------------命令字定义-------------*/
#define COUNT           0x10         /* 检测脉冲数 */

#define HANDLE          0xAA         /* 握手 */

#define DELETE          0xFC         /* 删除 */
#define SET             0xFD         /* 参数设置 */
#define MOVE            0xFE         /* 移位 */
#define ADD             0xFF         /* 循环加 */

/*-------------------- 复位相关----------------------*/
uchar *RST_FLAG1;
uchar *RST_FLAG2;
uchar *RST_FLAG3;
uchar *RST_FLAG4;
uchar P0_Status;                     /* 存放P0端口状态 */
uchar P1_Status;                     /* 存放P1端口状态 */
uchar P2_Status;                     /* 存放P2端口状态 */
uchar F_Status;

uchar Par_Change;    /* 参数改变标志位:1-改变,0-没变 */
uchar Volume_Ram;
uchar Band_Ram;

uchar Dis_Bit;
uint  Set_Data;
uint  Count_Data;

uchar Led1_Control;
uchar Led2_Control;
uchar Led3_Control;
uchar Led4_Control;
uchar Led5_Control;

/*------函数类型定义-----*/
void Init(void);
void DelayMs(uchar ucTime);
void Delay_100ms(uchar ucTime100);
void I2C_Start(void);
void I2C_Stop(void);
bit  I2C_TestAck(void);
void I2C_Write8Bit(uchar input);
void I2C_Ack();
void I2C_NoAck();
uchar I2C_Read8Bit();

bit  SerMem_Write(uchar *pucMem, uint usRegAddr, uint ucNum);
bit  SerMem_PageWrite(uchar *pucMem, uint usRegAddr, uchar ucNum);
bit  SerMem_Read(uchar *pucRegWord, uint usRegAddr, uint ucNum);

uchar GetKey(void);
void ProcessKey(uchar ucKey);
bit ifKeyDown(void);

void Speake(uchar ucTime);    /* 蜂鸣器发声 */
uchar DataToLed(uchar Value);
void Display(void);

void Sent_Ack(void);
void Serial_ProcessMsg(uchar *Buff);

void SaveBackPar(void);      /* 保存参数设定参数到EEPROM */
void LoadBackPar(void);      /* 从EEPROM中读取状态值 */

void Save_Flag(void);
void Flag_LoadCode(void);

void FirstSetup(void);       /* 初次调用参数设置-复位设置 */

/*
*************************************************
*            - MainProgram -
*             Data : 2004-10-25
*************************************************
*/
void main(void)
{
    DelayMs(100);    /* 等待 */

    P0 = 0xff;
    P1 = 0xff;
    P2 = 0xff;

    *RST_FLAG1 = (char *)0x7c;
    *RST_FLAG2 = (char *)0x7d;
    *RST_FLAG3 = (char *)0x7e;
    *RST_FLAG4 = (char *)0x7f;
    RST_FLAG1 = 0x7c;
    RST_FLAG2 = 0x7d;
    RST_FLAG3 = 0x7e;
    RST_FLAG4 = 0x7f;

    Wdog_Enable;

    /* 初始参数配置 */
    if ((*RST_FLAG1==0x55)&&(*RST_FLAG2==0xaa)&&(*RST_FLAG3==0x55)&&(*RST_FLAG4==0xaa)) /* 上电复位 */
    {
        LoadBackPar();
        P0 = P0_Status;              /* 恢复各端口的原始状态 */
        P1 = P1_Status;
        P2 = P2_Status;
        Wdog_Enable;
    }
    else /*  */
    {
        /* 初始参数配置 */
        RST_FLAG1 = 0x7c;
        RST_FLAG2 = 0x7d;
        RST_FLAG3 = 0x7e;
        RST_FLAG4 = 0x7f;
        *RST_FLAG1 = 0x55;
        *RST_FLAG2 = 0xaa;
        *RST_FLAG3 = 0x55;
        *RST_FLAG4 = 0xaa;          /* 置复位标志 */
        Led1_Control = 0;
        Led2_Control = 0;
        Led3_Control = 0;
        Led4_Control = 0;
        Led5_Control = 0;
        Count_Data = 0;
        Display();
        Dis_Bit = 1;
        Init();    /* 自检 */
    }

    TMOD = 0x20;    /* TMOD=20H定时器1方式2工作 */
    PCON = 0x80;    /* PCON=00H,SMOD=0 */
    TH1  = 0xfd;    /* TH1=0FDH,串行通信率为9600 */
    TL1  = 0xfd;
    SCON = 0x50;    /* 串行通信方式1 允许接收 */
    TR1  = 1;       /* 启动定时器 */

    TCON = 0x04;    /* 外中断1 IT1 = 1 */
    IE = 0x94;      /* EX1\ES\EA = 1 */

    Flag_LoadCode();

    while (1)
    {
        ucKey = GetKey();    /* 等待按键 */
        Wdog_Enable;
        if (V_K_NULL != ucKey)
        {
            ProcessKey(ucKey);    /* 响应按键 */
            Wdog_Enable;
        }
    }
}

/*
*************************************************
*            - 延时子程序 -
*             Input:  usTime (刻度为ms)
*            
*     延时时间单位为1毫秒,晶振使用11.0592兆赫
*usTime为需要延时的毫秒数,最大为255毫秒,误差小于1%
*************************************************
*/
void DelayMs(uchar ucTime)
{
    uint  i;
    uchar j;
    for(j=0;j<ucTime;j++)
    for(i=0;i<114;i++);
}

void Delay_100ms(uchar ucTime100)
{
  uchar x;
  for (x=0;x<ucTime100;x++)
  {
    DelayMs(100);
  }
}

/*
*************************************************
*            - I2C 接口起始操作 -
*             Data : 2002-3-18
*************************************************
*/
void I2C_Start(void)
{
    P_SDA = 1;
    P_SCL = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    P_SDA = 0;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    P_SCL = 0;
}

/*
*************************************************
*            - I2C 接口结束操作 -
*             Data : 2002-3-18
*************************************************
*/
void I2C_Stop(void)
{
    P_SCL = 0;
    P_SDA = 0;     /*  ????????                without  delay*/
   
    P_SCL = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    P_SDA = 1;
}

/*
*************************************************
*            - I2C 接口应答操作 -
*             Return: OK(1) FAIL(0)
*             Data : 2002-3-18
*************************************************
*/
bit I2C_TestAck(void)
{
    bit ErrorBit;
    P_SDA = 1;
    P_SCL = 1;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    ErrorBit = P_SDA;
    P_SCL = 0;
    return(ErrorBit);
}

/*
*************************************************
*            - I2C 接口单字节写入操作 -
*             Input:  写入数据
*             Data : 2002-3-18
*************************************************
*/
void I2C_Write8Bit(uchar input)
{
    uchar temp;
    for(temp = 8; temp != 0; temp--)
    {
        P_SDA = (bit)(input&0x80);
        P_SCL = 1;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        P_SCL = 0;
        input = input<<1;
    }
}

/*
*************************************************
*            - I2C 接口读认可信号 -
*             Return: OK(1) FAIL(0)
*             Data : 2002-3-18
*************************************************
*/
void I2C_Ack()
{
    P_SDA=0;
    P_SCL=1;
    P_SCL=0;
    P_SDA=1;
}

/*
*************************************************
*            - I2C 接口反认可信号 -
*             Return: OK(1) FAIL(0)
*             Data : 2002-3-18
*************************************************
*/
void I2C_NoAck()
{
    P_SDA=1;
    P_SCL=1;
    P_SCL=0;
}

/*
*************************************************
*            - I2C 接口单字节读入操作 -
*             Return: 读入的八位数据
*             Data : 2002-3-18
*************************************************
*/
uchar I2C_Read8Bit()
{
    uchar temp, rbyte=0;
    for(temp=8;temp!=0;temp--)
    {
        P_SCL=1;
        _nop_();
        _nop_();
        rbyte=rbyte<<1;
        rbyte=rbyte|((uchar)(P_SDA));
        P_SCL=0;
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
    return(rbyte);
}

/*
*************************************************
*            - EEPROM 串行内存配置操作 -
*             Input:  usRegAddr 寄存器地址
*                     ucMem     寄存器内容
*                     ucNum     写入个数
*             Return: OK(1) FAIL(0)
*             Data : 2002-3-18
*************************************************
*/
bit SerMem_Write(uchar *pucMem, uint usRegAddr, uint ucNum)
{
    I2C_Start();
    I2C_Write8Bit(EEPROM_W_ADDR);
    I2C_TestAck();
    I2C_Write8Bit((uchar)(usRegAddr>>8));
    I2C_TestAck();
    I2C_Write8Bit((uchar)(usRegAddr));
    I2C_TestAck();
    for( ; ucNum != 0; ucNum--)
    {
        I2C_Write8Bit(*pucMem);
        I2C_TestAck();
        pucMem++;
    }
    I2C_Stop();
    DelayMs(5);
    Wdog_Enable;
    return(OK);
}

/*
*************************************************
*            - EEPROM 串行内存配置操作 -
*             Input:  usRegAddr 寄存器地址
*                     ucMem     寄存器内容
*                     ucNum     写入个数
*             Return: OK(1) FAIL(0)
*             Data : 2002-3-18
*************************************************
*/
bit SerMem_PageWrite(uchar *pucMem, uint usRegAddr, uint ucNum)
{
    uchar ucTimes = ucNum / 64;
    uchar ucLNum = ucNum % 64;

    while (ucTimes)
    {
        I2C_Start();
        ucNum = 64;
        I2C_Write8Bit(EEPROM_W_ADDR);
        I2C_TestAck();
        I2C_Write8Bit((uchar)(usRegAddr>>8));
        I2C_TestAck();
        I2C_Write8Bit((uchar)(usRegAddr));
        I2C_TestAck();
        for( ; ucNum != 0; ucNum--)
        {
            I2C_Write8Bit(*pucMem);
            I2C_TestAck();
            pucMem++;
        }
        I2C_Stop();
        usRegAddr += 64;
        ucTimes--;
        DelayMs(10);
        Wdog_Enable;
    }
    DelayMs(10);
    if (ucLNum != 0)
    {
        ucNum = ucLNum;
        I2C_Start();
        I2C_Write8Bit(EEPROM_W_ADDR);
        I2C_TestAck();
        I2C_Write8Bit((uchar)(usRegAddr>>8));
        I2C_TestAck();
        I2C_Write8Bit((uchar)(usRegAddr));
        I2C_TestAck();
        for( ; ucNum != 0; ucNum--)
        {
            I2C_Write8Bit(*pucMem);
            I2C_TestAck();
            pucMem++;
        }
        I2C_Stop();
        DelayMs(10);
    }
    Wdog_Enable;
    return(OK);
}

/*
*************************************************
*            - 串行内存读取操作 -
*             Input:  usRegAddr    读地址
*                     *pucRegWord  读出存放缓冲区
*                     ucNum        读出个数
*             Return: OK(1) FAIL(0)
*             Data : 2002-3-18
*************************************************
*/
bit SerMem_Read(uchar *pucRegWord, uint usRegAddr, uint ucNum)
{
    I2C_Start();
    I2C_Write8Bit(EEPROM_W_ADDR);
    I2C_TestAck();
    I2C_Write8Bit((uchar)(usRegAddr>>8));
    I2C_TestAck();
    I2C_Write8Bit((uchar)(usRegAddr));
    I2C_TestAck();
    I2C_Start();
    I2C_Write8Bit(EEPROM_R_ADDR);
    I2C_TestAck();
    while(ucNum!=1)
    {
        *pucRegWord=I2C_Read8Bit();
        I2C_Ack();
        pucRegWord++;
        ucNum--;
        Wdog_Enable;
    }
    *pucRegWord=I2C_Read8Bit();
    I2C_NoAck();
    I2C_Stop();
    Wdog_Enable;
    return (OK);
}

/*
*************************************************
*               上电自检子程序
*************************************************
*/

⌨️ 快捷键说明

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