赞
踩
由于本人做题目时发现正点原子的串口发送教程是单字节,也在网上找了许多案例,但都不是很满意,这里借鉴了一下B站江科大UP主的代码,结合自己的需求,改了一下,大家可以参考一下,讲的很好,话不多说,直接上代码,希望帮助更多小伙伴。同时哪里不对的地方望大神多多指教。
usart.c
头文件自己添加
#if 1 #pragma import(__use_no_semihosting) uint8_t Serial_TxPacket[4]; //FF 01 02 03 04 FE uint8_t Serial_RxPacket[4]; uint8_t Serial_RxFlag; //标准库需要的支持函数 struct __FILE { int handle; }; FILE __stdout; //定义_sys_exit()以避免使用半主机模式 void _sys_exit(int x) { x = x; } //重定义fputc函数 int fputc(int ch, FILE *f) { while ((USART1->SR & 0X40) == 0); //循环发送,直到发送完毕 USART1->DR = (u8) ch; return ch; } #endif /*使用microLib的方法*/ /* int fputc(int ch, FILE *f) { USART_SendData(USART1, (uint8_t) ch); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {} return ch; } int GetKey (void) { while (!(USART1->SR & USART_FLAG_RXNE)); return ((int)(USART1->DR & 0x1FF)); } */ //#if EN_USART1_RX //如果使能了接收 //串口1中断服务程序 //注意,读取USARTx->SR能避免莫名其妙的错误 u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节. //接收状态 //bit15, 接收完成标志 //bit14, 接收到0x0d //bit13~0, 接收到的有效字节数目 u16 USART_RX_STA = 0; //接收状态标记 char rxarray[4]; uint8_t rxlength=0; //字符串发送函数 void HMISends(char *buf1) { u8 i=0; while(1) { if(buf1[i] != 0) { USART_SendData(USART1,buf1[i]); //发送一个字节 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET){};//等待发送结束 i++; } else { return ; } } } //字节发送函数 void HMISendb(u8 k) { u8 i; for(i=0; i<3; i++) { if(k != 0) { USART_SendData(USART1,k); //发送一个字节 while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET){};//等待发送结束 } else { return ; } } } void uart_init(u32 bound) { //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟 //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 //USART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3 ; //抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //USART 初始化设置 USART_InitStructure.USART_BaudRate = bound;//串口波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式 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); //初始化串口1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_Cmd(USART1, ENABLE); //使能串口1 } void Serial_SendByte(uint8_t Byte) { USART_SendData(USART1, Byte); while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } void Serial_SendArray(uint8_t *Array, uint16_t Length) { uint16_t i; for (i = 0; i < Length; i ++) { Serial_SendByte(Array[i]); } } void Serial_SendPacket(void) //发送字头 { Serial_SendByte(0xFF); Serial_SendArray(Serial_TxPacket, 4); Serial_SendByte(0xFE); } uint8_t Serial_GetRxFlag(void) //读取状态位 { if (Serial_RxFlag == 1) { Serial_RxFlag = 0; return 1; } return 0; } char tjcstr[100]; void USART1_IRQHandler(void) { int a=9; static uint8_t RxState = 0; static uint8_t pRxPacket = 0; if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET) { uint8_t RxData = USART_ReceiveData(USART1); // printf ("%d",RxData); if (RxState == 0) { if (RxData == 0xFF) { RxState = 1; pRxPacket = 0; } } else if (RxState == 1) { Serial_RxPacket[pRxPacket] = RxData; pRxPacket ++; if (pRxPacket >= 4) { RxState = 2; } } else if (RxState == 2) { if (RxData == 0xFE) { RxState = 0; Serial_RxFlag = 1; } } USART_ClearITPendingBit(USART1, USART_IT_RXNE); } }
usart.h
#ifndef __USART_H #define __USART_H #include "stdio.h" #include "sys.h" #define USART_REC_LEN 200 //定义最大接收字节数 200 #define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收 extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 extern u16 USART_RX_STA; //接收状态标记 //如果想串口中断接收,请不要注释以下宏定义 void uart_init(u32 bound); extern char rxarray[4]; extern uint8_t rxlength; extern uint8_t Serial_TxPacket[]; extern uint8_t Serial_RxPacket[]; void Serial_Init(void); void Serial_SendByte(uint8_t Byte); void Serial_SendArray(uint8_t *Array, uint16_t Length); void Serial_SendString(char *String); void Serial_SendNumber(uint32_t Number, uint8_t Length); void Serial_Printf(char *format, ...); void Serial_SendPacket(void); uint8_t Serial_GetRxFlag(void); #endif
大家需要注意的是发送数据格式,当然包头包尾自己可以改下哈。
格式:FF 12 45 67 89 FE
我们发送的数据都被数组接收了,那怎样打印出来尼,看大招。
- while(1)
- {
-
- if (Serial_GetRxFlag() == 1)
- {
- for(i=0;i<4;i++)
- {
- printf ("%x", Serial_RxPacket[i]);
- }
-
- }
- }
方法2
if(rxlength == 4) { //int rxint = (rxarray[0] << 24) | (rxarray[1] << 16) | (rxarray[2] << 8) | (rxarray[3]); //printf("get %c,%c,%c,%c",rxarray[0],rxarray[1],rxarray[2],rxarray[3]); union tmpa2i { char tmpa[4]; int tmpi; } tmpa2i1; tmpa2i1.tmpa[0] = rxarray[0]; tmpa2i1.tmpa[1] = rxarray[1]; tmpa2i1.tmpa[2] = rxarray[2]; tmpa2i1.tmpa[3] = rxarray[3]; int rxint = tmpa2i1.tmpi; printf("\x01\xff\xff\xffpage2.n7.val=%d\xff\xff\xff",rxint); rxlength = 0; }
他们的原理都差不多,都是数组接收,打印的方式不一样罢了,方法2是串口屏给单片机发送数据时写的,大家如果使用的是串口屏的话推荐看方法2。
需要源代码的伙伴评论区聊吧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。