历史上的今天
今天是:2024年08月25日(星期日)
2021年08月25日 | STM32 485通信 自我学习总结 控制380V变频器去控制380V电机
2021-08-25 来源:eefocus
准备总结一下学习过程中的485通信知识!----------------------------------------------------
先描述一下学习STM32与485通信的时候想实现的功能--------
首先是完成双机通信中的双向通信----这里定义A为主机发送指令给从机B,从机B在接收到主机A的指令后,判断有效位的正确性,如果正确将这个指令通过RS232串口显示到串口助手里,观察整个指令是否接收正确-----同时在从机B接收到主机A指令后,向主机A发送指定数据----主机A在接收到从机B数据后判断有效位的正确性,如果正确则通过RS232打印到串口助手,然后观察完整数据。--------这里的判断比较简单------只是判断接收数据的最后一位是否是规定的字符----为了数据的准确性,可以增加判断方法。
第一步是配置RS232的串口,这里使用USART1,测试printf函数的输出是否正常----------这里就不叙述了!
注意在主机的USART1中要打开接收中断-- USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//打开接收终端
第二步是配置RS485,这里使用USART2,配置如下---------
void USART2_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
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(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//打开接收终端
USART_ClearFlag(USART2, USART_FLAG_TC);
}
void MyPrintfByte(unsigned char byte)//发送一个字节
{
USART_SendData(USART2, byte);
while( USART_GetFlagStatus(USART2,USART_FLAG_TC)!= SET);
}
void MyPrintfStr(unsigned char *s)//发送字符串
{
uint8_t i=0;
while(s[i]!='')
{
USART_SendData(USART2,s[i]);
while( USART_GetFlagStatus(USART2,USART_FLAG_TC)!= SET);
i++;
}
}
void MyPrintfArray(uint8_t send_array[],uint8_t num)//发送数组中指定个数
{
uint8_t i=0;
while(i USART_SendData(USART2,send_array[i]); while( USART_GetFlagStatus(USART2,USART_FLAG_TC)!= SET); i++; } } 第三部是在中断里写接收函数-------------- void USART1_IRQHandler(void)//232接收中断函数---主要是在主机中 { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收到数据 { USART_ClearITPendingBit(USART1, USART_IT_RXNE);//清标志位 RS232_RX_BUF[RS232_RX_CNT++]=USART_ReceiveData(USART1); if( RS232_RX_CNT==4) RS232_RX_CNT=0; } } void USART2_IRQHandler(void) //485中断接收函数 { if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)//接收到数据 { USART_ClearITPendingBit(USART2, USART_IT_RXNE);//清标志位 RS485_RX_BUF[RS485_RX_CNT++]=USART_ReceiveData(USART2); //将接收到的数据保存到指定数组 if( RS485_RX_CNT==9)//接收指定长度为9个数据 RS485_RX_CNT=0; } } 第四步是对中断的优先级进行配置---- static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = ENABLE; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = ENABLE; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } 第五部是主函数---------- ---------------------------主机---------------------------------- int main(void) { uint8_t i,flag=0; USART2_Config(); USART1_Config(); GPIO_Config(); NVIC_Configuration(); printf("485主机rn"); while(1) { GPIO_SetBits(GPIOB,GPIO_Pin_5);//发送模式 Delay(50000); //必要的延时 if(RS232_RX_BUF[3]=='1') //通过串口助手发送一组数据,根据不同数据下面向从机发送不同的指令 MyPrintfStr("12345678!"); else if(RS232_RX_BUF[3]=='2') MyPrintfStr("abcdefgh@"); else if(RS232_RX_BUF[3]=='3') MyPrintfStr("ABCDEFGH#"); RS485_RX_BUF[8]='-'; //将接收数据的最后一位设置为其它 Delay(50000); GPIO_ResetBits(GPIOB,GPIO_Pin_5);//接收模式 Delay(50000); //USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); flag=0; while(!(RS485_RX_BUF[8]=='T')&&flag<20)//等待接收到数据,并且最后一位数据位---T---或者超时退出循环---超时数值比较重要,太小会使数据丢失。 { Delay(0x666ee); flag++; } for(i=0;i<9;i++) //打印出接收到从机的数据 { if(i<8) printf("%c",RS485_RX_BUF[i]); else printf("%crn",RS485_RX_BUF[i]); } Delay(0x6666ee); } } ------------------------------------------从机-------------------------------------- int main(void) { uint8_t i; USART2_Config(); GPIO_Config(); USART1_Config(); NVIC_Configuration();
史海拾趣
|
随着应用的不断扩展,今天和未来的单片机普及和车辆网络正在继续。单片机是车辆内各种电子控制模块的“大脑”,而网络则是“系统互连”。本地互连网络(LIN)是业界第一个提出车内Class A开放多路复用协议标准。它定义了一个支持车辆内 ...… 查看全部问答> |
|
我现在用CC1100接收模块开发一个项目,用的单片机是MSP430F2274,但相应的电源板只能提供3mA的电流,我现在想用电磁波解决这个问题,想问哪个高手能给我些代码,非常感谢!… 查看全部问答> |
|
手里有一块28335的板子和一个前辈留下的仿真器,各个地方都找遍了就是找不到驱动程序,求各位大侠出手相助。 我的系统是WIN7 32位,已装好CCS3.3。用过的大侠能把驱动发我邮箱么..mashaokang1111@163.com。谢谢啊! [ 本帖最后由 mashaokang 于 20 ...… 查看全部问答> |
|
ufun群开始使用了 感谢朋友们的支持!现在项目资金总额达到了11803元。 令人格外高兴的是,有PCB制板公司的朋友愿意提供免费的PCB加工;焊接也有可能得到免费的支持;器件优惠还在联系…… 大家的支持使最终 ...… 查看全部问答> |




