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

📄 mcuunit.c

📁 一个完整的个人产品开发源代码,包括对单片机STC12C5410的编程(含内部AD采样、自创的内部Flash编程源码等)、LCD1602的驱动编程等。
💻 C
📖 第 1 页 / 共 4 页
字号:
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日  期: 2007年09月20日(增加了正负数符号显示功能,输入参数为有符号整数,取消了千位数显示功能)
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日  期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DataToLCDBuf(INT16 nData, INT8U nBufID)
{
  INT16U nTemp1;
  INT8U  nTemp2;

  if (nData >= 0)                                     // 检查要转换的数据是正数还是负数,负数需要显示负号
  {
    gnLcdBuf[nBufID][0] = ' ';
    nTemp1 = nData;
  }
  else
  {
    gnLcdBuf[nBufID][0] = '-';
    nTemp1 = nData * (-1);
  }
  nTemp2 = nTemp1/100;                                // 得到百位数字
  nTemp1 = nTemp1 - nTemp2*100;                       // 计算余数
  gnLcdBuf[nBufID][1] = nTemp2 + 0x30;                // 十进制数字转换为ASCII码
  nTemp2 = nTemp1/10;                                 // 得到十位数字
  gnLcdBuf[nBufID][3] = nTemp2 + 0x30;                // 十进制数字转换为ASCII码
  nTemp2 = nTemp1 - nTemp2*10;                        // 得到个位数字
  gnLcdBuf[nBufID][4] = nTemp2 + 0x30;                // 十进制数字转换为ASCII码
}

// ------------------------------------------------------------------------------------------------------																										
/********************************************************************************************************
** 函数名称: SendDataToPC
** 功能描述: 利用RS-232串行口向上位机发送测量数据。本方法分解要发送的数据到发送缓冲区中,然后发送帧头,后
**           面的数据发送工作在串口中断服务程序中完成。
** 输  入: 无
** 输  出: 无
** 全局变量: gbIsTxHeadOK>>>>>>>指示是否已将帧头全部发送至上位机,0~否,1~是;
**           gbIsTxDataOK>>>>>>>指示是否已将帧数据全部发送至上位机,0~否,1~是;
**           gnDisData[]>>>>>>>>存放前三个测量通道及其平均值的工程量结果,对应于显示缓冲区;
**           gnTxBuf[]>>>>>>>>>>串行接口发送缓冲区(不含帧头及校验和)。
** 全局常量:无
** 调用模块: 无
** 其它说明:无
**
** 作  者: 罗建
** 日  期: 2007年07月03日
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日  期: 2007年07月29日(数据发送方式改为了串口中断发送方式,效率会更高)
**-------------------------------------------------------------------------------------------------------
** 修 改 人: 罗建
** 日  期: 2007年09月20日(发送的数据与显示的数据一致,并且包含符号位,同时修改了开关的状态)
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日  期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void SendDataToPC(void)
{
  bit       bIsNeg;
  INT8U     i;
  TWordType nDisData;

  for (i=0;i<4;i++)                              // 准备要发送的测量数据,高位在前,低位在后
  {
    if (gnDisData[i] >= 0)                       // 检查要发送的数据是正数还是负数
    {
      bIsNeg = FALSE;
      nDisData.Word = gnDisData[i];
    }
    else
    {
      bIsNeg = TRUE;
      nDisData.Word = gnDisData[i] * (-1);
    }
    gnTxBuf[i*2]   = nDisData.Byte[0];           // 先高位MSB
    gnTxBuf[i*2+1] = nDisData.Byte[1];           // 后低位LSB
	if (bIsNeg)                                  // 检查数据是否是负数
      gnTxBuf[i*2] = gnTxBuf[i*2] | 0x80;        // 将最高位置为1表示负数
  }
  gnTxBuf[8] = 0;                                // 准备要发送的开关(含输入和输出)状态,位6、7备用
  if (!SW_TEST)									 // 位0表示测试按扭是否按下,1为按下
    gnTxBuf[8] |= 0x01;
  if (!SW_CLR)									 // 位1表示清除按扭是否按下,1为按下
    gnTxBuf[8] |= 0x02;
  if (!SW_KEY3)									 // 位2表示输入开关3是否按下,1为按下
    gnTxBuf[8] |= 0x04;
  if (!SW_KEY4)									 // 位3表示输入开关4是否按下,1为按下
    gnTxBuf[8] |= 0x08;
  if (!OUT1)									 // 位4表示输出开关1是否有输出,1为有输出
    gnTxBuf[8] |= 0x10;
  if (!OUT2)									 // 位5表示输出开关2是否有输出,1为有输出
    gnTxBuf[8] |= 0x20;
  TI = FALSE;                                    // 准备发送数据到上位机
  gbIsTxHeadOK = FALSE;
  gbIsTxDataOK = FALSE;
  SBUF = 0xFF;									 // 开始发送数据
}

// ------------------------------------------------------------------------------------------------------																										
/********************************************************************************************************
** 函数名称: DoneADC
** 功能描述: 执行一次STC12C5408AD的前四个通道的ADC。
** 输  入: 无
** 输  出: 无
** 全局变量: 略
** 全局常量:无
** 调用模块: 无
** 其它说明:本函数对STC12C5408AD的前四个通道执行FILTER次的AD转换,并对转换结果进行初步的工程量转换及平均
**           值滤波,结果最后放在gnADData[i].Word全局变量中。
**
** 作  者: 罗建
** 日  期: 2007年09月20日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日  期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void DoneADC(void)
{
  INT8U     i;                                   // i为循环变量
  INT8U     nADChan;                             // nADChan指向当前AD转换通道
  INT8U     nFilteCnt;                           // nFilteCnt为软件滤波器计数器
  INT16U    nADRes[4];                           // 存放四个测量通道的AD转换结果

  nFilteCnt = FILTER;
  while (nFilteCnt-- > 0)						 // 检查滤波是否完成
  {
    nADChan = 0;
	do{
	  ADC_CONTR &= 0xF8;                         // 选择nADChan通道进行AD转换
      ADC_CONTR |= nADChan;
      ADC_CONTR |= 0x08;                         // 启动AD转换
      while (!(ADC_CONTR & 0x10));               // 等待AD转换完成
      ADC_CONTR &= 0xE7;                         // 清除AD转换标志
      nADRes[nADChan] = 0;
      nADRes[nADChan] = nADRes[nADChan] | ADC_DATA;  // 读取AD转换结果
      nADRes[nADChan] = nADRes[nADChan] << 2;
      nADRes[nADChan] = nADRes[nADChan] & 0xFFFC;
      nADRes[nADChan] = nADRes[nADChan] | (ADC_LOW2 & 0x03);
	  nADChan++;
    }while (nADChan < 4);					     // 检查是否所有的通道都测量完毕,是则显示
    gnADData[0].Word += (INT32U)nADRes[0] * VREF / nADRes[3];    // 对通道1的测量值进行工程量转换
    gnADData[1].Word += (INT32U)nADRes[1] * VREF / nADRes[3];    // 对通道2的测量值进行工程量转换
    gnADData[2].Word += (INT32U)nADRes[2] * VREF / nADRes[3];    // 对通道3的测量值进行工程量转换
  }  
  for (i=0;i<3;i++)                              // 进行均值滤波处理
  {
    gnADData[i].Word /= FILTER;
	if (nADRes[i] >= 2)							 // 对测量值进行微量调整
	  gnADData[i].Word += 2;
	else if (nADRes[i] >= 1)
	  gnADData[i].Word += 1;
  }
}

// ------------------------------------------------------------------------------------------------------																										
/********************************************************************************************************
** 函数名称: SaveBase
** 功能描述: 将三个测量通道的基准值写入STC5408AD芯片内部的EEPROM中。
** 输  入: 无
** 输  出: 无
** 全局变量: gnBaseVal[]>>>>>>>>存放前三个测量通道的基准测量值。
** 全局常量:无
** 调用模块: WriteBytes()>>>>>>>向STC5408AD芯片内部的EEPROM中的指定地址处写入指定个数的数据。
** 其它说明:每个通道的基准值均为16位无符号整数,读取时先读低地址的高位字节,再读高地址的低位字节,最后组
**           合成为一个16位无符号整数作为基准值。
**
** 作  者: 罗建
** 日  期: 2007年09月20日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日  期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void SaveBase(void)
{
  WriteBytes(ADDR_BASE_VAL1, 2, gnBaseVal[0].Byte);
  WriteBytes(ADDR_BASE_VAL2, 2, gnBaseVal[1].Byte);
  WriteBytes(ADDR_BASE_VAL3, 2, gnBaseVal[2].Byte);
}

// ------------------------------------------------------------------------------------------------------																										
/********************************************************************************************************
** 函数名称: LoadBase
** 功能描述: 从STC5408AD芯片内部的EEPROM中读取三个测量通道的基准值。
** 输  入: 无
** 输  出: 无
** 全局变量: gnBaseVal[]>>>>>>>>存放前三个测量通道的基准测量值。
** 全局常量:无
** 调用模块: ReadBytes()>>>>>>>>从STC5408AD芯片内部的EEPROM中的指定地址处读取指定个数的数据至指定的缓冲区。
** 其它说明:每个通道的基准值均为16位无符号整数,读取时分成两个字节,低地址放高位字节,高地址放低位字节。
**
** 作  者: 罗建
** 日  期: 2007年09月20日
**-------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日  期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void LoadBase(void)
{
  ReadBytes(ADDR_BASE_VAL1, 2, gnBaseVal[0].Byte);
  ReadBytes(ADDR_BASE_VAL2, 2, gnBaseVal[1].Byte);
  ReadBytes(ADDR_BASE_VAL3, 2, gnBaseVal[2].Byte);
}

// ------------------------------------------------------------------------------------------------------																										
/********************************************************************************************************
** 函数名称: DisLCD
** 功能描述: 将测试结果(减去基准值后)显示在LCD上。
** 输  入: 无
** 输  出: 无
** 全局变量: gbClring>>>>>>>>>>>指示当前是否正处于清除LCD显示状态,0~否,1~是;
**           gbDisInfo>>>>>>>>>>指示当前是否正在显示INFO字符信息,0~否,1~是;
**           gnDisData[]>>>>>>>>存放要在LCD上显示及要发送给PC的前三个测量通道及其平均值的测量数据;
**           gnLcdBuf[]>>>>>>>>>代表四组LCD显示缓冲区内容(如:2.35mm);
**           gnADData[]>>>>>>>>>存放前三个测量通道的工程量结果;
**           gnBaseVal[]>>>>>>>>存放前三个测量通道的基准测量值。
** 全局常量:无
** 调用模块: DataToLCDBuf()>>>>>把一个整型数据按个、十、百进行分解,再转换为对应数字的ASCII码存放到LCD显
**                              示缓冲区中;
**           DisplayListChar()>>在LCD显示屏的指定位置处显示一串字符。

⌨️ 快捷键说明

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