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();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)