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

📄 mcuunit.c

📁 一个完整的个人产品开发源代码,包括对单片机STC12C5410的编程(含内部AD采样、自创的内部Flash编程源码等)、LCD1602的驱动编程等。
💻 C
📖 第 1 页 / 共 4 页
字号:
** 修 改 人:
** 日  期:
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
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 + -