stm32 串口模拟



#define TXIO PB0 
#define RXIO PB1in 
#define bit(n) PB0=n
#define Delay_n 53 //波特率根据延时在设置  19200波特率   

void IR_SendByte(u8 val)//发送bit位
 {
     u16 i;
     bit(0); 
     Delay_us(Delay_n);
     for(i=0;i<8;i++)
      {
       if(val&0x1){bit(1);}
       else{bit(0);}
       val>>=1;
       Delay_us(Delay_n);
      }
    bit(1); 
    Delay_us(Delay_n);
 }

void IR_SendStr(u8*st,u16 len)
{//在这填入16位数据即可
 int i=0;
 while ((len--)!=0)
 {  
   IR_SendByte(st[i]);
   i++;
 }
}


enum{
	COM_START_BIT,
	COM_D0_BIT,
	COM_D1_BIT,
	COM_D2_BIT,
	COM_D3_BIT,
	COM_D4_BIT,
	COM_D5_BIT,
	COM_D6_BIT,
	COM_D7_BIT,
	COM_STOP_BIT,
};
/*
定义好了状态机,还需要一个变量,来保存这些状态机的变化,并定义它的初始状态为COM_STOP_BIT:
下面是PA5的外部中断服务程序,它的主要任务是检测起始位,当他第一次检测到下降沿,则说明数据即将到来,这时只要打开定时器就可以了:
*/
u8 recvStat = COM_STOP_BIT;
u8 recvData = 0;
unsigned int len = 0;	//接收计数
u8 USART_buf[1024];  //接收缓冲区

void TIM4_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能
  //定时器TIM4初始化
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
	TIM_ClearITPendingBit(TIM4, TIM_FLAG_Update);
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级1级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  //从优先级1级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器			 
}


void EXTI1_IRQHandler(void)
{
	if(EXTI_GetFlagStatus(EXTI_Line1) != RESET)
	{
		if(RXIO == 0)  //检测引脚高低电平,如果是低电平,则说明检测到下升沿
		{
			if(recvStat == COM_STOP_BIT)
			{
				recvStat = COM_START_BIT; //状态为停止位
        //Delay_us(10); //延时一定时间
				TIM_Cmd(TIM4, ENABLE);
			}
		}
		EXTI_ClearITPendingBit(EXTI_Line1);
	}
}

void TIM4_IRQHandler(void)
{  
	if(TIM_GetFlagStatus(TIM4, TIM_FLAG_Update) != RESET)
	{
		TIM_ClearITPendingBit(TIM4, TIM_FLAG_Update);	
		 recvStat++;
		if(recvStat == COM_STOP_BIT)
		{
			TIM_Cmd(TIM4, DISABLE);
			USART_buf[len++] = recvData;	
			return;
		}
		if(RXIO==1)
		{
			recvData |= (1 << (recvStat - 1));
		}else{
			recvData &= ~(1 << (recvStat - 1));
		}	
  }		
}







int nn=0;
void usart_my(void)
{
     EXTI_InitTypeDef EXTI_InitStructure;
     NVIC_InitTypeDef NVIC_InitStructure;
     GPIO_InitTypeDef GPIO_InitStructure;
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE);
    
   //	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 	
//    //因为PB4 和 JTAG 共用IO,需要禁止JTAG
//	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);  //开启AFIO时钟
//	  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //禁止JTAG功能  	

//	
   	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 
  	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	//最大输出速度为50MHz
  	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	
  	GPIO_Init(GPIOB, &GPIO_InitStructure);			//设置GPIO
		PB0 = 0;

 
  
	//SoftWare Serial RXD
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
	GPIO_Init(GPIOB, &GPIO_InitStructure);	 

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);
	EXTI_InitStructure.EXTI_Line = EXTI_Line1;
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling; //下降沿触发中断
	EXTI_InitStructure.EXTI_LineCmd=ENABLE;
	EXTI_Init(&EXTI_InitStructure);


	NVIC_InitStructure.NVIC_IRQChannel= EXTI1_IRQn ; 
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2; 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;  
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;  
	NVIC_Init(&NVIC_InitStructure);  
   
             
 
IR_SendStr("模拟uart 测试\r\n",strlen("模拟uart 测试\r\n"));

while(1)
	{
		if(len >=2048)
		{nn=len;     len = 0;			
			IR_SendStr(USART_buf,nn);

		}
	}


	while(1)
{

IR_SendStr("0123456789模拟uart 测试\r\n",strlen("0123456789模拟uart 测试\r\n"));
}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103是意法半导体(STMicroelectronics)推出的一款具有高性能和低功耗特点的32位ARM Cortex-M3微控制器。它具有丰富的外设资源,包括模拟串口功能。 模拟串口是一种软件模拟的串行通信接口,通过GPIO引脚模拟实现串口的收发功能。相对于硬件串口模拟串口的实现更加灵活,可以根据实际需求进行频率和波特率的调整。 在STM32F103上实现模拟串口,首先需要配置相应的GPIO引脚作为串口的收发引脚。然后,通过编写相关的软件代码,实现串口数据的发送和接收。 对于发送数据,可以设置GPIO引脚的状态为高电平或低电平,模拟发送的数据位。可以使用循环遍历的方式,逐位将要发送的数据写入GPIO引脚,并根据波特率确定数据的发送时序。 对于接收数据,需要通过GPIO引脚读取接收到的高电平或低电平状态,将其转化为二进制数据。可以使用延时和状态判断的方法,确定接收时序,并逐位读取接收到的数据。 模拟串口的实现需要考虑到波特率、数据位、停止位和校验位等参数的配置。可以使用定时器作为时钟源,保证数据的发送和接收具有一定的稳定性和可靠性。 总之,STM32F103的模拟串口功能可以通过配置GPIO引脚和编写相应的软件代码实现。通过模拟实现串口的收发功能,可以满足一些特殊应用需求,提高系统的灵活性和可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值