📄 communication_usart.c
字号:
UCSR0B = 0x00; // 禁止接收器、发送器、接收结束和数据寄存器空中断
UCSR0A = 0x00; // 清除帧、数据溢出、奇偶校验错误及数据寄存器空标志
COMM_USART_initialization(); // 重新初始化 USART 端口状态
USART0_TX_COMM_Start(tcomm_com_rep_tx);// 向对方发送“要求重新发送”命令
}
else
{
if (tcomm_sign0.tcomm_rdovr == TCOMM_VVALUE)// 检查接收作业错误是否为数据缓冲区溢出?
{
tcomm_sign0.tcomm_rdovr = 0x00; // 清除通讯接收数据缓冲区溢出标志
}
USART0_TX_COMM_Start(tcomm_com_rep_tx);// 向对方发送“要求重新发送”命令
usart0_rx_index = 0x00; // 数据接收缓冲区地址指针归零
usart0_com_rx_counter = 0x00; // 接收命令个数计数器归零
tcomm_sign0.tcomm_rxenum++; // 通讯接收作业发生错误次数+1
tcomm_sign0.tcomm_rxerr = 0x00; // 清除讯接收作业错误标志
tcomm_sign0.tcomm_rxupd = 0x00; // 清除通讯接收作业己更新标志
}
}
else
{
if (tcomm_sign0.tcomm_rddata == TCOMM_VVALUE)// 检查接收通讯任务是否为接收通讯数据?
{
if (tcomm_sign0.tcomm_rdalw != TCOMM_VVALUE)// 检查通讯接收数据是否己处理结束?
{
usart0_rx_index = usart0_rx_index-3;// CRC数据长度=接收数据总长度-3个结束符
if (DataCheck_CRC_2Bit(usart0_rx_buffer,usart0_rx_index) \
== 0x0000) // 进行2位CRC码校验,校验接收数据是否正确?
{
USART0_TX_COMM_Start(tcomm_com_data_ok);// 向对方发送“接收数据正确”命令
tcomm_sign0.tcomm_rdalw = TCOMM_VVALUE;// 置允许处理通讯接收数据标志
tcomm_sign0.tcomm_rddata = 0x00; // 清除接收通讯数据标志
usart0_rx_counter = usart0_rx_index-2;// 个数计数器置为有效数据长度值
}
else
{
USART0_TX_COMM_Start(tcomm_com_rep_tx);// 向对方发送“要求重新发送”命令
}
usart0_rx_index = 0x00; // 数据接收缓冲区地址指针归零
tcomm_sign0.tcomm_rxupd = 0x00; // 清除通讯接收作业己更新标志
}
}
else // 否,则为接收通讯命令
{
if (StrCmp_sram_flash(usart0_com_rx_buffer, tcomm_com_head, 3) \
!= 0x00) // 接收命令的0~2字节是否为命令开头标识字符?
{
usart0_com_rx_counter = 0x00; // 接收命令个数计数器归零
tcomm_sign0.tcomm_rxupd = 0x00; // 清除通讯接收作业己更新标志
}
else
{
for (i=0; i<4; i++) // 读取 EEPROM 中本机设备编号到 SRAM 中
{
EEPROM_READ(tcomm_device_number[i],&Device_Number[i]);
}
if ((StrCmp_sram_flash(&usart0_com_rx_buffer[3],Public_Device_Number,4) != 0x00) \
|| (StrCmp_sram_sram(&usart0_com_rx_buffer[3],tcomm_device_number,4) != 0x00))
// 接收命令3~6字节是否为公共或本机的设备编号?
{
usart0_com_rx_counter = 0x00; // 接收命令个数计数器归零
tcomm_sign0.tcomm_rxupd = 0x00; // 清除通讯接收作业己更新标志
}
else
{
// 如果接收命令7~9字节为“向我方请求发送数据”,执行相应处理,否则继续判别
if (StrCmp_sram_flash(&usart0_com_rx_buffer[7],tcomm_com_ask_tx,3)==0x00)
{
if (tcomm_sign0.tcomm_rdalw != TCOMM_VVALUE)// 检查通讯接收数据是否己处理结束?
{
USART0_TX_COMM_Start(tcomm_com_ok_rx); // 向对方发送“允许对方发送数据”命令
tcomm_sign0.tcomm_rddata = TCOMM_VVALUE;// 置接收通讯数据标志
usart0_com_rx_counter = 0x00; // 接收命令个数计数器归零
tcomm_sign0.tcomm_rxupd = 0x00; // 清除通讯接收作业己更新标志
}
}
// 如果接收命令7~9字节为“允许我方发送数据”,执行相应处理,否则继续判别
else if (StrCmp_sram_flash(&usart0_com_rx_buffer[7],tcomm_com_ok_rx,3)==0x00)
{
if (tcomm_sign0.tcomm_tdalw != TCOMM_VVALUE)// 检查通讯发送数据是否己处理结束?
{
tcomm_sign0.tcomm_tddata = TCOMM_VVALUE;// 置通讯发送数据标志
USART0_TX_Start(); // 启动通讯发送作业
usart0_com_rx_counter = 0x00; // 接收命令个数计数器归零
tcomm_sign0.tcomm_rxupd = 0x00; // 清除通讯接收作业己更新标志
}
}
// 如果接收命令7~9字节为“要求我方重新发送”,执行相应处理,否则继续判别
else if (StrCmp_sram_flash(&usart0_com_rx_buffer[7],tcomm_com_rep_tx,3)==0x00)
{
USART0_TX_Start(); // 启动通讯发送作业
usart0_com_rx_counter = 0x00; // 接收命令个数计数器归零
tcomm_sign0.tcomm_rxupd = 0x00; // 清除通讯接收作业己更新标志
}
// 如果接收命令7~9字节为“对方接收数据正确”,执行相应处理,否则继续判别
else if (StrCmp_sram_flash(&usart0_com_rx_buffer[7],tcomm_com_data_ok,3)==0x00)
{
tcomm_sign0.tcomm_tdalw = TCOMM_VVALUE; // 置允许处理通讯发送数据
tcomm_sign0.tcomm_tddata = 0; // 清除通讯发送数据标志
usart0_com_rx_counter = 0x00; // 接收命令个数计数器归零
tcomm_sign0.tcomm_rxupd = 0x00; // 清除通讯接收作业己更新标志
}
// 如果接收命令7~9字节为“要求我方发送指定数据”,执行相应处理,否则继续判别
else if (StrCmp_sram_flash(&usart0_com_rx_buffer[7],tcomm_com_dcom_tx,3)==0x00)
{
tcomm_sign0.tcomm_tdalw = TCOMM_VVALUE; // 置允许处理通讯发送数据
usart0_com_rx_counter = 0x00; // 接收命令个数计数器归零
tcomm_sign0.tcomm_rxupd = 0x00; // 清除通讯接收作业己更新标志
}
// 如果接收命令7~9字节为“传送控制操作指令”,执行相应处理,否则继续判别
else if (StrCmp_sram_flash(&usart0_com_rx_buffer[7],tcomm_com_ctrl_com,3)==0x00)
{
if (tcomm_sign0.tcomm_rdalw != TCOMM_VVALUE)// 检查通讯接收数据是否己处理结束?
{
USART0_TX_COMM_Start(tcomm_com_ok_rx); // 向对方发送“允许对方发送数据”命令
tcomm_sign0.tcomm_rddata = TCOMM_VVALUE;// 置接收通讯数据标志
usart0_com_rx_counter = 0x00; // 接收命令个数计数器归零
tcomm_sign0.tcomm_rctrl = TCOMM_VVALUE; // 置通讯接收控制操作指令标志
tcomm_sign0.tcomm_rxupd = 0x00; // 清除通讯接收作业己更新标志
}
}
// 如果接收命令7~9字节不是上面的通讯协议命令,则接收的通讯命令错误。
else
{
USART0_TX_COMM_Start(tcomm_com_rep_tx); // 向对方发送“要求重新发送”命令
usart0_com_rx_counter = 0x00; // 接收命令个数计数器归零
tcomm_sign0.tcomm_rxenum++; // 通讯接收作业发生错误次数+1
tcomm_sign0.tcomm_rxupd = 0x00; // 清除通讯接收作业己更新标志
}
}
}
}
}
}
}
/*==========================================================================================
函数功能: 本函数用于对接收到的通信数据进行处理操作。
备注: ①.注意:本函数为消息任务队列函数,要在主函数中不间断循环调用运行。
②.入口参数:由于本函数为消息任务队列函数,因此,本函数在调用时,将在函数体中
隐式调用通讯处理消息任务标志变量的下面这个入口参数的全局静态变量。
允许处理通讯接收数据(tcomm_sign0.tcomm_rdalw)=TCOMM_VVALUE,用以判断
是否有新的通讯接收数据需要处理,以决定下一步的处理操作。
③.出口参数:由于本函数为消息任务队列函数,因此,本函数在调用时,将在函数体中
隐式修改下面这个出口参数的全局静态变量。
允许处理通讯接收数据(tcomm_sign0.tcomm_rdalw)=0,用以通知其它处理函数,
本中断函数己完成接收数据处理操作。
==========================================================================================*/
void USART0_RX_Data_Manage(void)
{
#if defined(USART_DATA_TO_FROM_EEPROM) // 通信数据转储目的为EEPROM的条件编译
#if (USART0_RXBUF_SIZE < 256)
unsigned char j; // 临时变量
#else
unsigned int j;
#endif
#endif // 通信数据转储目的条件编译结束
if (tcomm_sign0.tcomm_rdalw == TCOMM_VVALUE)// 是否允许处理通讯接收数据?
{
#if defined(USART_DATA_TO_FROM_EEPROM) // 通信数据转储目的为EEPROM的条件编译
for (j=0; j<usart0_rx_counter; j++)
{
EEPROM_WRITE(&usart0_rx_eepbuf[usart0_rx_eepbuf_index], usart0_rx_buffer[j]);
usart0_rx_eepbuf_index++;
if (usart0_rx_eepbuf_index == USART0_RX_EEPBUF_SIZE)
{
usart0_rx_eepbuf_index = 0; // 转储缓冲区数据地址索引变量归零
}
}
#elif defined(USART_DATA_TO_FROM_EXTSRAM) // 通信数据转储目的大于 64 KB SRAM 条件编译
ExtSRAM_Black_Write(usart0_rx_buffer, usart0_rx_counter);
#else // 通信数据转储目的条件编译
#error 函数 " USART0_RX_Data_Manage " 错误!函数体中没有接收数据复制目的执行部分。
#endif // 通信数据转储目的条件编译结束
usart0_rx_counter = 0x00; // 接收数据个数计数器归零
tcomm_sign0.tcomm_rdalw = 0x00; // 清除允许处理通讯接收数据标志
}
}
/*==========================================================================================
函数功能: 本函数用于USART0异步通信进行发送各类发送数据通讯作业函数。
在本函数中除了将发送的数据序列复制到发送数据缓冲区内,还将生成发送数据序列的
2位监督码(CRC码)和通讯任务结束字符“0D、0A、17”,发送数据时,这5位
数据将接在数据序列尾部一同发送出去。
备注: ①.注意:本函数为消息任务队列函数,要在主函数中不间断循环调用运行。
②.入口参数:由于本函数为消息任务队列函数,因此,本函数在调用时,将在函数体中
隐式调用通讯处理消息任务标志变量的下面这个入口参数的全局静态变量。
允许处理通讯发送数据(tcomm_sign0.tcomm_tdalw)=TCOMM_VVALUE,用以判断
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -