新手入门
- 积分
- 7
- 金钱
- 7
- 注册时间
- 2020-11-15
- 在线时间
- 4 小时
|
1金钱
本帖最后由 支持向量鸡 于 2021-1-20 12:52 编辑
现状:
1.板子上的芯片是stm32f103zet6
2.板子上只有rs485的串口
3.但是另一个设备是rs232
已经能实现:1.板子通过rs485的串口,对rs485的设备接收、发送设计,说明设备本身硬件没问题
2.板子通过rs485的串口,对rs232的设备发送数据
未能实现:
1.板子通过rs485的串口,接收s232的设备的数据。
请问用代码怎么实现rs485转rs232呢?
目前的代码如下:
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "oled.h"
#include "bmp.h"
#include "rs485.h"
int main(void)
{
u8 i;
u8 t;
u8 lenOfRs485rec;
//最大长度为8,防止超过8字符后显示乱码
u8 rs485rec[8];
u8 rs485sen[9]={'a','b','c','d','e','f','g','h'};
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
OLED_Init(); //初始化OLED
OLED_Clear() ;
LED_Init();
RS485_Init(9600); //初始化RS485
t=0;
OLED_Clear();
while(1)
{
RS485_Send_Data(rs485sen,8);//发送9个字节
delay_ms(250);
//屏幕第1行
OLED_ShowString(1,0,"Times:",16);
t++;
if(t>100)t=0;
OLED_ShowNum(48,0,t,3,16);//显示t的值
//屏幕第2行
OLED_ShowString(1,2,"send:",16);
for(i=0;i<8;i++)OLED_ShowChar(48+i*8,2,rs485sen[0+i],16); //显示发送的数据
//屏幕第3行
//通过串口1中断接收数据,储存到rs485buf,长度为lengthOfRs485rec
OLED_ShowString(1,4,"rec:",16);
RS485_Receive_Data(rs485rec,&lenOfRs485rec);
if(lenOfRs485rec)//接收到有数据
{
if(lenOfRs485rec>8)lenOfRs485rec=8;//最大是8个数据.
for(i=0;i<lenOfRs485rec;i++)OLED_ShowChar(40+i*8,4,rs485rec[0+i],16); //显示接收的数据
}
//屏幕第4行,暂时无内容
delay_ms(250);
}
}
//==============================手动分割线,rs485.c中的代码如下========================================
//#include "oled.h"
//#include "led.h"
#include "sys.h"
#include "rs485.h"
#include "delay.h"
#ifdef EN_USART1_RX //如果使能了接收
//接收缓存区
u8 RS485_RX_BUF[64]; //接收缓冲,最大64个字节.
//接收到的数据长度
u8 RS485_RX_CNT=0;
void USART1_IRQHandler(void)
{
u8 res;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //USART1接收中断,接收到数据
{
//OLED_ShowString(1,6,"NVIC",16); //用于测试是否中断,rs485成功,rs232失败?
//LED0=0;
res =USART_ReceiveData(USART1); //读取接收到的数据
if(RS485_RX_CNT<64)
{
RS485_RX_BUF[RS485_RX_CNT]=res; //记录接收到的值
RS485_RX_CNT++; //接收数据增加1
}
}
}
#endif
//初始化IO 本项目使用串口1
//pclk1 : PCLK1时钟频率(Mhz)
//bound:波特率
//RS485_TXD PA9 RS485_RXD PA10 RS485_CS PA0
void RS485_Init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
SystemInit(); //rs232中的语句
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //使能USART2,PA0是USART2?
//rs232必须有复用?
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//RS485_CS的IO口初始化 PA0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0端口配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//RS485_TXD的IO口初始化 PA9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽
GPIO_Init(GPIOA, &GPIO_InitStructure);
//RS485_RXD的IO口初始化 PA10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1,ENABLE);//复位串口1
RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1,DISABLE);//停止复位
#ifdef EN_USART1_RX //如果使能了接收
USART_InitStructure.USART_BaudRate = bound;//波特率设置
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据长度
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(USART1, &USART_InitStructure); ; //初始化串口1
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //使能串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级2级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级2级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启接收中断
USART_Cmd(USART1, ENABLE); //使能串口1
#endif
RS485_TX_EN=0; //默认为接收模式
}
//RS485发送len个字节.
//buf:发送区首地址
//len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节)
void RS485_Send_Data(u8 *buf,u8 len)
{
u8 t;
RS485_TX_EN=1; //设置为发送模式
for(t=0;t<len;t++) //循环发送数据
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
USART_SendData(USART1,buf[t]);
}
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
RS485_RX_CNT=0;
RS485_TX_EN=0; //设置为接收模式
}
//RS485查询接收到的数据
//buf:接收缓存首地址
//len:读到的数据长度
void RS485_Receive_Data(u8 *buf,u8 *len)
{
u8 rxlen=RS485_RX_CNT;
u8 i=0;
*len=0; //默认为0
delay_ms(10); //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
{
for(i=0;i<rxlen;i++)
{
buf=RS485_RX_BUF;
}
*len=RS485_RX_CNT; //记录本次数据长度
RS485_RX_CNT=0; //清零
}
}
在中断部分有LED和OLED的两行注释,是因为我怀疑rs232的信号没能让板子进入串口中断,确实测试时OLED和LED都没有信号,所以因为rs232无法中断,结果板子收不到信号?但rs485就可以,不懂为什么?
|
|