STM32F407VET6 普通 IO 口模拟串口发送数据

1、只实现了,使用普通 IO 口模拟串口的发送,没有实现接收

2、由于是模拟发送的是 TTL 电平,所以在使用串口助手验证发送数据的准确性时,应该使用 USB 转 TTL ,而不能使用 USB 转 232(验证时,本人犯了这样的错误)

方法一:调节占空比,实现定时器延时

/对应波特率的1个电平持续时间
//(1/2400) = 416us
#define IO_USART_SENDDELAY_TIME 	416

void uart_tx_bit(uint8_t bit) {
	if (bit == 1) {
		GPIO_SetBits(GPIOD, GPIO_Pin_12);
	} else {
		GPIO_ResetBits(GPIOD, GPIO_Pin_12);
	}
}

void uart_tx_delayus(uint32_t nTime) {
	uint16_t tmp;
	//获得 TIM4 计数器的值
	tmp = TIM_GetCounter(TIM4);
	if (tmp + nTime <= 65535)
		while ((TIM_GetCounter(TIM4) - tmp) < nTime);
	else {
		TIM_SetCounter(TIM4, 0);
		//设置 TIM4 计数器寄存器值为0
		while (TIM_GetCounter(TIM4) < nTime);
	}
}

void uart_tx_byte(uint8_t data) {
	uint8_t i, tmp;

	// 开始位
	uart_tx_bit(0);	//将TXD的引脚的电平置低
	uart_tx_delayus(IO_USART_SENDDELAY_TIME);

	for (i = 0; i < 8; i++) {
		tmp = (data >> i) & 0x01;
		if (tmp == 0) {
			uart_tx_bit(0);
			uart_tx_delayus(IO_USART_SENDDELAY_TIME);	//0
		} else {
			uart_tx_bit(1);
			uart_tx_delayus(IO_USART_SENDDELAY_TIME);	//1
		}
	}
	// 结束位
	uart_tx_bit(1);	//将TXD的引脚的电平置高
	uart_tx_delayus(IO_USART_SENDDELAY_TIME);
}

static void hw_init(void) {
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
	GPIO_SetBits(GPIOD, GPIO_Pin_12);

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
	TIM_TimeBaseStruct.TIM_Period = 65535 - 1;
	TIM_TimeBaseStruct.TIM_Prescaler = 84 - 1;  
	TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStruct);
	TIM_Cmd(TIM4, ENABLE);
}

void uart_tx_init(void) {
	hw_init();
}

方法二:定时器中断的方式

//对应波特率的1个电平持续时间
//(1/2400) = 416us
#define IO_USART_SENDDELAY_TIME 	416

static int send_bit_flag = 0;
static int value_bit[10];
static uint8_t k = 0;

static void send_bit(int bit) {
	if (bit == 1) {
		GPIOD->BSRRL = GPIO_Pin_12;
	} else {
		GPIOD->BSRRH = GPIO_Pin_12;
	}
}

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

	k = 0;
	TIM_Cmd(TIM4, ENABLE);
	send_bit_flag = 1;
}


void TIM4_IRQHandler(void) {
	if (TIM_GetITStatus(TIM4, TIM_IT_Update) == SET) {
		if (send_bit_flag == 1) {
			send_bit(value_bit[k]);
			k++;
		}
		if (k == 11) {
			TIM_Cmd(TIM4, DISABLE);
			send_bit_flag = 0;
			k = 0;
		}
	}
	/* 清除中断标志位 */
	TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
}

static void hw_init(void) {
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	GPIO_SetBits(GPIOD, GPIO_Pin_12);


	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
	TIM_TimeBaseStruct.TIM_Period = 416 - 1;
	TIM_TimeBaseStruct.TIM_Prescaler = 84-1; 
	TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStruct);

	TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
	TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
	TIM_Cmd(TIM4, DISABLE);

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}


void uart_tx_init(void) {
	hw_init();
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值