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

📄 communication_usart.c

📁 本程序是用于通用同步和异步串行接收器和转发器(USART)
💻 C
📖 第 1 页 / 共 4 页
字号:
    tcomm_sign0.tcomm_rxend = 0x00;           // 清除通讯接收作业结束标志
  }
  if ((usart0_rx_status & (USART0_FRAMING_ERROR | USART0_PARITY_ERROR | \
      USART0_DATA_OVERRUN))== 0)              // 检查是否存在帧错误、数据溢出及奇偶校验错误?
  {
    tcomm_sign0.tcomm_rxerr = TCOMM_VVALUE;   // 置通讯接收作业错误标志
  }
  if (tcomm_sign0.tcomm_rddata == TCOMM_VVALUE)// 检查接收通讯任务是否为接收通讯数据?
  {
    usart0_rx_buffer[usart0_rx_index] = usart0_rx_data;
    if (usart0_rx_data == 0x17)               // 检查是否接收到通讯数据结束字符“0D、0A、17”?
    {
      temp = usart0_rx_index;
      if ((usart0_rx_buffer[temp-1] == 0x0A) && (usart0_rx_buffer[temp-2] == 0x0D))
      {
        tcomm_sign0.tcomm_rxupd = TCOMM_VVALUE;// 置通讯接收作业己更新标志
        tcomm_sign0.tcomm_rxend = TCOMM_VVALUE;// 置通讯接收作业结束标志
        tcomm_sign0.tcomm_rxport = TCOMM_PORT_USART;// 置通讯接收端口标志为 USART 端口
      }
    }
    if (++usart0_rx_index == USART0_RXBUF_SIZE)
    {
      usart0_rx_index = 0;
      tcomm_sign0.tcomm_rdovr = TCOMM_VVALUE; // 置通讯接收数据缓冲区溢出标志
      tcomm_sign0.tcomm_rxerr = TCOMM_VVALUE; // 置通讯接收作业错误标志
    }
  }
  else                                        // 否则,通讯任务即为接收通讯命令
  {
    usart0_com_rx_buffer[usart0_com_rx_counter] = usart0_rx_data;
    if (++usart0_com_rx_counter == TCOMM_BUF_SIZE)// 检查接收通讯命令是否共接收到 10 个字节?
    {
      usart0_com_rx_counter = 0;
      tcomm_sign0.tcomm_rxupd = TCOMM_VVALUE; // 置通讯接收作业己更新标志
      tcomm_sign0.tcomm_rxend = TCOMM_VVALUE; // 置通讯接收作业结束标志
      tcomm_sign0.tcomm_rxport = TCOMM_PORT_USART;// 置通讯接收端口标志为 USART 端口
    }
  }
}

/*==========================================================================================
函数功能:    本函数用于USART0异步通信使用数据寄存器空中断方式以块形式进行发送数据的
              中断服务程序。
备注:        ①.注意:本函数需在USART0的数据寄存器空中断中断请求的中断向量函数中
                  调用。在调用之前需使能数据寄存器空中断。
              ②.入口参数:本函数在调用时无法进行明式入口参数数值传递,将在函数体中隐式
                            调用下面这几个入口参数的全局静态变量。
                  ●.发送通讯命令(tcomm_sign0.tcomm_tdcom),用以判断执行从命令缓冲区中
                      读取数据进行发送作业的处理操作。
                  ●.发送通讯数据(tcomm_sign0.tcomm_tddata),用以判断执行从数据缓冲区中
                      读取数据进行发送作业的处理操作。
                  ●.通讯发送作业结束(tcomm_sign0.tcomm_txend),用以通知其它处理函数,
                      本中断函数正在运行中。
              ③.出口参数:本函数在返回时无法进行明式出口参数数值传递,将在函数体中隐式
                            修改下面这几个出口参数的全局静态变量。
                  ●.通讯发送作业结束(tcomm_sign0.tcomm_txend),用以通知其它处理函数,
                      本中断函数己完成通讯发送作业。
                  ●.完成通讯发送作业后,本函数将禁止 USART 数据寄存器空中断。
==========================================================================================*/
void USART0_DRE_ISR_BlockData(void)
{
  unsigned char usart0_tx_data;               // 临时USART0发送数据变量
  char temp;                                  // 临时变量
  if (tcomm_sign0.tcomm_txend == TCOMM_VVALUE)// 检查是否为发送通讯任务的第一个数据?
  {
    tcomm_sign0.tcomm_txend = 0x00;           // 清除通讯发送作业结束标志
  }
  if (tcomm_sign0.tcomm_tddata == TCOMM_VVALUE)// 检查发送通讯任务是否为发送通讯数据?
  {
    usart0_tx_data = usart0_tx_buffer[usart0_tx_index];
    UDR0 = usart0_tx_data;
    usart0_tx_index++;
    if (usart0_tx_index == usart0_tx_counter) // 检查是否己完成发送发送通讯任务的全部数据?
    {
      tcomm_sign0.tcomm_txend = TCOMM_VVALUE; // 置通讯发送作业结束标志
      temp = UCSR0B;                          // 禁止 USART 数据寄存器空中断
      temp &= ~USART0_EN_INT_DRE;
      UCSR0B = temp;
    }
  }
  else                                        // 否则,通讯任务即为发送通讯命令
  {
    usart0_tx_data = usart0_com_tx_buffer[usart0_com_tx_counter];
    UDR0 = usart0_tx_data;
    usart0_com_tx_counter++;
    if (usart0_com_tx_counter == TCOMM_BUF_SIZE)// 检查发送通讯命令是否己共发送了 10 个字节?
    {
      usart0_com_tx_counter = 0;
      tcomm_sign0.tcomm_txend = TCOMM_VVALUE; // 置通讯发送作业结束标志
      temp = UCSR0B;                          // 禁止 USART 数据寄存器空中断
      temp &= ~USART0_EN_INT_DRE;
      UCSR0B = temp;
    }
  }
}

/*==========================================================================================
函数功能:    本函数用于USART0异步通信使用数据寄存器空中断方式进行发送通讯作业函数。
函数入口参数:
备注:        ①.本函数在函数体中隐式修改下面这两个全局静态变量:
                  ●.发送数据计数器首个地址指针(usart0_tx_index)= 0 。
                  ●.发送命令计数器首个地址指针(usart0_com_tx_counter)= 0 。
              ②.调用本函数将启动USART0数据寄存器空中断请求。
==========================================================================================*/

void USART0_TX_Start(void)
{
  unsigned char temp;                         // 临时变量
  usart0_tx_index = 0;                        // 发送数据个数计数器指向首个地址指针
  usart0_com_tx_counter = 0;                  // 发送命令个数计数器指向首个地址指针
  temp = UCSR0B;                              // 使能 USART 数据寄存器空中断,
  temp |= USART0_EN_INT_DRE;                    // 执行发送数据通讯作业
  UCSR0B = temp;
}

/*==========================================================================================
函数功能:    本函数用于USART0异步通信使用数据寄存器空中断方式进行发送各类通讯命令
              作业函数。
函数入口参数:*first_data_address ------ 首个发送命令字在 flash 中的地址指针。
备注:        ①.本函数发送的命令格式:COM+设备编号(4 个字节)+ 命令字(3 个字节)。
                  其中:COM+设备编号 ------ 在函数体中隐式添加。
                        命令字 ------------- 由入口参数带入。
              ②.本函数在函数体中隐式修改下面这两个全局静态变量:
                  ●.发送命令缓冲区(usart0_com_tx_buffer)的内容。
                  ●.通讯发送数据标志(tcomm_sign0.tcomm_tddata)=0。
              ③.调用本函数将启动USART0数据寄存器空中断请求。
==========================================================================================*/
void USART0_TX_COMM_Start(unsigned char flash *first_data_address)
                          // 首个发送命令字在 flash 中的地址指针
{
  unsigned char temp;                         // 临时变量
  usart0_com_tx_counter = 0;                  // 发送命令个数计数器指向首个地址指针
  for (temp=0 ; temp<0x03 ; temp++)
  {                                           // 复制协议命令开头标识字符串到发送命令缓冲区
    usart0_com_tx_buffer[usart0_com_tx_counter] = tcomm_com_head[temp];
    usart0_com_tx_counter++;
  }
  for (temp=0 ; temp<0x04 ; temp++)
  {                                           // 复制本机的设备编号字符串到发送命令缓冲区
    usart0_com_tx_buffer[usart0_com_tx_counter] = Device_Number[temp];
    usart0_com_tx_counter++;
  }
  for (temp=0 ; temp<0x03 ; temp++)
  {                                           // 复制通讯命令字符串到发送命令缓冲区
    usart0_com_tx_buffer[usart0_com_tx_counter] = *(first_data_address++);
    usart0_com_tx_counter++;
  }
  tcomm_sign0.tcomm_tddata = 0;               // 清除通讯发送数据标志
  usart0_com_tx_counter = 0;                  // 发送命令个数计数器指向首个地址指针
  temp = UCSR0B;                              // 使能 USART 数据寄存器空中断,
  temp |= USART0_EN_INT_DRE;                    // 执行发送命令通讯作业
  UCSR0B = temp;
}

/*==========================================================================================
函数功能:    本函数用于对接收到的通信作业协议命令进行处理操作。
备注:        ①.注意:本函数为消息任务队列函数,要在主函数中不间断循环调用运行。
              ②.入口参数:由于本函数需与接收结束中断服务函数进行数据交换,因此,本函数
                            在调用时,将在函数体中隐式调用接收结束中断服务函数的下面这几
                            个入口参数的全局静态变量。
                  ●.接收通讯命令(tcomm_sign0.tcomm_rdcom),用以判断接收作业是否为
                      接收通讯命令,以决定下一步的处理操作。
                  ●.接收通讯数据(tcomm_sign0.tcomm_rddata),用以判断接收作业是否为
                      接收通讯数据,以决定下一步的处理操作。
                  ●.通讯接收作业己更新(tcomm_sign0.tcomm_rxupd),用以判断本函数需要
                      执行下一步操作。
                  ●.通讯接收作业错误(tcomm_sign0.tcomm_rxerr),用以判断本函数需要
                      执行下一步操作。
                  ●.通讯发生错误次数(tcomm_sign0.tcomm_errnum),用以判断本函数需要
                      执行下一步操作。
              ③.出口参数:由于本函数需与接收结束中断服务函数进行数据交换,因此,本函数在
                            调用时,将在函数体中隐式修改下面这几个出口参数的全局静态变量。
                  ●.通讯接收作业己更新(tcomm_sign0.tcomm_rxupd),用以通知其它处理函数,
                      本中断函数己完成通讯发送作业。
                  ●.允许处理通讯接收数据(tcomm_sign0.tcomm_rdalw),用以通知其它处理
                      函数执行处理通讯接收数据操作。
==========================================================================================*/
void USART0_RX_COMM_Manage(void)
{
  unsigned char i;                            // 临时变量
  unsigned char tcomm_device_number[5];       // 设备编号的数组变量
  if ((tcomm_sign0.tcomm_rxupd == TCOMM_VVALUE) && \
      (tcomm_sign0.tcomm_txend == TCOMM_VVALUE))// 检查接收作业是否己更新和发送作业是否己结束?
  {
    if (tcomm_sign0.tcomm_rxerr == TCOMM_VVALUE)// 检查通讯接收作业是否有错误?
    {
      if (tcomm_sign0.tcomm_rxenum >= TCOMM_ERRNUM_VALUE)// 检查接收错误次数是否超过允许次数?
      {

⌨️ 快捷键说明

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