📄 communication_usart.c
字号:
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 + -