完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
2个回答
|
|
辅助理解:数据结构(C语言版)
头文件数据定义 typedef enum { USART_QUEUE_EMPTY = 0, USART_QUEUE_FULL = 1, USART_QUEUE_OK = 2, } usart_queue_status_t; #define USART_QUEUE_SIZE 256 typedef struct { u16 front; u16 rear; u16 size; u8 data[USART_QUEUE_SIZE]; } usart_queue_t; extern usart_queue_t usart1_send; void UsartQueueInit(usart_queue_t *q); uint8_t UsartQueuePop(usart_queue_t *q, uint8_t *data); uint8_t UsartQueuePush(usart_queue_t *q, uint8_t data); .c文件 #include "sys.h" #include "usart.h" usart_queue_t usart1_send; #if 1 #pragma import(__use_no_semihosting) //解决HAL库使用时,某些情况可能报错的bug int _ttywrch(int ch) { ch=ch; return ch; } //标准库需要的支持函数 struct __FILE { int handle; /* Whatever you require here. If the only file you are using is */ /* standard output using printf() for debugging, no file handling */ /* is required. */ }; /* FILE is typedef’ d in stdio.h. */ FILE __stdout; //定义_sys_exit()以避免使用半主机模式 void _sys_exit(int x) { x = x; } //重定义fputc函数 int fputc(int ch, FILE *f) { while((USART1->ISR&0X40)==0);//循环发送,直到发送完毕 USART1->TDR = (u8) ch; return ch; } #endif //end //串口缓冲队列初始化 void UsartQueueInit(usart_queue_t *q) { q->size = 0; q->front = 0; q->rear = 0; } //入队 uint8_t UsartQueuePush(usart_queue_t *q, uint8_t data) { if (((q->rear % USART_QUEUE_SIZE) == q->front) && ((q->size == USART_QUEUE_SIZE))) { //printf("--------------USART_QUEUE_FULL------------------"); return USART_QUEUE_FULL; } q->data[q->rear] = data; q->rear = (q->rear + 1) % USART_QUEUE_SIZE; q->size++; return USART_QUEUE_OK; } //出队 uint8_t UsartQueuePop(usart_queue_t *q, uint8_t *data) { if ((q->front == q->rear) && (q->size == 0)) { //printf("--------------USART_QUEUE_EMPTY-------------------"); return USART_QUEUE_EMPTY; } *data = q->data[q->front]; q->front = (q->front + 1) % USART_QUEUE_SIZE; q->size--; return USART_QUEUE_OK; } void USART1_IRQHandler(void) { u8 res; if(USART1->ISR&(1<<5))//接收到数据 { res=USART1->RDR; UsartQueuePush(&usart1_send, res); } USART1->ICR |=0x0008; } //初始化IO 串口1 上位机 //pclk2:PCLK2时钟频率(Mhz) //bound:波特率 void USART1_Init(u32 pclk2,u32 bound) { u32 temp; temp=(pclk2*1000000+bound/2)/bound; //得到USARTDIV@OVER8=0,采用四舍五入计算 RCC->AHB1ENR|=1<<1; //使能PORTB口时钟 RCC->APB2ENR|=1<<4; //使能串口1时钟 GPIO_Set(GPIOB,PIN14|PIN15,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//PB14,PB15,复用功能,上拉输出 GPIO_AF_Set(GPIOB,14,4); //PB14,AF4 GPIO_AF_Set(GPIOB,15,4);//PB15,AF4 //波特率设置 USART1->BRR=temp; //波特率设置@OVER8=0 USART1->CR1=0; //清零CR1寄存器 USART1->CR1|=0<<28; //设置M1=0 USART1->CR1|=0<<12; //设置M0=0&M1=0,选择8位字长 USART1->CR1|=0<<15; //设置OVER8=0,16倍过采样 USART1->CR1|=1<<3; //串口发送使能 //使能接收中断 USART1->CR1|=1<<2; //串口接收使能 USART1->CR1|=1<<5; //接收缓冲区非空中断使能 MY_NVIC_Init(0,2,USART1_IRQn,2);//组2,最低优先级 USART1->CR1|=1<<0; //串口使能 } |
|
|
|
使用时,解析一个丢一个数据,通讯协议定义最短接收指令个数为9,所以当接收一个完成指令在进行解析,接收数据格式CC 33 length order data1 ...... datan check1 check2
void UsartQueueDataProcess(void) { if(usart1_send.size > 9) { int i = 0; UsartCheckInform check_inform; if (UsartQueuePop(&usart1_send, &check_inform.Head1) == USART_QUEUE_OK) { //printf("-----------------head1--------------------------"); if (check_inform.Head1 == 0xcc) // head1; { check_inform.data[0] = 0xcc; //printf("-----------------head1--------------------------"); if (UsartQueuePop(&usart1_send, &check_inform.Head2) == USART_QUEUE_OK) { if (check_inform.Head2 == 0x33) // head2 { check_inform.data[1] = 0x33; //printf("-----------------head2--------------------------"); if (UsartQueuePop(&usart1_send, &check_inform.Lenghth) == USART_QUEUE_OK) { check_inform.data[2] = check_inform.Lenghth; // printf("-----------------Lenghth--------------------------"); for (i = 0; i < check_inform.Lenghth; i++) { UsartQueuePop(&usart1_send, &check_inform.data[i + 3]); } if (Check_Sum(check_inform.data, check_inform.Lenghth + 3) == 1) //校验正确 { // switch (check_inform.data[3]) { case 0x01:// 运动控制指令 if(state_yksp!=1) { if (check_inform.data[8] == 1) { speedlinedata = (int16_t)(((uint16_t)check_inform.data[5] << 8) + (uint16_t)check_inform.data[4]); speedangledata = (int16_t)(((uint16_t)check_inform.data[7] << 8) + (uint16_t)check_inform.data[6]); state_pcsp=1; carsport_state=0; speed11=const_speed*(speedlinedata-wheel_interval/2*speedangledata/1000); speed22=const_speed*(speedlinedata-wheel_interval/2*speedangledata/1000); speed33=-const_speed*(speedlinedata+wheel_interval/2*speedangledata/1000); speed44=-const_speed*(speedlinedata+wheel_interval/2*speedangledata/1000); } else { speed11=0; speed22=0; speed33=0; speed44=0; } Motor_Velocity(Motor1_Drive_ID,(uint32_t)(speed11)); Motor_Velocity(Motor2_Drive_ID,(uint32_t)(speed22)); delay_us(1000); Motor_Velocity(Motor3_Drive_ID,(uint32_t)(speed33)); Motor_Velocity(Motor4_Drive_ID,(uint32_t)(speed44)); } break ; case 0x11: // 信号处理单元 融入数据查询 即融合信息上传频率设定 DataFrequency = check_inform.data[4]; //信息频率上传确定 0为单次 break; case 0x12:// 里程计清零指令 X = 0; Y = 0; Yaw_Angle = 0; break; case 0x81: // 当前发送机状态为0 且第一次解析发送机指令 if ((check_inform.data[4] == 0x01) && (enginestartstopflag == 0x00)) { //printf("-----------------ENGING---START------------------------"); emginestarstopstate = 0X0E; timedurcnt=0; } if ((check_inform.data[4] == 0x02) && (enginestartstopflag == 0x01)) { //printf("-----------------ENGING---STOP------------------------"); emginestarstopstate=0X10; timedurcnt=0; } break; case 0x82: // 底盘升降 switch (check_inform.data[4]) { case 0x01: // 当前不在01 挡位则进行解析 if (UnderPlantFour != 0x01) { UnderPlantUpdownConState = 0xFF; UpdownTimeflag = 0x01; } break; case 0x02: if (UnderPlantFour != 0x02) { UnderPlantUpdownConState = 0xFF; UpdownTimeflag = 0x02; } break; case 0x03: if (UnderPlantFour != 0x03) { UnderPlantUpdownConState = 0xFF; UpdownTimeflag = 0x03; } break; case 0x04: if (UnderPlantFour != 0x04) { UnderPlantUpdownConState = 0xFF; UpdownTimeflag = 0x04; } break; } break; case 0x90: // 目前只有设置油量选项 根据协议其余信息自动上传 switch (check_inform.data[4]) { // 设置油量 case 0x03: oil = check_inform.data[5]; break; } break; case 0x92: // 电机复位请求标志 Motor_ErrorReset_Request(Motor1_Drive_ID); Motor_ErrorReset_Request(Motor2_Drive_ID); Motor_ErrorReset_Request(Motor3_Drive_ID); Motor_ErrorReset_Request(Motor4_Drive_ID); MOTOR_init(); break; default : break; } } } } } } } } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1649 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1566 浏览 1 评论
994 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
694 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1613 浏览 2 评论
1874浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
660浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
528浏览 3评论
544浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
517浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-28 15:14 , Processed in 0.951195 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号