上期我们使用GPIO模拟串口成功的发送了数据,本期我们进一步实现串口接收的功能。

首先,因为波特率的统一,我们可以使用同一个定时器来接收和发送。
这里我们定义两个变量来设置发送和接收的标记。
其次,由于起始位是一个低电平,空闲状态的串口总线是高电平,因此当我们收到消息的时候,实际上是一个下降沿。

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(RXFlag==0)
{
RXFlag = 1;
Recive = 0;
}
}
因此我们将RX引脚设置为下降沿的外部中断,并且收到外部中断,并且如果RX空闲(RXFlag == 0)的话,就将接收缓存区(Recive)置零,之后将RX标志位置1,在定时器中可以处理。
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(TXFlag==1)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,Data[num++]);
if(num == 10)
{
num = 0;
HAL_TIM_Base_Stop_IT(&htim1);//关闭定时器
TXFlag = 0;
}
}
/*
外部中断触发后接收信息
*/
if(RXFlag==1)
{
num++;
if(num>=1&&num<=8)
{
/*
从第二位开始总计八位,对应数据从低到高
*/
Recive = Recive|(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_10)<<(num-1));
}
if(num == 10)
{
num = 0;
RXFlag = 0;
}
}
}
定时器的中断回调函数中,我们逐一读取数据的低位到高位,将其存入缓存区Recive中。
之后我们运行代码,Debug代码,利用串口助手发送数据,查看Recive的数据是否为我们发送的数据。
我们在设置一个接收完成的标志,当接收完成的时候,就将我们的数据利用上期我们模拟发送的代码发送回来。
可以实现接收和发送。
但是接收和发送的乱码率还是比较高的。

这可能是由于共用一个定时器的原因,导致接收的数据出现了异常。
主要代码
/* USER CODE BEGIN 4 */
int TXnum = 0;
int RXnum = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(TXFlag==1)
{
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_9,Data[TXnum++]);
if(TXnum == 10)
{
TXnum = 0;
TXFlag = 0;
TXSTA = 1;
}
}
/*
外部中断触发后接收信息
*/
if(RXFlag==1)
{
if(RXnum>=1&&RXnum<=8)
{
/*
从第二位开始总计八位,对应数据从低到高
*/
Recive = Recive|(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_10)<<(RXnum-1));
}
RXnum++;
if(RXnum == 10)
{
RXnum = 0;
RXFlag = 0;
RXSTA = 1;
}
}
}
/* 中断回调函数 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(RXFlag==0)
{
RXFlag = 1;
Recive = 0;
RXSTA = 0;
}
}
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include
int Data[10];
int RXFlag = 0;
int TXFlag = 0;
int RXSTA = 0;
int TXSTA = 1;
unsigned char Recive = 0;
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
void MyPrintf(int s);
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void MyPrintf(int s)
{
if(TXFlag==0 && TXSTA)
{
Data[0] = 0;
for(unsigned char i = 0;i<8;i++)
{
if(s & 0x01){
Data[i+1] = 1;
}
else{
Data[i+1] = 0;
}
s = s >> 1;
}
Data[9] = 1;
TXFlag = 1;
TXSTA = 0;
}
}
int fputc(int ch, FILE *f) {
// 发送单个字符
MyPrintf(ch);
// 返回发送的字符
return ch;
}
嘉立创PCB


登录 或 注册 后才可以进行评论哦!
还没有评论,抢个沙发!