韶关营销型网站建设,服装外贸流程,网站设计制作平台哪个好,大学学风建设网站目录
K210-UART串口通信相关函数#xff1a;
使用K210串口的时候需要映射引脚#xff1a;
K210与STM32串口通信
发送单字节#xff1a;
K210端
STM32端
发送数据包
K210端
STM32端 K210的UART模块支持全双工通信#xff0c;可以同时进行数据的发送和接收。在K21…目录
K210-UART串口通信相关函数
使用K210串口的时候需要映射引脚
K210与STM32串口通信
发送单字节
K210端
STM32端
发送数据包
K210端
STM32端 K210的UART模块支持全双工通信可以同时进行数据的发送和接收。在K210上使用UART串口通信你可以连接外部设备如传感器、显示器、WiFi模块等实现数据的交换和控制。
K210-UART串口通信相关函数
1.machine.UART()该函数用于初始化一个UART串口对象。你可以指定串口的编号如UART1、波特率、数据位、校验位、停止位、TX引脚和RX引脚等参数。
import machine# 初始化串口
uart machine.UART(1, baudrate115200, tx12, rx13)
在这个示例中我们使用machine.UART()函数初始化了一个串口对象指定了串口的编号1、波特率115200、TX引脚12和RX引脚13。
或者可以
machine.UART(uart,baudrate,bits,parity,stop,timeout, read_buf_len) machine.UART()函数是用于初始化一个UART串口对象的函数它可以接受以下参数 uart串口编号可以为1、2、3。baudrate波特率用于指定串口通信的数据传输速率。bits数据位数可以为5、6、7、8。parity校验位可以为None、0、1、2。stop停止位可以为1、2。timeout超时时间单位为毫秒。read_buf_len读缓冲区长度用于指定串口读取数据时的缓冲区大小。 其中uart参数是必需的其他参数都有默认值。下面分别介绍这些参数的含义和用法 uart串口编号可以为1、2、3。如果你的开发板上有多个串口需要指定使用哪个串口进行通信。baudrate波特率用于指定串口通信的数据传输速率。常见的波特率有9600、115200等需要根据实际情况进行设置。bits数据位数可以为5、6、7、8。一般情况下使用8位数据位即可。parity校验位可以为None、0、1、2。校验位用于检查数据传输中是否出现错误一般情况下可以设置为None。stop停止位可以为1、2。停止位用于指定每个数据帧的结束位置一般情况下使用1个停止位即可。timeout超时时间单位为毫秒。当读取串口数据时如果在超时时间内没有读取到任何数据则会返回None。read_buf_len读缓冲区长度用于指定串口读取数据时的缓冲区大小。如果读取的数据量较大可以适当增大该值以避免数据丢失。 2.uart.write()该函数用于向串口发送数据。你可以发送字符串或者字节数据。
# 发送数据
uart.write(Hello, UART!)
3.uart.read()该函数用于从串口接收数据。它会阻塞程序直到接收到指定数量的数据或者超时
# 接收数据
data uart.read(10)
print(data) 这段代码从串口读取最多10个字节的数据并将其打印出来。 4.uart.any()该函数用于检查串口是否有未读取的数据。如果有返回值为True否则返回False。
# 检查是否有未读取的数据
if uart.any():data uart.read()print(data) 这段代码首先调用uart.any()函数检查串口是否有未读取的数据如果有则调用uart.read()函数将数据读取并打印出来。 5.uart.flush()该函数用于清空串口的缓冲区将所有未读取的数据丢弃 使用K210串口的时候需要映射引脚
# IO6→RX1IO7→TX1
fm.register(6, fm.fpioa.UART1_RX, forceTrue)
fm.register(7, fm.fpioa.UART1_TX, forceTrue)fm.register()函数是用于配置FPIOAFlexible Peripheral I/O Assignments的函数它可以将指定的引脚与相应的功能进行绑定。 K210与STM32串口通信
K210与STM32串口通信发送分为两种一种是发送单字节一种是发送数据包。因为发送的数据不一样从而K210的代码和STM32的代码都是不一样的。
本篇文章只涉及K210发送给STM32。
发送单字节
K210端
from machine import UART, Timer
from fpioa_manager import fm#映射串口引脚
fm.register(6, fm.fpioa.UART1_RX, forceTrue)
fm.register(7, fm.fpioa.UART1_TX, forceTrue)
while True:textuart.read() #读取数据if text: #如果读取到了数据uart.write(1)STM32端
void Usart3_Init(unsigned int baud)
{GPIO_InitTypeDef gpio_initstruct;USART_InitTypeDef usart_initstruct;NVIC_InitTypeDef nvic_initstruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);//PA2 TXDgpio_initstruct.GPIO_Mode GPIO_Mode_AF_PP;gpio_initstruct.GPIO_Pin GPIO_Pin_10;gpio_initstruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOB, gpio_initstruct);//PA3 RXDgpio_initstruct.GPIO_Mode GPIO_Mode_IN_FLOATING;gpio_initstruct.GPIO_Pin GPIO_Pin_11;gpio_initstruct.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOB, gpio_initstruct);usart_initstruct.USART_BaudRate baud;usart_initstruct.USART_HardwareFlowControl USART_HardwareFlowControl_None; usart_initstruct.USART_Mode USART_Mode_Rx | USART_Mode_Tx; usart_initstruct.USART_Parity USART_Parity_No; usart_initstruct.USART_StopBits USART_StopBits_1; usart_initstruct.USART_WordLength USART_WordLength_8b; USART_Init(USART3, usart_initstruct)USART_Cmd(USART3, ENABLE); USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); nvic_initstruct.NVIC_IRQChannel USART2_IRQn;nvic_initstruct.NVIC_IRQChannelCmd ENABLE;nvic_initstruct.NVIC_IRQChannelPreemptionPriority 0;nvic_initstruct.NVIC_IRQChannelSubPriority 1;NVIC_Init(nvic_initstruct);}
if(USART_ReceiveData(USART3)1)//K210
{numbert;
}发送数据包
K210端
def str_int(data_str):bb binascii.hexlify(data_str)bb str(bb)[2:-1]#print(bb)#print(type(bb))hex_1 int(bb[0])*16hex_2 int(bb[1],16)return hex_1hex_2def send_data(x,y,w,h,msg):start 0x24end 0x23length 5class_num 0x05 #例程编号class_group 0xBB #例程组data_num 0x00 #数据量fenge 0x2c #逗号crc 0 #校验位data [] #数据组#参数都为0if x0 and y0 and w0 and h 0:passelse:#x(小端模式)low x 0xFF #低位high x 8 0xFF #高位data.append(low)data.append(fenge) #增加,data.append(high)data.append(fenge) #增加,#y(小端模式)low y 0xFF #低位high y 8 0xFF #高位data.append(low)data.append(fenge) #增加,data.append(high)data.append(fenge) #增加,#w(小端模式)low w 0xFF #低位high w 8 0xFF #高位data.append(low)data.append(fenge) #增加,data.append(high)data.append(fenge) #增加,#h(小端模式)low h 0xFF #低位high h 8 0xFF #高位data.append(low)data.append(fenge) #增加,data.append(high)data.append(fenge) #增加,if msg !None:#msgfor i in range(len(msg)):hec str_int(msg[i])data.append(hec)data.append(fenge) #增加,#print(data)data_num len(data)length len(data)#print(length)send_merr [length,class_num,class_group,data_num]for i in range(data_num):send_merr.append(data[i])#print(send_merr)#不加上CRC位进行CRC运算for i in range(len(send_merr)):crc send_merr[i]crc crc%256send_merr.insert(0,start) #插入头部send_merr.append(crc)send_merr.append(end)#print(send_merr)global send_bufsend_buf send_merr 首先是 str_int 函数它的作用是将输入的字符串转换为整数。具体实现上它使用了 Python 的标准库中的 binascii.hexlify 方法将输入的字符串 data_str 转换为十六进制表示的字节串然后对于每一个字节分别将其高四位和低四位转换成十进制数并进行一定的运算最终返回一个整数。 接下来是 send_data 函数它的作用是组装一个特定格式的数据包。函数接受五个参数 x, y, w, h, msg其中 x, y, w, h 是四个整数msg 是一个字符串。根据这些参数函数构建了一个包含起始标识、长度、例程编号、例程组、数据量、数据内容以及校验位的数据包。 在函数内部首先定义了一些常量如起始标识、结束标识、长度、例程编号、例程组等。然后根据传入的参数判断是否需要加入 x, y, w, h 这四个整数。如果这四个整数全部为 0那么就不将它们加入数据包中否则将它们按照小端模式即低位在前、高位在后的顺序加入到数据中。接下来是对传入的字符串 msg 进行处理将其中每个字符转换为整数后加入数据中。 接着计算数据量和长度并将所有数据组装成一个列表 send_merr。最后计算校验位并将其加入到 send_merr 中同时在开头和结尾分别加上起始标识和结束标识最终得到一个完整的数据包。 STM32端
char buf_msg[100] {\0};
u8 new_flag 0;
u8 r_index 0;
u16 buf_crc 0;
u8 tou_flag 0;
u8 len_flag 0;
u8 buf_len 0;
char data[50];void recv_k210msg(uint8_t recv_msg)
{if (recv_msg $){new_flag 1;}if (recv_msg #){if (buf_len r_index){new_flag 0;tou_flag 0;len_flag 0;buf_crc - buf_msg[r_index - 1];buf_crc % 256;if (buf_crc buf_msg[r_index - 1]){deal_recvmsg();}else{r_index 0;buf_crc 0;}}}if (new_flag 1){if (recv_msg $ tou_flag 0){tou_flag 1;}else{buf_msg[r_index] recv_msg;buf_crc recv_msg;if (len_flag 0){buf_len buf_msg[0];len_flag 1;}}}
}void deal_recvmsg(void)
{u8 index, data_i 0;u8 eg_num buf_msg[1];u8 number buf_msg[3];u8 i_duo 0;if (r_index ! buf_len){buf_len 0;return;}for (index 0; index number; index){if (buf_msg[4 index] 0x2c i_duo 0){i_duo 1;continue;}data[data_i] buf_msg[4 index];i_duo 0;}buf_crc 0;r_index 0;memset(buf_msg, 0, sizeof(buf_msg));deal_data(eg_num);
}void deal_data(u8 egnum)
{u16 x, y, w, h;u8 msg[20] {\0};u8 icopy 0;u16 id 999;switch (egnum){case 1:case 5:case 6:x data[1] 8 | data[0];y data[3] 8 | data[2];w data[5] 8 | data[4];h data[7] 8 | data[6];break;case 2:case 3:x data[1] 8 | data[0];y data[3] 8 | data[2];w data[5] 8 | data[4];h data[7] 8 | data[6];while (*(data 8 icopy) ! \0){msg[icopy] *(data 8 icopy);icopy;}break;case 4:x data[1] 8 | data[0];y data[3] 8 | data[2];w data[5] 8 | data[4];h data[7] 8 | data[6];id data[8] 8 | data[9];while (*(data 10 icopy) ! \0){msg[icopy] *(data 10 icopy);icopy;}break;case 7:case 8:x data[1] 8 | data[0];y data[3] 8 | data[2];w data[5] 8 | data[4];h data[7] 8 | data[6];id data[8];break;case 9:x data[1] 8 | data[0];y data[3] 8 | data[2];w data[5] 8 | data[4];h data[7] 8 | data[6];while (*(data 8 icopy) ! \0){msg[icopy] *(data 8 icopy);icopy;}break;case 10:case 11:id data[0];break;}k210_msg.class_n egnum;k210_msg.x x;k210_msg.y y;k210_msg.w w;k210_msg.h h;k210_msg.id id;strcpy((char*)k210_msg.msg_msg, (char*)msg);memset(data, 0, sizeof(data));
}
void USART2_IRQHandler(void)
{uint8_t Rx2_Temp;if (USART_GetITStatus(USART2, USART_IT_RXNE) ! RESET){Rx2_Temp USART_ReceiveData(USART2);recv_k210msg(Rx2_Temp);}
}recv_k210msg 函数用于接收 K210 模块传来的消息并根据特定的起始符号 $ 和结束符号 # 进行消息解析。具体流程如下 当接收到 $ 符号时表示开始接收新的消息将 new_flag 置为 1。当接收到 # 符号时表示消息接收完毕进行消息处理。如果消息长度符合要求计算消息校验和并调用 deal_recvmsg 进行处理。在接收到其他字符时如果处于接收新消息状态将字符存入缓冲区 buf_msg 中并更新校验和 buf_crc。 deal_recvmsg 函数用于对接收到的消息进行处理主要是根据消息类型和内容进行解析并调用 deal_data 函数进行进一步处理。具体流程如下 根据消息中指定的格式提取数据并调用 deal_data 函数进行处理。处理完成后清空缓冲区 buf_msg 和相关标志位以便接收下一条消息。 deal_data 函数用于根据不同类型的消息对数据进行解析和处理。具体流程如下 根据消息的类型进行不同的数据解析操作提取出消息中的有用信息并赋值给 k210_msg 结构体。结构体 k210_msg 包含了消息的分类、位置信息、ID 信息以及消息内容。处理完成后清空数据缓冲区 data。 有读者看到这里可能会想问能不能用单字节的方式发送字符串STM32中USART_ReceiveData(USART3)1此处没法等于字符串。