打印
[APM32F4]

APM32F4xx 系列软件模拟 USART

[复制链接]
1242|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wex1002|  楼主 | 2024-9-9 09:28 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
引言
在系统使用过程中,可能会遇到系统资源(如串口)不够的情况,此时可以使用 IO 口模拟串口,实现同样的功能。本应用笔记介绍了在 APM32F4xx 系列上通过外部中断和定时器如何实现IO 口模拟串口。



APM32F4xxUSART简介

USART(通用同步异步收发器)是一个可以灵活地与外部设备进行全双工、半双工数据交换的串行通信设备,且同时满足外部设备对工业标准NRZ 异步串行数据格式的要求。USART 还提供宽范围的波特率选择,且支持多处理器通信。USART 不仅支持标准的异步收发模式,也支持一些其他的串行数据交换模式,如LIN 协议、智能卡协议、IrDA SIR ENDEC 规范和硬件流控制模式。USART 还支持使用DMA 功能,以实现高速数据通信。



串口模式

串行通讯是指将数据逐位顺序传送的通信方式。串口分为同步串行接口和异步串行接口。



同步模式:一次传输的数据块中包含的数据较多,所以接收时钟与发送时钟严格同步,比异步模式多了一个可以输出同步时钟的信号线USART_CK。适用于大批量数据需要传输的情况。下图为USART 同步发送时序图,分别给出极性和相位自由组合成的四种情况,图1USART_CTRL1寄存器的DBLCFG=0,对应1位起始位,8位数据位,一位停止位的情况,图2USART_CTRL1寄存器的DBLCFG=1,对应1位起始位,9位数据位,1位停止位的情况。其中USART_CK 的时钟极性由USART_CTRL2 寄存器的CPOL位决定:CPOL0时,CK 脚的空闲状态为低电平;CPOL1时,CK引脚的空闲状态为高电平。USART_CK的相位由USART_CTRL2寄存器的CPHA位决定:CPHA0时,表明在第1个时钟边沿进行采样;CPOL1时,表明在第2个时钟边沿进行采样。



同步模式:一次传输的数据块中包含的数据较多,所以接收时钟与发送时钟严格同步,比异步模式多了一个可以输出同步时钟的信号线USART_CK。适用于大批量数据需要传输的情况。下图为USART 同步发送时序图,分别给出极性和相位自由组合成的四种情况,图1USART_CTRL1寄存器的DBLCFG=0,对应1位起始位,8位数据位,一位停止位的情况,图2USART_CTRL1寄存器的DBLCFG=1,对应1位起始位,9位数据位,1位停止位的情况。其中USART_CK 的时钟极性由USART_CTRL2 寄存器的CPOL位决定:CPOL0时,CK 脚的空闲状态为低电平;CPOL1时,CK引脚的空闲状态为高电平。USART_CK的相位由USART_CTRL2寄存器的CPHA位决定:CPHA0时,表明在第1个时钟边沿进行采样;CPOL1时,表明在第2个时钟边沿进行采样。




图 1 USART 同步发送时序图(DBLCFG=0)





2 USART 同步发送时序图(DBLCFG=1)



异步模式是串行,异步,全双工的通信。通过收发双方约定相同波特率实现同步通信,数据以相同的帧格式进行发送。通常运用在短距离、速率不高的工业实际应用中。本文主要讨论异步串口通信情况。



UART 通信协议概述

异步通信需要收发双方约定波特率,确定每位比特位的持续时间,以保证双方的时序同步。其中,波特率是指单位时间内传送的码元的符号个数。
如图 3,图 4 所示,串口的报文格式为:起始位(1bit)+ 数据位(5~8 bits)+ 奇偶校验位0/1 bit+停止位(0.5~1.5 bits)。
起始位:使用串口时,在发送有效,自动产生 1bit 的低电平起始位。
数据位:通信时有效数据的长度,通常为 5~8 位。在进行数据收发前,应先完成相应的配置。
奇偶校验位:增加校验位以检验传输过程中是否因干扰出现数据传输错误的情况。设置为奇校验,确保传输数据逻辑高位的个数为奇数;设置为偶校验,确保传输数据逻辑高位的个数为偶数。
停止位:有效数据发送完毕后,发送设定位数的高电平,表示一帧数据传输结束。空闲位:在下一个起始位逻辑低位到来之前,数据线一直保持高位状态。空闲位不属于报文内容。




图 3 串口帧结构图(含空闲位)


图 4 串口帧结构图(不含空闲位)



软件模拟串口

硬件设计

本次设计使用 APM32F407ZGT6 的 GPIO PB9,PB10 分别模拟串口的发送线 TX 和接收线 RX。借助 USB TTL 线,将 RX 连接开发板的 PB9TX 连接 PB10,同时将两边地线相连。




图 5 硬件连接图



软件设计

本次设计实现功能为接收串口助手发送的数据后,发送相同数据进行回显。设置波特率为 9600 bps,起始位 1 bit,数据位 8 bit,不设校验位,停止位 1 bit
设计思路为:将功能实现分为接收和发送两个部分。
接收功能的实现,需要以精确的延时为前提;从而获得正确的数据。例程使用通用定时器定时104us(t = 1/9600 s = 104us)进入中断,在中断服务函数中按位接收数据。
将接收到的数据存入缓存区,并将其发送到串口助手进行回显。
发送功能实现相对简单:将数据线置 0,模拟起始位;利用滴答定时器进行延时 104us;利用 for循环按位发送并延时。完成 8 位数据位传输后,将数据线置 1,模拟停止位。




图 6 软件实现流程图



GPIO 配置

函数完成了 GPIO PB9,PB10 的初始化配置。
将发送引脚 TX PB9 配置为推挽输出模式,输出速度为 50MHz。串口在空闲时,数据位为高电平状态,因此,完成配置后,需将 PB9 1
将接收引脚 RX PB10 配置为上拉输入模式,同时配置外部中断,数据开始传输前,一定会产生一个下降沿。因此将 PB10 中断触发方式设定为下降沿触发。



void Soft_Usart_Init(void)
{
GPIO_Config_T gpioConfig;
EINT_Config_T eintConfig;
RCM_EnableAHB1PeriphClock(RCM_AHB1_PERIPH_GPIOB);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
/* Tx GPIOB PIN9 */
GPIO_ConfigStructInit(&gpioConfig);
gpioConfig.mode = GPIO_MODE_OUT;
gpioConfig.otype = GPIO_OTYPE_PP;
gpioConfig.pin = GPIO_PIN_9;
gpioConfig.speed = GPIO_SPEED_50MHz;
GPIO_Config(GPIOB,&gpioConfig);
GPIO_SetBit(GPIOB,GPIO_PIN_9);
/* Rx GPIOB PIN10 */
GPIO_ConfigStructInit(&gpioConfig);
gpioConfig.mode = GPIO_MODE_IN;
gpioConfig.pin = GPIO_PIN_10;
gpioConfig.pupd = GPIO_PUPD_UP;
gpioConfig.speed = GPIO_SPEED_50MHz;
GPIO_Config(GPIOB,&gpioConfig);
SYSCFG_ConfigEINTLine(SYSCFG_PORT_GPIOB,SYSCFG_PIN_10);
eintConfig.line = EINT_LINE_10;
eintConfig.mode = EINT_MODE_INTERRUPT;
eintConfig.lineCmd = ENABLE;
eintConfig.trigger = EINT_TRIGGER_FALLING;
EINT_Config(&eintConfig);
NVIC_EnableIRQRequest(EINT15_10_IRQn,2,3);
}
TMR 配置

例程使用 TMR4 通用定时器。根据波特率 9600 bps 可知,每一位数据的持续时间为 104.16us配置一次计数时间为 1us,周期设定为 104 可达到所需定时效果。

TMR4 时钟线为 APB1,如图 7,图 8 和图 9 所示,根据用户手册和系统时钟初始化函数可知APB1 AHB1 进行 4 分频后得到,最大频率为 42MHzTMR 时钟频率为 42 * 2 = 84MHz。根据计算公式将预分频系数设置为 83,得到计数器驱动时钟为 84 /83+1= 1MHz,即计数一次时间为 1/1M s = 1 us。一次中断产生的时间间隔为自动重装载值 104 * 计数一次所需时间 1us=104us



表格 1 计算公式说明及使用



图 7 RCM 寄存器配置


图 8 APB1PSC 位域说明


图 9 时钟树

void TMR4_Init(void)
{
TMR_BaseConfig_T TMRBaseConfig;
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_TMR4);
TMRBaseConfig.clockDivision = TMR_CLOCK_DIV_1;
TMRBaseConfig.countMode = TMR_COUNTER_MODE_UP;
TMRBaseConfig.division = 84 - 1;
TMRBaseConfig.period = 104;
TMR_ConfigTimeBase(TMR4,&TMRBaseConfig);
TMR_ClearStatusFlag(TMR4,TMR_FLAG_UPDATE);
TMR_Enable(TMR4);
/* Configure NVIC_IRQRequest */
TMR_EnableInterrupt(TMR4,TMR_INT_UPDATE);
NVIC_EnableIRQRequest(TMR4_IRQn,2,1);
}





使用特权

评论回复
沙发
wex1002|  楼主 | 2024-9-9 15:19 | 只看该作者
GPIO 模拟串口发送
根据图 3 可知,空闲时数据线处于高电平状态,由高电平跳变为低电平表示通信开始,因此在有效数据传输前将 PB9 置 0;发送起始位后,根据设置的波特率,延时 104us,利用 for 循环开始发送数据位。需要注意的是,串口由最低位开始发送。数据位发送结束,将引脚置 1,模拟停止位。
void Soft_Usart_TXData(u8 ch)
{
uint8_t i = 0;
GPIO_ResetBit(GPIOB,GPIO_PIN_9);
Delay_us(BaudRate_9600);
for(i = 0; i < 8; i++)
{
if(ch & 0x01)
{
GPIO_SetBit(GPIOB,GPIO_PIN_9);
}
else
{
GPIO_ResetBit(GPIOB,GPIO_PIN_9);
}
Delay_us(BaudRate_9600);
ch = ch >> 1;
}
GPIO_SetBit(GPIOB,GPIO_PIN_9);
Delay_us(BaudRate_9600);
}
void Soft_Usart_Send(u8 *buf,u8 len)
{
uint8_t t;
for(t = 0;t < len;t++)
{
Soft_Usart_TXData(buf[t]);
Delay_ms(1);
}
}
GPIO 中断服务函数

当接收到低电平并且接收位超过或等于停止位时,此时重置接收状态为起始位,使能定时器,开始接收新一帧的数据。若接收状态未达到停止位,表示此时的下降沿由有效数据产生,并不表示新数据的到来,可直接跳出中断。

void EINT15_10_IRQHandler(void)
{
if(EINT_ReadStatusFlag(EINT_LINE_10) != RESET)
{
if(Soft_Usart_RXData() == 0)
{
if(recvState >= COM_STOP_BIT)
{
recvState = COM_START_BIT;
TMR_Enable(TMR4);
flag = 1;
}
}
EINT_ClearStatusFlag(EINT_LINE_10);
}
}
TMR 中断服务函数

开启定时器后,每隔 104us 触发中断。进入中断服务函数,完成数据的按位接收。由于串口发送数据时,由最低位开始发送,在接收一位数据后需通过移位,将其放置在正确的位置,保证接收数据的准确性。当读取到停止位时,将接收值存入缓存区。

void TMR4_IRQHandler(void)
{
if(TMR_ReadStatusFlag(TMR4,TMR_FLAG_UPDATE) != RESET)
{
TMR_ClearStatusFlag(TMR4,TMR_FLAG_UPDATE);
recvState++;
if(recvState >= COM_STOP_BIT)
{
TMR_Disable(TMR4);
USART_buf[len++] = recvData;
return;
}
if(Soft_Usart_RXData())
{
recvData |= (1 << (recvState - 1));
}
else
{
recvData &= ~(1 << (recvState - 1));
}
}
}
主函数

完成初始化后,持续发送接收到的数据。

int main(void)
{
NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_2);
Delay_Init();
Soft_Usart_Init();
TMR4_Init();
while (1)
{
if(len > 10)
{
len = 0;
Soft_Usart_Send(USART_buf,11);
}
}
}



使用特权

评论回复
板凳
wex1002|  楼主 | 2024-9-9 15:20 | 只看该作者
实验现象
打开串口调试助手,设置波特率,起始位,数据位和停止位后,发送字符,成功回显。


图 10 实验现象




使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

4

主题

167

帖子

0

粉丝