7816时一个比较早的老通讯时序了,最近项目上需要用UART模拟所以,简单学习时序。
时序比较简单,熟悉UART的一眼看着就像是串口的时序,只是他没有停止位,取而代之的就是保护时间guradtime,一般是两个etu所以可以使用两个停止位来模拟。电路图上就是将RX和TX短接,在发送关闭串口的接受功能反之接收时关闭发送功能就可以了。
1、报文格式。
C-APDU有4字节的必备长度和1个可变长度条件体组成
CLA:命令报文类别字节
INS:命令报文指令字节
P1:参数1
P2:参数2
LC:条件体数据域的实际长度
DATA:数据域
Le:期望返回数据的长度
CLA INS P1 P2 LC DATA Le 这里需注意的就是在物理链路上给卡发送APUD指令时需要按一下时序发送,先发送前5个字节然后等待卡回应INS 后才可继续发送余下的DATA,LE可以没有。
初始化同普通接口初始化相同
初始化代码
GPIO\_InitTypeDef GPIO\_InitStructure;
NVIC\_InitTypeDef NVIC\_InitStructure;
USART\_InitTypeDef USART\_InitStructure;
RCC\_APB2PeriphClockCmd( RCC\_APB2Periph\_GPIOB | RCC\_APB2Periph\_AFIO, ENABLE);
RCC\_APB1PeriphClockCmd(RCC\_APB1Periph\_USART3, ENABLE);
GPIO\_InitStructure.GPIO\_Pin = FM151\_TXD\_PIN;
GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_AF\_PP;
GPIO\_InitStructure.GPIO\_Speed = GPIO\_Speed\_50MHz;
GPIO\_Init(FM151\_PORT, &GPIO\_InitStructure);
GPIO\_InitStructure.GPIO\_Pin = FM151\_RXD\_PIN;
GPIO\_InitStructure.GPIO\_Mode = GPIO\_Mode\_IN\_FLOATING;
GPIO\_InitStructure.GPIO\_Speed = GPIO\_Speed\_50MHz;
GPIO\_Init(FM151\_PORT, &GPIO\_InitStructure);
USART\_InitStructure.USART\_BaudRate = 9600;
USART\_InitStructure.USART\_WordLength = USART\_WordLength\_9b;//9位数据
USART\_InitStructure.USART\_StopBits = USART\_StopBits\_1;//1位停止位
USART\_InitStructure.USART\_Parity = USART\_Parity\_Even;//偶校验
USART\_InitStructure.USART\_HardwareFlowControl = USART\_HardwareFlowControl\_None; //硬件流控制失能
USART\_InitStructure.USART\_Mode = USART\_Mode\_Rx | USART\_Mode\_Tx; //发送和接受使能
USART\_Init(USART3, &USART\_InitStructure);
//Usart1 NVIC 配置
NVIC\_InitStructure.NVIC\_IRQChannel = USART3\_IRQn;
NVIC\_InitStructure.NVIC\_IRQChannelPreemptionPriority = 4 ; //抢占优先级4
NVIC\_InitStructure.NVIC\_IRQChannelSubPriority = 0; //子优先级0
NVIC\_InitStructure.NVIC\_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC\_Init(&NVIC\_InitStructure); //根据指定的参数初始化VIC寄存器
USART\_Cmd(USART3, ENABLE);
USART\_ITConfig(USART3, USART\_IT\_RXNE, DISABLE); //开始都不允许接受中断
这里采用中断接受,所以需要字节实现自己的中断服务函数。
发送数据
static void UartSendByte(u8 *dat)
{
while (USART\_GetFlagStatus(USART3, USART\_FLAG\_TXE) == RESET);
USART\_SendData(USART3, \*dat);
while (USART\_GetFlagStatus(USART3, USART\_FLAG\_TC) == RESET);
USART\_ClearFlag(USART3, USART\_FLAG\_TC);
delay\_us(guardtime);
}
发送一定字节数据
void SendData(u8 *data, u16 datalenth)
{
u16 i;
SetUartDir(TX);
for (i = 0; i < datalenth - 1; i++)
{
UartSendByte(data + i);
}
UartSendLastByte(data + i);
SetUartDir(RX);
}
这里注意最后一个字节不需要额外的保护时间。最后就是配置UART的接受和发送的寄存器函数。
void SetUartDir( u8 dir)
{
u32 reg;
//发送时禁止接收,发送完成才开始接收
if (dir == RX)
{
reg = USART3->CR1;
reg |= USART_Mode_Rx;
reg &= (~USART_Mode_Tx);
USART3->CR1 = reg;
USART\_ITConfig(USART3, USART\_IT\_RXNE, ENABLE);
}
else if (dir == UART\_TXD)
{
reg = USART3->CR1;
reg |= USART\_Mode\_Tx;
reg &= (~USART\_Mode\_Rx);
USART3->CR1 = (u16)reg;
USART\_ITConfig(USART3, USART\_IT\_RXNE, DISABLE);
}
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章