通信协议:通信数据以帧形式传递 [波特率、起始位、数据位、奇偶校验位、停止位]
以stm32f1系列芯片为例:共有5个串口,1-3是通用同步/异步串行接口USART(USART1-PA9、PA10 USART2-PA2、PA3 USART3-PB10、PB11) 4-5是通用异步串行接口UART(UART4-PC10、PC11 UART5-PC12、PD2)
代码实现:
(1)配置RX和TX引脚和串口初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_InitStructure.USART_BaudRate = bound;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
(2串口中断函数,一般以0x0D(ascill:13表示回车\r),0x0a(ascill:
10表示换行\n)结尾,是一种自定义数据帧结束标志,同时帧头也是定义的一种开始标志,因为不知道串口什么时候发送数据,定义帧头,当接收到帧头,剩下的数据是我们需要的,以openmv为例.当接收到0x2C,0x012,在单片机中定义一个USART_Rx_Buf[]存储c(x)和c(y)的数据。
data=ustruct.pack("kkkkkk",
0x2C,
0x12,
int(cx),
int(cy),
0x0d,
0x0a)
串口中断服务函数:
void USART1_IRQHandler(void)
{
u8 Res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
Res =USART_ReceiveData(USART1);
if((USART_RX_STA&0x8000)==0)
{
if(USART_RX_STA&0x4000)
{
if(Res!=0x0a)USART_RX_STA=0;
else USART_RX_STA|=0x8000;
}
else
{
if(Res==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;
}
}
}
}
第一次进入串口中断服务函数时,先判断是哪个串口接收到数据产生的中断,如果是,将接收到的1byte数据存储到变量里,接着判断是否还有数据没有接收完,如果接收到0x0d,0x0a,表示接收完成。USART_RX_STA有十六位,bit0-13表示有效数据,bit14表示接收到0x0d,bit15表示接收0x0a,接收完成。USART_GetFalgStatu
s函数用来检测串口中断标志位的状态,返回值为SET或者RESET。USART_GetITStatus函数用来判断中断标志位或是否发生中断,返回值为SET或者RESET。USART_ClearITPendingBit函数用在中断处理函数中对标志位进行清除操作。
(2)数据收发
void usart_SendingByte(USART_TypeDef *p_USARTx,unsigned char ch)
{
while(USART_GetFlagStatus(USARTx,USART_FLAG_TXE)!=SET);
USART_SendData(p_USARTx,ch);
}
void usart_sendingString(USART_TypeDef *p_USARTx,unsigned char *str)
{
unsigned int k;
do
{
usart_sending_byte(p_USARTx,*(str+k));
k++;
}
while(*(str+k)!='\0');
while(USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET)
{}
}
unsigned char usart_receive_byte(USART_TypeDef *p_USARTx,unsigned char ch)
{
while(USART_GetFlagStatus(USARTx,USART_FLAG_RXNE)!=SET);
USART_ClearITPendingBit(p_USARTx,USART_IT_RXNE);
ch=USART_ReceiveData(USARTx);
return ch;
}
#define max_Buff_len 8
unsigned char USART_Buffer[max_Buff_len];
unsigned char USART_Rx=0;
void USART_Send_Receive()
{
if(USART_GetITStatus(USART1,USART_FLAG_RXNE)!=RESET)
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
Uart1_Buffer[Uart1_Rx]=USART_ReceiveData(USART1);
Uart1_Rx++;
if(Uart1_Buffer[Uart1_Rx-1]==0x0a||Uart1_Rx==Max_BUFF_Len)
{
if(Uart1_Buffer[0]==0x01)
{
printf("%s\r\n",Uart1_Buffer);
Uart1_Rx=0;
}
else
{
Uart1_Rx=0;
}
}
}
}