上篇在第一部分介绍了GD32F190如何采集外部传感器的值,今天介绍RS485通讯部分。 第二部分 RS485通讯 对于RS485通讯部分,直接将STM32已经通讯成功大代码移植过来,只需要更改部分代码即可。 1.修改端口初始化代码 void Uart1Config(void) //初始化UART1 { GPIO_InitPara GPIO_InitStructure; USART_InitPara USART_InitStructure; //定义结构体 /* Enable GPIO clock */ RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_GPIOA, ENABLE); //使能GPIO时钟 RCC_APB1PeriphClock_Enable(RCC_APB2PERIPH_USART1, ENABLE);//使能USART1时钟 /* Connect PXx to USARTx_Tx */ GPIO_PinAFConfig(GPIOA, GPIO_PINSOURCE9, GPIO_AF_1); /* Connect PXx to USARTx_Rx */ GPIO_PinAFConfig(GPIOA, GPIO_PINSOURCE10, GPIO_AF_1); /* Configure USART Tx as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_PIN_9 | GPIO_PIN_10; GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF; GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_10MHZ; GPIO_InitStructure.GPIO_OType = GPIO_OTYPE_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PUPD_PULLUP; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_DeInit( USART1 ); //使能时钟 USART_InitStructure.USART_BRR = 9600; //波特率9600 USART_InitStructure.USART_WL = USART_WL_8B; //数据位8位 USART_InitStructure.USART_STBits = USART_STBITS_1; //1位停止位 USART_InitStructure.USART_Parity = USART_PARITY_RESET; USART_InitStructure.USART_HardwareFlowControl = USART_HARDWAREFLOWCONTROL_NONE; USART_InitStructure.USART_RxorTx = USART_RXORTX_RX | USART_RXORTX_TX;
USART_Enable(USART1, ENABLE); } 一定要将IO口定义为复用模式。其他基本都是一样的。
2.修改中断函数 在gd32f1x0_it.c函数中没有串口USART1函数的中断,需要自己增加,但是函数名一定要正确: void USART1_IRQHandler(void) { if( USART_GetIntBitState(USART1, USART_INT_RBNE) != RESET) //接收中断 { RxBuffer[ RxCounter++ ] = ( uint8_t )USART_DataReceive( USART1 ); if( RxCounter >= Size ) { USART_INT_Set( USART1 , USART_INT_RBNE , DISABLE ); } } if( USART_GetIntBitState( USART2, USART_INT_TBE ) != RESET ) //发送中断 { USART_DataSend( USART1 , TxBuffer[ TxCounter ++ ] ); if( TxCounter >= Size ) { USART_INT_Set(USART1, USART_INT_TBE, DISABLE); } } }
3.主函数修改 在主函数中1S中发送一次向主控板发送一次数据: int main(void) { u8 error=0,checksum; volatile u8 T_Display=0,H_Display=0; u16 T_Value=0,H_Value=0; SysTick_Configuration(); //初始化时钟 EvbUart2Config(); //初始化UART GD_EVAL_LEDInit(LED1); //初始化LED SHT1x_Init(); //初始化SHT10 Uart1Config(); EVB_PRINTF("欢迎使用GD32分布监控室内空气质量测试系统\r\n"); EVB_PRINTF("***** SHT10 实验 *****\r\n"); USART_INT_Set( USART1, USART_INT_RBNE, ENABLE ); //使能接收中断 USART_INT_Set( USART1, USART_INT_TBE, ENABLE ); //使能发送中断 while(1) { GD_EVAL_LEDOn(LED1); //点亮LED灯,开始读取温湿度 delay_s(1); //------------------------读取SHT1X传感器数据-------------------------------------- error+=SHT1x_Measure( &T_Value,&checksum,0); //measure temperature error+=SHT1x_Measure( &H_Value,&checksum,1); //measure humidity if(error!=0)SHT1x_Reset(); //通讯故障,复位传感器 else { sht1x.T_Result = T_Value; sht1x.H_Result = H_Value; SHT1X_Caculation1((float*)&sht1x.T_Result, (float*)&sht1x.H_Result ); sht1x.Temperature=sht1x.T_Result; sht1x.Humidity=(u16)sht1x.H_Result; sht1x.DEW=SHT1X_dewpoint1(sht1x.T_Result, sht1x.H_Result); delay_ms(20); }
if(sht1x.Temperature<0) { T_data[7]=0x2d; //在温度前加符号“-” sht1x.Temperature=-sht1x.Temperature; } else T_data[7]=0x20; //若温度大于0,显示为空 T_data[8]=(sht1x.Temperature/1000) + 0x30; T_data[9]=(sht1x.Temperature%1000/100) + 0x30; T_data[11]=(sht1x.Temperature%1000%100/10) + 0x30; T_data[12]=(sht1x.Temperature%1000%100%10) + 0x30; T_data[25]=(sht1x.Humidity/1000) + 0x30; T_data[26]=(sht1x.Humidity%1000/100) + 0x30; T_data[28]=(sht1x.Humidity%1000%100/10) + 0x30; T_data[29]=(sht1x.Humidity%1000%100%10) + 0x30; T_data[41]=(sht1x.DEW/1000) + 0x30; T_data[42]=(sht1x.DEW%1000/100) + 0x30; T_data[44]=(sht1x.DEW%1000%100/10) + 0x30; T_data[45]=(sht1x.DEW%1000%100%10) + 0x30; EVB_PRINTF((const char*)ST); EVB_PRINTF((const char*)T_data); //发送数据到串口 GD_EVAL_LEDOff(LED1); //关闭LED灯 delay_s(1);
if(k==1)RS485_Send_Data(T_data,45); //1s中后将数据发给主控板 delay_s(2); } }
4.实验结果
两块板子之间的通讯协议主要是MODBUS协议,自己根据需求自定义即可。
结论与心得: 通过GD32F190方案的学习与摸索,个人觉得GD32F190在国产领域中做的一件相当不错,有很多人性化的设计。特别是代码移植方面,比较方便。但是在芯片资料方面还是需要多多努力,因为资料太少,写的东西也比较笼统,不够详细。希望GD32的设计团队继续加油,为国产芯片做出更大贡献。
|