赞
踩
目录
1.1导入需要的库
- from fpioa_manager import fm #用于映射IO口
- from machine import UART #用于串口配置
- from machine import Timer #用于产生定时器中断 用于读取是否接收到数据包
1.2串口初始化及定义发送的数据格式
- fm.register(17, fm.fpioa.UART1_TX, force=True)
- fm.register(21, fm.fpioa.UART1_RX, force=True)
-
- #8位数据位,无校验位,1位停止位 波特率115200 另外一个单片机的配置需要相同
- uart_A = UART(UART.UART1, 115200, 8, 0, 1, timeout=1000, read_buf_len=4096)
-
- class K210_transmit():
- head = 0xAA
- x = 256
- y = 312
- end = 0xAF
-
- K210 = K210_transmit()
-
- #单片机一般都是一个字节一个字节读取串口数据,所以我们要把数据一个字节一个字节的进行发送
- #我们通常使用K210都是发送坐标数据给其它单片机,但是坐标范围明显超过了一个字节大小(255),所以把
- #x,y坐标拆分成高8位和低8位发送,确保数据不会因为超出范围产生错误
-
- def K210_data():
- data=bytearray([K210.head,
- K210.x>>8,K210.x,
- K210.y>>8,K210.y,
- K210.end])
- return data

1.3发送数据包
uart_A.write(K210_data())
STM32单片机的串口初始化我这里就不过多介绍了,相信大家学到了K210单片机,STM32自然是没有问题的,我们只需要将其配置为115200,8位数据位,无校验位,1位停止位即可。
- void USART1_init(int botelv)
- {
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
-
-
- //发送引脚 PA9 TX
- GPIO_InitTypeDef GPIO_InitStructure;//定义GPIO结构体
- GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF_PP;//复用推挽输出 复用推挽输出可以输出高低电平 复用开漏不接上拉电阻只能输出低电平
- GPIO_InitStructure.GPIO_Pin= GPIO_Pin_9;//管脚1
- GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;//频率
- GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化
-
-
- //接收引脚 PA10 RX
- GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IPU;//上拉输入
- GPIO_InitStructure.GPIO_Pin= GPIO_Pin_10;//管脚1
- GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;//频率
- GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化
-
-
- USART_InitTypeDef USART_InitStructure;
- USART_InitStructure.USART_BaudRate=botelv;//波特率
- USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//不支持硬件流
- USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;//发送模式 和 接收模式
- USART_InitStructure.USART_Parity=USART_Parity_No;//没有奇偶校验
- USART_InitStructure.USART_StopBits=USART_StopBits_1;//1个停止位
- USART_InitStructure.USART_WordLength=USART_WordLength_8b;//一帧8位
- USART_Init(USART1,&USART_InitStructure);
-
-
- USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
-
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
- NVIC_Init(&NVIC_InitStructure);
-
-
- USART_Cmd(USART1,ENABLE);//使能USART串口
-
- }
-
- void USART1_SendByte(uint8_t Data)//发送一个字节
- {
- while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);//等待TDR空
- USART_SendData(USART1,Data);//发送一个字节
- }

通过上面这些配置,可以通过void USART1_SendByte(uint8_t Data)函数发送一个字节,所以发送一个HEX数据包就非常简单了!
- USART1_SendByte(0xAA);//发送包头
- USART1_SendByte(Data);//发送数据
- USART1_SendByte(0xAF);//发送包尾
首先就是对串口的配置,如上面的配置一样,可知我们已经开启了串口的接收中断,所以我们在串口接收中断函数中判断数据包是否符合要求即可。这里我们只接收4个字节
- uint8_t Rx_DataPack[8]={0,0,0,0};
- uint8_t Tx_DataPack[4]={0,0,0,0};
- uint8_t Rx_flag=0;
-
- void USART1_IRQHandler(void)
- {
- static uint8_t Rx_StateFlag=0;
- static uint8_t Rx_Datapx=0;
- if(USART_GetFlagStatus(USART1,USART_IT_RXNE)==SET)
- {
- uint8_t RxData = USART_ReceiveData(USART1);
- if(Rx_StateFlag==0)
- {
- if(RxData==0xAA)//包头
- {
- Rx_Datapx=0;//数组指针清零
- Rx_StateFlag=1;//接收标志位置一开始接收有用数据
- }
- }
- else if(Rx_StateFlag==1)
- {
- Rx_DataPack[Rx_Datapx]=RxData;
- Rx_Datapx++;
-
- if(Rx_Datapx >= 8)//接收到个指定个数的数据
- {
- Rx_StateFlag=2;//接收标志位置2判断下一个数据是不是包尾
- }
- }
- else if(Rx_StateFlag==2)
- {
- if(RxData==0xAF)
- {
- Rx_StateFlag=0;//是包尾结束
- Rx_flag=1;
- }
- }
- USART_ClearITPendingBit(USART1, USART_IT_RXNE);
- }
- }

- Rx_StateFlag=0 #接收数据包状态标准位
- Rx_index=0 #接收数据数组索引下标
- Rdata_array=bytearray([0,0,0,0])#接收数据数组
- Rx_OK_flag=0 #接收完成标志位 0没有接收成功 1接收成功
-
-
- def fun(void):
- global Rx_StateFlag
- global Rx_index
- global Rdata_array
- global Rx_OK_flag
- R_data = uart_A.readchar()
- if R_data>0:
- if Rx_StateFlag==0:
- if R_data==170: #0xAA
- Rx_StateFlag=1
- Rx_index=0
- elif Rx_StateFlag==1:
- Rdata_array[Rx_index]=R_data
- Rx_index=Rx_index+1
- if Rx_index>=4:
- Rx_StateFlag=2
- elif Rx_StateFlag==2:
- if R_data==175:
- Rx_StateFlag=0
- Rx_OK_flag=1
- else :
- Rx_StateFlag=0
- Rx_OK_flag=0
- #初始化定时器0,周期5ms
- tim=Timer(Timer.TIMER0,Timer.CHANNEL0,mode=Timer.MODE_PERIODIC,period=1,unit=Timer.UNIT_MS,callback=fun)

这里使用软件定时器的回调函数模拟串口接收中断函数,具体判断数据包是否符合要求的方法与STM32单片机类似。
总结:不难,多用CH340转接口连接到电脑上打开串口助手调试,控制变量法先确保数据是按正常格式发送出去了,再去调试接收函数,不要接收和发送一起调试!!!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。