金牌会员
 
- 积分
- 1028
- 金钱
- 1028
- 注册时间
- 2021-2-4
- 在线时间
- 146 小时
|
1金钱
手上有个项目 目前用了两个串口一个接串口屏(115200) 一个接电机(9600)
都采用在中断内发送数据
需求是:
屏输入数据发给单片机
单片机处理后发给屏幕用作显示
单片机发给电机执行动作
目前在屏幕上输入数据后
单片机只发送了一个字符给屏(串口4,抢占优先级0)后,就执行485发送了
进入了485的那个串口中断(串口1,抢占优先级1)
485发送数据是完整发出的 电机可以执行相应动作
但是屏幕上不会显示数据
代码贴在下方 希望大佬可以看看
//这是串口屏初始化的
// TFT屏 串口4 IO初始化
void TFT_GPIO_Init(TFT_Conf *TFT_GPIO_Init_Struct)
{
GPIO_InitTypeDef GPIO_Init_Struct;
GPIO_Init_Struct.GPIO_Pin = TFT_GPIO_Init_Struct->Tx_PINx;
GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_AF_PP; //推挽复用输出
GPIO_Init(TFT_GPIO_Init_Struct->Tx_PORTx, &GPIO_Init_Struct); //初始化输出引脚
GPIO_Init_Struct.GPIO_Pin = TFT_GPIO_Init_Struct->Rx_PINx;
GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(TFT_GPIO_Init_Struct->Rx_PORTx, &GPIO_Init_Struct); //初始化输入引脚
}
// TFT屏 串口4初始化
void TFT_Init(void)
{
TFT.Tx_PINx = TFT_RS232_TX_PIN;
TFT.Tx_PORTx = TFT_RS232_TX_PORT;
TFT.Rx_PINx = TFT_RS232_RX_PIN;
TFT.Rx_PORTx = TFT_RS232_RX_PORT;
for (uint8_t i = 0; i < TFT_SUM; i++)
{
TFT_GPIO_Init(&TFT_Array[i]); //初始化串口4的IO
}
USART_InitTypeDef TFT_UART_Init_Struct;
TFT_UART_RCC_ENABLE(); //使能TFT_UART的时钟
// USART 初始化设置
TFT_UART_Init_Struct.USART_BaudRate = 115200; //设置波特率
TFT_UART_Init_Struct.USART_WordLength = USART_WordLength_8b; //字长为8
TFT_UART_Init_Struct.USART_StopBits = USART_StopBits_1; //一个停止位
TFT_UART_Init_Struct.USART_Parity = USART_Parity_No; //无奇偶校验位
TFT_UART_Init_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件控制流
TFT_UART_Init_Struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(TFT_UART, &TFT_UART_Init_Struct); //初始化TFT串口
USART_ITConfig(TFT_UART, USART_IT_RXNE, ENABLE); //使能串口4的接收中断
USART_Cmd(TFT_UART, ENABLE); //串口4使能
//配置中断优先级
NVIC_InitTypeDef NVIC_TFT_UART_Init_Struct;
NVIC_TFT_UART_Init_Struct.NVIC_IRQChannel = TFT_UART_IRQn; //串口4中断入口
NVIC_TFT_UART_Init_Struct.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_TFT_UART_Init_Struct.NVIC_IRQChannelPreemptionPriority = 0; //优先级
NVIC_TFT_UART_Init_Struct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_TFT_UART_Init_Struct);
}
//这是串口屏的发送与接收中断
/*************************************************中断函数***********************************************/
//串口4中断处理函数
void TFT_UART_IRQHandler(void)
{
// uint8_t CLear_Flag = CLear_Flag; //清除警告
// uint8_t Temp_Rx;
// RXNE的标志位不为空。它表明移位寄存器的内容被转移到RDR。
if (USART_GetITStatus(TFT_UART, USART_IT_RXNE) != RESET) //接收到一帧数据
{
TFT.TFT_Rx_Buffer[TFT.TFT_Rx_Count++] = USART_ReceiveData(TFT_UART);
if (TFT.TFT_Rx_Count >= TFT_RX_MAX) //超过最大长度
{
TFT.TFT_Rx_Count = TFT_RX_MAX;
}
if (TFT.TFT_Rx_Count == TFT_LEN + 3) //已经接收完有效数据
{
TFT.Flag_Rx = 1; //接收到一帧数据
TFT.TFT_Rx_Count = 0;
}
}
//发送中断触发
if (USART_GetITStatus(TFT_UART, USART_IT_TXE) != RESET)
{
USART_SendData(TFT_UART, TFT.TFT_Tx_Buffer[TFT.TFT_Tx_Count++]);
if (TFT.TFT_Tx_Count >= TFT.TFT_Tx_Len) //所有帧都发完了
{
TFT.TFT_Tx_Count = 0; //字节数
TFT.TFT_Tx_Len = 0; //帧数
memset(TFT.TFT_Tx_Buffer, 0, TFT_TX_MAX);
USART_ITConfig(TFT_UART, USART_IT_TXE, DISABLE); //关闭发送中断
}
USART_ClearFlag(TFT_UART, USART_IT_TXE); //清除字节发送完成中断
}
}
//这是485的初始化
void RS485_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_Init_Struct;
GPIO_Init_Struct.GPIO_Pin = RS485_EN_PIN;
GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(RS485_EN_PORT, &GPIO_Init_Struct);
GPIO_Init_Struct.GPIO_Pin = RS485_TX_PIN;
GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_AF_PP; //推挽复用输出
GPIO_Init(RS485_TX_PORT, &GPIO_Init_Struct);
GPIO_Init_Struct.GPIO_Pin = RS485_RX_PIN;
GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(RS485_RX_PORT, &GPIO_Init_Struct);
}
void RS485_Init(void)
{
RS485_GPIO_Init();
USART_InitTypeDef RS485_UART_Init_Struct;
RS485_UART_RCC_ENABLE();
// USART 初始化设置
RS485_UART_Init_Struct.USART_BaudRate = 9600; //设置波特率
RS485_UART_Init_Struct.USART_WordLength = USART_WordLength_8b; //字长为8
RS485_UART_Init_Struct.USART_StopBits = USART_StopBits_1; //一个停止位
RS485_UART_Init_Struct.USART_Parity = USART_Parity_No; //无奇偶校验位
RS485_UART_Init_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件控制流
RS485_UART_Init_Struct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(RS485_UART, &RS485_UART_Init_Struct); //初始化485串口
USART_ITConfig(RS485_UART, USART_IT_RXNE, ENABLE); //使能串口1的接收中断
USART_Cmd(RS485_UART, ENABLE); //串口1使能
//配置中断优先级
NVIC_InitTypeDef NVIC_RS485_UART_Init_Struct;
NVIC_RS485_UART_Init_Struct.NVIC_IRQChannel = RS485_UART_IRQn; //串口1中断入口
NVIC_RS485_UART_Init_Struct.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_RS485_UART_Init_Struct.NVIC_IRQChannelPreemptionPriority = 1; //优先级
NVIC_RS485_UART_Init_Struct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_RS485_UART_Init_Struct);
}
//这是485的中断
//串口1中断处理函数
void RS485_UART_IRQHandler(void)
{
// RXNE的标志位不为空。它表明移位寄存器的内容被转移到RDR。
//在单缓冲器模式里,由软件读USART_DR寄存器完成对RXNE位清除
if (USART_GetITStatus(RS485_UART, USART_IT_RXNE) != RESET) //接收中断非空表示接收到一帧数据
{
// USART_ClearITPendingBit(RS485_UART, USART_IT_RXNE); //清除接收中断标志位
Rx485_Buff.Rx_Buff[Rx485_Buff.Rx_Count++] = USART_ReceiveData(RS485_UART); //保存数据
//一帧数据接收完成
if (Rx485_Buff.Rx_Count == MODBUS_LEN + 5 + 1) //数据长度 + 3(帧头 长) + 2(校验)
{
memcpy(Rx485_Buff.Rx_Temp_Buff, Rx485_Buff.Rx_Buff, Rx485_Buff.Rx_Count - 1); //拷贝至临时数组
Rx485_Buff.Flag_Rx = 1;
}
}
//发送中断
//发送先往DR填数据然后使能发送中断
if (USART_GetITStatus(RS485_UART, USART_IT_TXE) != RESET) //可以填充数据了
{
USART_SendData(RS485_UART, Rx485_Buff.Tx_Buff[Rx485_Buff.Tx_Count++]); //发送数据
if (Rx485_Buff.Tx_Count == Rx485_Buff.Tx_Len) //一帧数据发送完了
{
Rx485_Buff.Tx_Count = 0;
Rx485_Buff.Tx_Len = 0;
memset(Rx485_Buff.Tx_Buff, 0, RS485_TX_BUFF_MAX); //清除缓存
BLDC.CMD = CMD_BLDC_IDLE; //清除繁忙标志位
USART_ITConfig(RS485_UART, USART_IT_TXE, DISABLE); //关闭发送中断
//发送完成处理
while (USART_GetFlagStatus(RS485_UART, USART_FLAG_TC) != SET)
; //当一帧发送完成时(停止位发送后)并且置位了TXE位,TC位被置起
RX485_RX_MODE();
}
USART_ClearFlag(RS485_UART, USART_IT_TXE); //清除字节发送完成中断标志位
}
}
|
|