📄 mcuunit.c
字号:
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void SER_ISR(void) interrupt 4
{
if (RI)
RI = FALSE; // 允许下次接收数据
else if (TI)
{
TI = FALSE;
if (!gbIsTxHeadOK)
{
gbIsTxHeadOK = TRUE; // 帧头已发送完毕
gnTxCnt = 0; // 准备发送数据
gnCrc = 0; // 准备计算校验和
SBUF = 0xFF; // 发送第二个帧头
}
else if (!gbIsTxDataOK)
{
if (gnTxCnt > 8) // 检查数据是否发送完
{
gbIsTxDataOK = TRUE;
SBUF = gnCrc; // 发送校验和
}
else
{
gnCrc = gnCrc^gnTxBuf[gnTxCnt]; // 计算校验和
SBUF = gnTxBuf[gnTxCnt]; // 发送缓冲区中的数据
}
gnTxCnt++; // 准备发送下一个数据
}
else
gbIsTxBusyOK = FALSE; // 串口发送缓冲区处于空闲状态
}
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: SysInit
** 功能描述: 仪器上电时,对系统全局变量、特殊功能寄存器、定时器、串行口及中断进行初始化。
** 输 入: 无
** 输 出: 无
** 全局变量: gnKeyCnt>>>>>>>>>>>按键检测间隔计数器;
** gnADData[]>>>>>>>>>存放前三个测量通道及其平均值的工程量结果;
** gnLcdBuf[]>>>>>>>>>LCD显示缓冲区。
** 全局常量:无
** 调用模块: 无
** 其它说明:无
**
** 作 者: 罗建
** 日 期: 2007年06月29日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年07月03日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年07月05日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年07月29日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年09月20日(P3.2=OUT1、P3.3=OUT2默认设为高电平)
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void SysInit(void)
{
INT8U i;
P3 = 0x0F; // TXD和RXD必须先设为高电平才能正常通讯
gnKeyCnt = KEY_WAIT;
/* LCD显示缓冲区初始化 */
for (i=0;i<4;i++)
{
gnLcdBuf[i][0] = ' '; // 空格
gnLcdBuf[i][2] = '.'; // 小数点
gnLcdBuf[i][5] = 'm'; // 单位:mm
gnLcdBuf[i][6] = 'm'; // 单位:mm
gnLcdBuf[i][7] = ' '; // 空格
gnADData[i].Word = 0; // 清零
}
/* 配置ADC模块 */
P1M0 = 0x0F; // P1.0~P1.3作为ADC输入(开漏),P1.4~P1.7作为通用IO(准双向口)
P1M1 = 0x0F;
ADC_CONTR = 0x80; // 打开ADC电源,每通道转换速度约为12KHz(约80us)
/* 配置串行通讯口 */
/***************************************************************
PCON地址为 ,复位值为
SMOD --- --- --- GF1 GF0 PD IDL 16进制值
0 0 0 0 0 0 0 0 0x00
****************************************************************
SCON地址为 ,复位值为
SM0 SM1 SM2 REN TB8 RB8 TI RI 16进制值
0 1 0 0 0 0 0 0 0x40
***************************************************************/
PCON = 0x00; // SMOD=1,如果SMOD=0,则波特率将减半
SCON = 0x40; // 串行口工作于方式1,10位异步收发,允许接收
/* 配置T0和T1 */
/***************************************************************
TMOD地址为89H,设定值为
GATE1 C/T1 M1 M0 GATE0 C/T0 M1 M0 16进制值
0 0 1 0 0 0 0 1 0x21
****************************************************************
AUXR地址为8EH,设定值为
T0x12 T1x12 UART_M0x6 EADCI ESPI ELVDI - - 16进制值
0 0 0 0 0 0 0 0 0x00
****************************************************************
TCON地址为88H,设定值为
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 16进制值
0 1 0 1 0 0 0 0 0x50
****************************************************************
波特率计算
12T模式:Reload = 256 - INT(Fosc/Baud0/32/12 + 0.5);
1T模式: Reload = 256 - INT(Fosc/Baud0/32 + 0.5).
式中,INT()表示取整操作,即取消小数点,加0.5用于四舍五入;
Fosc为晶振频率;
Baud0为标准波特率。
***************************************************************/
TH0 = T0_CONST / 256; // 设置T0定时初值(10ms)
TL0 = T0_CONST % 256;
TH1 = T1_CONST; // 设置T1定时初值(19200bps)
TL1 = T1_CONST;
AUXR = 0x00; // T0和T1采用12T模式
TMOD = 0x21; // 配置T0定时,T1自动重装载为UART提供波特率
TCON = 0x50; // 启动T0、T1定时
/* 配置中断允许控制寄存器 */
/***************************************************************
IE地址为 ,复位值为
EA --- ET2 ES ET1 EX1 ET0 EX0 16进制值
1 0 0 1 0 0 1 0 0x92
***************************************************************/
IE = 0x92; // 开放相关中断
}
// ------------------------------------------------------------------------------------------------------
/********************************************************************************************************
** 函数名称: main
** 功能描述: 主程序,负责检测按键,并根据按键情况进行数据处理,同时将数据发送至PC。
** 输 入: 无
** 输 出: 无
** 全局变量: gbTimeOver>>>>>>>>>指示规定的定时间隔时间时否到,0~未到,1~已到;
** gbIsTxBusyOK>>>>>>>指示是否串口发送缓冲区处于忙状态,0~否,1~是。
** 全局常量:LOGO[]>>>>>>>>>>>>>开机显示在LCD屏上的两行字符串。
** 调用模块: SysInit()>>>>>>>>>>仪器上电初始化;
** LCDInit()>>>>>>>>>>LCD上电初始化;
** LoadBase()>>>>>>>>>从STC5408AD芯片内部的EEPROM中读取三个测量通道的基准值;
** WriteCmdToLCD()>>>>向LCD显示屏中写入命令;
** DisplayListChar()>>在LCD显示屏的指定位置处显示一串字符;
** SendDataToPC()>>>>>通过RS-232串口发送测量数据到上位机;
** DoneKey()>>>>>>>>>>检测用户按键并处理。
** 其它说明:
**
** 作 者: 罗建
** 日 期: 2007年06月29日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年07月03日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年07月05日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年07月29日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日 期: 2007年09月20日(将ADC过程集中到DoneKey子程序中进行处理,数据发送也是自发进行的,该版改变很大)
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日 期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void main(void)
{
bit bLogo; // 仪表在上电时,该标志为TRUE,指示当前正在显示LOGO标志
INT16U nTimeCnt; // 代表LOGO信息显示时间对应的系统定时间隔次数,默认为200,代表2秒
/* 初始化操作 */
SysInit(); // 初始化系统定时器等片内外设
LCDInit(); // 初始化LCD
LoadBase(); // 从EEPROM中载入基准测量值
/* LOGO显示 */
DisplayListChar(0, 0, 16, LOGO[0]); // 显示LOGO信息并保持3秒
DisplayListChar(0, 1, 16, LOGO[1]);
bLogo = TRUE;
nTimeCnt = LOGO_WAIT;
while (bLogo) // 检查是否还处于LOGO信息显示状态
{
if (gbTimeOver) // T0每10ms定时一次
{
gbTimeOver = FALSE;
nTimeCnt--;
if (nTimeCnt == 0)
bLogo = FALSE;
}
}
/* 显示清零 */
WriteCmdToLCD(0x01, TRUE); // 显示清屏(2007.07.05,增加)
ClrLCD(); // 显示0.00mm
/* 主程序循环 */
while (TRUE)
{
if (gbTimeOver) // 每隔10ms响应一次
{
gbTimeOver = FALSE;
DoneKey(); // 处理用户按键操作
if (!gbIsTxBusyOK && !TI) // 待发送缓冲区空时,向PC发送一次数据
{
gbIsTxBusyOK = TRUE;
SendDataToPC();
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -