📄 计数器程序.c
字号:
/*
***********************************************************
***********************************************************
* 项目 : 计数器程序
*
* 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 + -