stm32 普通io模拟串口程序

本程序中

使用GPIOB.5-作为TX,,,GPIOD.6作为RX

并将这两个IO口接在led上,能够查看发送和接受的数据状态。

使用tim3作为定时器中断,本程序中将波特率设置为 1bps  的原因是想从led灯的状态读取发送和接受的数据

 

下面为我的程序

#include <stdio.h>
#include "stm32f10x.h"

#include "misc.h"
#include "stm32f10x_exti.h"
#include "stm32f10x_tim.h"
#include "stm32f10x_usart.h"

void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void TIM3_Configuration(void);

unsigned char receive(int a);
int receive_bit(void);
void send(int value);
void send_bit(int send_bit_vlaue);
int send_bit_flag=0;
unsigned char receive_final_value=0;
unsigned char receive_disfinal_value=0;
int i = 0,k=0,j=0;
unsigned char  result = 0;
int value_bit[10];
int receive_flag=0;
int u=0x5a;


int main(void)
{
	RCC_Configuration();
  GPIO_Configuration();
	TIM3_Configuration();
	NVIC_Configuration();
	GPIO_SetBits(GPIOB,GPIO_Pin_2);
	GPIO_SetBits(GPIOB,GPIO_Pin_5);
	value_bit[9] = 1;
	while(1)
	{
		

		if(receive_final_value ==0x44 )
		{
			GPIO_SetBits(GPIOD,GPIO_Pin_3);
    }
		if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==Bit_RESET)
	  {
		  send(0x44);
      send_bit_flag=1;			
    }
		
		
  }
	return 0;
}

void send(int value)
{
	value_bit[0]=0;
	value_bit[9]=1;
	for(i = 1; i < 9; i++)
	{
		value_bit[i] = value & 1;
		value = value >> 1;
  }
}


void send_bit(int send_bit_vlaue)
{
	if(send_bit_vlaue == 1)
	{
		GPIO_SetBits(GPIOB,GPIO_Pin_5);
  }
	else
	{
		GPIO_ResetBits(GPIOB,GPIO_Pin_5);
  }
}



int receive_bit()
{ 
	int receive_bit_value=1;
	receive_bit_value=GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6);
	return receive_bit_value;
}

unsigned char  receive(int a)
{
	result=result>>1;
	if(a==1)
	{
		result=result|0x80;
	}
	return result;
}

void TIM3_IRQHandler(void)
{
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);	
	if(send_bit_flag==1)
	{
		send_bit(value_bit[k]);
		k++;
	}
	if(k==10)
	{
		send_bit_flag=0;
		k=0;
	}
	
	if(receive_flag==1)
	{
		receive_disfinal_value=receive(receive_bit());
		j++;
	}
	if(receive_bit() == 0)
	{
		receive_flag=1;
	}
	if(j==8)
	{
		receive_final_value=receive_disfinal_value;
		u=receive_final_value;
		receive_flag=0;
		j=0;
	}

}

void RCC_Configuration(void)
{
	SystemInit();
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); 
}

void GPIO_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_5);
	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_Init(GPIOD,&GPIO_InitStructure);
	

	
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_Init(GPIOD,&GPIO_InitStructure);
	

	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
  GPIO_Init(GPIOC,&GPIO_InitStructure);
	

}

void TIM3_Configuration(void)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
	
  TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
  TIM_TimeBaseStruct.TIM_Period=1999;
  TIM_TimeBaseStruct.TIM_Prescaler=35999;
  TIM_TimeBaseStruct.TIM_ClockDivision=0;
  TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up;
	
  TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStruct);
	
  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
  TIM_Cmd(TIM3,ENABLE);
}


void NVIC_Configuration(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
	
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

 

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32中,通过普通IO模拟串口通信,需要自己编写相关的发送和接收函数来实现数据的处理和解析。下面是一个示例代码,可以供你参考: ```c #include "stm32f1xx.h" #define UART_TX GPIO_PIN_9 // 发送引脚 #define UART_RX GPIO_PIN_10 // 接收引脚 #define BAUDRATE 9600 // 波特率 GPIO_InitTypeDef GPIO_InitStruct; void delay_us(uint32_t us) { uint32_t tickstart = HAL_GetTick(); uint32_t wait = us * (SystemCoreClock / 1000000U); while ((HAL_GetTick() - tickstart) < wait) { } } void UART_GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); // 使能GPIOA时钟 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Pin = UART_TX; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 配置发送引脚为输出模式 GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pin = UART_RX; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 配置接收引脚为输入模式 } void UART_SendByte(uint8_t data) { uint8_t i; HAL_GPIO_WritePin(GPIOA, UART_TX, GPIO_PIN_RESET); // 发送起始位 for (i = 0; i < 8; i++) { // 按位发送数据 if (data & 0x01) { HAL_GPIO_WritePin(GPIOA, UART_TX, GPIO_PIN_SET); } else { HAL_GPIO_WritePin(GPIOA, UART_TX, GPIO_PIN_RESET); } data >>= 1; delay_us(1000000 / BAUDRATE); } HAL_GPIO_WritePin(GPIOA, UART_TX, GPIO_PIN_SET); // 发送停止位 delay_us(1000000 / BAUDRATE); } uint8_t UART_ReceiveByte(void) { uint8_t data = 0; uint8_t i; while (HAL_GPIO_ReadPin(GPIOA, UART_RX) == GPIO_PIN_RESET) { // 等待接收起始位 } delay_us(1000000 / BAUDRATE / 2); // 延时半个波特率时钟周期,等待数据位 for (i = 0; i < 8; i++) { // 按位接收数据 data >>= 1; if (HAL_GPIO_ReadPin(GPIOA, UART_RX) == GPIO_PIN_SET) { data |= 0x80; } delay_us(1000000 / BAUDRATE); } while (HAL_GPIO_ReadPin(GPIOA, UART_RX) == GPIO_PIN_SET) { // 等待接收停止位 } return data; } int main(void) { HAL_Init(); UART_GPIO_Init(); // 初始化GPIO口 while (1) { UART_SendByte(0xAA); // 发送数据 uint8_t data = UART_ReceiveByte(); // 接收数据 } } ``` 在这个示例代码中,我们使用GPIOA的Pin9和Pin10分别模拟串口的发送和接收。在发送数据时,我们将发送引脚拉低,并按照位的顺序依次将数据输出到发送引脚上。在接收数据时,我们轮询接收引脚的电平状态,按照位的顺序将数据接收下来。需要注意的是,由于使用IO模拟串口的收发,在高速通讯时容易出现误码和数据丢失等问题,因此需要充分测试和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值