管理员
  
- 积分
- 165394
- 金钱
- 165394
- 注册时间
- 2010-12-1
- 在线时间
- 2112 小时
|
有不少客户,不会配置STM32F103的串口3例程,不知道串口3如何配置。
其实,我们在开发板的扩展实验里面,已经有用到串口3了。如下所示:
上图中,这四个例程,都是用的串口3.
以蓝牙通串口模块例程为例,如下图所示:
都有串口3 的.c和.h了。
今天,我们在战舰开发板(精英板完全一样)标准例程的串口1基础上,稍作修改,将通信串口改为串口3:
先将USART3的文件夹,拷贝到标准例程串口实验的HARDWARE文件夹下:
然后打开串口实验工程,并添加HARDWARE\USART3文件夹下的usart3.c到工程HARDWARE分组下,然后
在头文件包含路径,添加USART3文件夹路径进来:
然后,根据实际串口1的代码,修改usart3.c,修改后,代码如下:
[mw_shl_code=c,true]#include "sys.h"
#include "usart3.h"
#include "stdarg.h"
#include "stdio.h"
#include "string.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32F103开发板
//串口3初始化代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2015/3/14
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//********************************************************************************
//修改说明
//无
//////////////////////////////////////////////////////////////////////////////////
//串口接收缓存区
u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN个字节.
u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; //发送缓冲,最大USART3_MAX_SEND_LEN字节
//接收状态
//接收到的数据状态
//接收状态
//bit15, 接收完成标志
//bit14, 接收到0x0d
//bit13~0, 接收到的有效字节数目
vu16 USART3_RX_STA=0;
void USART3_IRQHandler(void)
{
u8 res;
if(USART3->SR&(1<<5)) //接收到数据
{
res=USART3->DR;
if((USART3_RX_STA&0x8000)==0)//接收未完成
{
if(USART3_RX_STA&0x4000)//接收到了0x0d
{
if(res!=0x0a)USART3_RX_STA=0;//接收错误,重新开始
else USART3_RX_STA|=0x8000; //接收完成了
}else //还没收到0X0D
{
if(res==0x0d)USART3_RX_STA|=0x4000;
else
{
USART3_RX_BUF[USART3_RX_STA&0X3FFF]=res;
USART3_RX_STA++;
if(USART3_RX_STA>(USART3_MAX_RECV_LEN-1))USART3_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
//初始化IO 串口3
//pclk1 CLK1时钟频率(Mhz)
//bound:波特率
void usart3_init(u32 pclk1,u32 bound)
{
RCC->APB2ENR|=1<<3; //使能PORTB口时钟
GPIOB->CRH&=0XFFFF00FF; //IO状态设置
GPIOB->CRH|=0X00008B00; //IO状态设置
RCC->APB1ENR|=1<<18; //使能串口时钟
RCC->APB1RSTR|=1<<18; //复位串口3
RCC->APB1RSTR&=~(1<<18);//停止复位
//波特率设置
USART3->BRR=(pclk1*1000000)/(bound);// 波特率设置
USART3->CR1|=0X200C; //1位停止,无校验位.
//使能接收中断
USART3->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(0,1,USART3_IRQn,2);//组2
USART3_RX_STA=0; //清零
}
//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u3_printf(char* fmt,...)
{
u16 i,j;
va_list ap;
va_start(ap,fmt);
vsprintf((char*)USART3_TX_BUF,fmt,ap);
va_end(ap);
i=strlen((const char*)USART3_TX_BUF); //此次发送数据的长度
for(j=0;j<i;j++) //循环发送数据
{
while((USART3->SR&0X40)==0); //循环发送,直到发送完毕
USART3->DR=USART3_TX_BUF[j];
}
}
[/mw_shl_code]
最后,修改main.c里面的代码,如下:
[mw_shl_code=c,true]int main(void)
{
u16 t;
u16 len;
u16 times=0;
Stm32_Clock_Init(9); //系统时钟设置
uart_init(72,115200); //串口初始化为115200
usart3_init(36,9600); //串口3初始化为9600
delay_init(72); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
while(1)
{
if(USART3_RX_STA&0x8000)
{
len=USART3_RX_STA&0x3FFF;//得到此次接收到的数据长度
u3_printf("\r\n您发送的消息为:\r\n\r\n");
for(t=0;t<len;t++)
{
USART3->DR=USART3_RX_BUF[t];
while((USART3->SR&0X40)==0);//等待发送结束
}
u3_printf("\r\n\r\n");//插入换行
USART3_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
u3_printf("\r\n战舰/精英STM32开发板 串口3实验\r\n");
u3_printf("正点原子@ALIENTEK\r\n\r\n");
}
if(times%200==0)u3_printf("请输入数据,以回车键结束\r\n");
if(times%30==0)LED0=!LED0;//闪烁LED,提示系统正在运行.
delay_ms(10);
}
}
}
[/mw_shl_code]
这样,我们就实现了把串口实验(默认使用串口1),改到了串口3。
注意,这里我们使用串口3的波特率是9600,并不是115200,因为使用115200的时候,波特率设置误差有点大
有可能导致通信异常,见下图:
可以看到,同样设置115200,串口1就是115200,而串口3变成了115384。
这是因为串口3的时钟比串口1低了一半。所以建议使用串口3的时候,设置不同波特率时,先看误差有多大。
最后,下载这个代码测试(串口3,9600波特率),结果如下图:
至此,串口3的代码,就修改成功了,能发能收,没有任何问题。
最后附上本代码:
实验4 串口实验_串口3版本.rar
(118.68 KB, 下载次数: 565)
|
|