STM32F103RCT6的串口1与串口2的数据转发(求教)

yelvlab 2017-07-04 09:34:05
我现在因为一些事情需要使用单片机来编程,以前了解过一点51,简单用过arduino,对编程的精髓不了解,现在必须使用32了,完全懵了。
我现在需要使用32的USART1接电脑,USART2连接一个SIM卡模块,(硬件已经连接好了,并且是在一块板子上USART2没有接出来,无法确定状态。)我需要写一段代码来完成 这中间AT指令的转发。从USART1接收到的数据转发给USART2,同时等待USART2返回数据,然后再通过USART1发送给电脑,就相当于32做了一个中继。
我现在毫无头绪,有人来指点下 这个程序的 编程思路应该怎么样的,例如使不使用中断,或者在主函数内顺序执行。
...全文
2258 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
ApiaoZhou 2020-12-29
  • 打赏
  • 举报
回复
小白学习一下
day_day97 2018-08-11
  • 打赏
  • 举报
回复
引用 17 楼 jiqiang01234 的回复:
[quote=引用 16 楼 qq_34917736 的回复:]
温馨提示一下,单片机发送AT指令有一个特别的地方,就是结尾必须是0A 0A 0D,也就是必须发送"\r\n",只是"\n"的话是无效的

不准确,确切地说,结尾必须是0x0A,即'\r'
参见《SIM800 Series_AT Command Manual_V1.09》
1.4 AT Command syntax
The "AT" or "at" or “aT” or “At”prefix must be set at the beginning of each Command line. To terminate a Command line enter <CR>.[/quote]
嗯,当时一下子把0D和0A记混了,却是是0A结尾,但我强调的不是这点,是必须要有两个0D再加0A才能被ESP8266识别,否则返回error
jiqiang01234 2018-08-10
  • 打赏
  • 举报
回复
引用 16 楼 qq_34917736 的回复:
温馨提示一下,单片机发送AT指令有一个特别的地方,就是结尾必须是0A 0A 0D,也就是必须发送"\r\n",只是"\n"的话是无效的

不准确,确切地说,结尾必须是0x0A,即'\r'
参见《SIM800 Series_AT Command Manual_V1.09》
1.4 AT Command syntax
The "AT" or "at" or “aT” or “At”prefix must be set at the beginning of each Command line. To terminate a Command line enter <CR>.
day_day97 2018-08-04
  • 打赏
  • 举报
回复
温馨提示一下,单片机发送AT指令有一个特别的地方,就是结尾必须是0A 0A 0D,也就是必须发送"\r\n",只是"\n"的话是无效的
day_day97 2018-08-04
  • 打赏
  • 举报
回复
1、开启第二个串口的接收中断,判断接收完成之后发送
2、开启第二串口的接收中断,设置标志位;在主循环里面不断访问这个标志位,当标志位显示完成之后,开始发送
主循环函数:
void uart2_tips(void)
{
if(USART2_RX_STA&0x8000)
{
len=USART2_RX_STA&0x3fff; //得到此次接收到的数据长度
printf("\r\n您发送的USART2消息为:\r\n\r\n");
for(t=0;t<len;t++)
{
USART_SendData(USART1, USART2_RX_BUF[t]);//向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
command_operate(USART2_RX_BUF,USART2_RX_STA);
printf("\r\n\r\n");//插入换行
USART2_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
printf("\r\nSTM32 USART2\r\n");
}
delay_ms(10);
}
}

串口二中断处理函数(仿照正点原子的例程):
void USART2_IRQHandler(void)                	//串口1中断服务程序
{
u8 Res;
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntEnter();
#endif
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(USART2); //读取接收到的数据

if((USART2_RX_STA&0x8000)==0)//接收未完成
{
if(USART2_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x24)USART2_RX_STA=0;//接收错误,重新开始
else USART2_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x24)
USART2_RX_STA|=0x4000;
else
{
USART2_RX_BUF[USART2_RX_STA&0X3FFF]=Res ;
USART2_RX_STA++;
if(USART2_RX_STA>(USART_REC_LEN-1))USART2_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
#if SYSTEM_SUPPORT_OS //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
OSIntExit();
#endif
}

串口2设置:
void uart2_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);

//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10

//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器

//USART 初始化设置

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(USART2, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART2, ENABLE); //使能串口1
}
Votangroom 2018-07-28
  • 打赏
  • 举报
回复
先用串口助手这些工具调通每一个串口,电脑的串口助手自不必说,stm32的两个串口的收发都调通,然后是sim卡,我不知道你这个sim卡的串口有没有回复信息;sim卡也是有回应的是不是,用串口助手简单调试一下看看能不能正常工作就可以了。然后你再考虑整体怎么做 #3#6已经给出方法了
wgx1344115787 2018-07-28
  • 打赏
  • 举报
回复
重定向可以吧
Dirk 2017-08-16
  • 打赏
  • 举报
回复
单片机串口,一般都是采用主动发送,中断接受! 你这里面,两个串口接受中断,接收到数据后,单片机转发。当然,还可以考虑DMA,不过我没有试过可以还是不可以。如果可以,你配置好通道,然后就可以什么都不用做了!
zhu08dgut 2017-08-15
  • 打赏
  • 举报
回复
先把各自串口的收发做成功,然后转发就简单多了,网上很
wf__struggle 2017-08-15
  • 打赏
  • 举报
回复
我做过一个模块是,跟你的差不多,uart口1 就收到的原样发给uart2 ,uart2接DTU的模块(插入SIM卡可以上公网的那种) uart2的自动的去做初始化 和链接基站的(包括重连)的动作 ,然后检测到uart1有数据过来就将包转成AT指令的通过DTU模块转出去,uart2 接收的数据在将AT部分解掉再转给uart1,整个设备的参数包括IP地址,端口之类的通过uart1设置。(整个模块的功能实际上就是串口转网络的功能,项目上要用 网上买一个这个玩意要500块左右,所以就自己做了)
of123 2017-08-10
  • 打赏
  • 举报
回复
6 楼正解。
tianxj001 2017-08-10
  • 打赏
  • 举报
回复
采用接受中断简单一些,usart1接受中断程序直接启动USART2发送,把接受到的字节转发就成 同样,USART2接受中断,启动USART1的发送,直接转发。
yelvlab 2017-07-05
  • 打赏
  • 举报
回复
串口1的初始化 中断等等已经测试没问题,但是串口2 没外接,并且,我现在是卡在了 怎么让两个串口交换数据
八马难追 2017-07-05
  • 打赏
  • 举报
回复
接收的数据保存在数组里,调用发送函数不就行了。在串口1的接收中断里,调用串口2的发送函数,在串口2的接收中断里,调用串口1的发送函数。
zhxianbin 2017-07-04
  • 打赏
  • 举报
回复
stm32 的串口代码网上很多,找一个参考下,分别把每个串口的收发调试好就简单了
yelvlab 2017-07-04
  • 打赏
  • 举报
回复
我也是这么想的,但是 每成功啊
worldy 2017-07-04
  • 打赏
  • 举报
回复
很简单,UART1给接口接收到的数据,原样传递给UART2,UART2接收的数据原样转发UART1

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧