实验一:
工程。
链接:https://pan.baidu.com/s/1g8DV4yZWOix0BbcZ08LYDQ?pwd=2176
提取码:2176
串口1的使用。发送功能。
单片机发送信息到电脑。
通过串口进行通信。
首先单片机这边。
单片机这边,需要对单片机的串口模块进行使能初始化,设置串口的格式。
单片机和电脑的串口收发格式要配置一致。不然A和B肯定通信不成功,鸡和鸭讲,对牛弹琴。
打开串口助手,看下格式。
格式包括波特率,停止位,数据位和校验位。电脑端的串口助手(我们这里使用XCOM的串口助手)默认这个配置,单片机也这么配置一下。
看到上述的串口初始化的步骤主要是
1、初始化端口的时钟,串口1的时钟,都要打开,因为我们需要用到芯片的该个功能,因此必须打开对应时钟。
2、由于端口PA9和PA10默认是IO模式,这个我们配置为端口复用模式,切换到串口1功能;
3、串口1的具体格式的初始化。设置通信格式,和要通话端的格式一致。
4、使能串口,清空串口对应的中断标记位。允许发生中断。
5、在其他地方或者这个函数里面,我们可以设置串口1的中断优先级等,配置一下。这里在前面配置了。
初始化函数用PA9和PA10作为串口使用。
可以用stm32CubeMX软件查看。
如何对stm32查看IO功能。-CSDN博客
看到PA9和PA10分别是串口1的TXD发送和RXD接收引脚。
这里我们需要用到一个USB-TTL模块,我们可以自学习一下232电平,TTL电平等。记得发送和接收对接。才能正常收发数据。
这里我们只是对发送功能进行讲解,因此接收的中断先不讲解。
使用这个的时候,先在工程中确认包括usart.c文件。然后用里面的额初始化函数进行初始化。注意波特率。
然后再main.c中的main函数里面,进行include头文件,然后进行串口初始化。
这里讲解一下printf函数。printf函数,我们一般在一开始学习C语言的时候,就讲解了。那时候我们是将printf函数输出到电脑的屏幕中,查看一下信息,比如变量,字符串啊等等信息。这里我们用printf函数,也是实现这个功能。
不过单片机里面执行printf函数,需要多一个重定向的步骤。告诉单片机,我们需要在单片机的那个串口printf出去,要重定向到对应的单片机串口才行。
所以在usart.c文件里面。看到这个函数里面有串口1,因为我们的PA9和PA10就是串口1,定向到这个,我们的串口才能输出信息打印出去。
你可以配置串口3,然后这里改为串口3,那么printf就定向到串口3去了,同理也一样。
我们可以修改一下这个函数,改为大写的Printf函数,或者多一个函数的形参,后面我们再讲解。
在库中的stm32f4xx_usart.c中,包括了一个发送字节,一个是接收字节的函数。这是库函数的东西,主要是将缓冲区的数据读取出来或者是发送出去。
在这个函数基础上,我们在sys.c中添加3个函数,一个是发字节,一个是发字符串,一个是自定义大写的Printf函数。注意在sys.h中要添加对应函数的声明。
//**********************************************************************
// /* 发送一个字节数据到USART */
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
/* 发送一个字节数据到USART */
USART_SendData(pUSARTx,ch);
/* 等待发送数据寄存器为空 */
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
// while((pUSARTx->SR&0X40)==0);//循环发送,直到发送完毕
// pUSARTx->DR = (u8) ch;
//
}
//*******************************************************************
//字符串发送函数
void Usart_SendString( USART_TypeDef * pUSARTx,char *buffertemp)
{
uint8_t i=0;
while(1)
{
if(buffertemp[i]!='\0')
{
USART_SendData(pUSARTx,buffertemp[i]); //发送一个字节
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE)==RESET){};//等待发送结束
i++;
}
else
return ;
}
}
/*
/*
- 函 数 名: Printf
- 功能说明: 可变参数重定义Printf函数
- 形 参: 1.串口号 2.char* fmt,… 格式化输出字符串和参数
- 返 回 值: 无
*/
#define USART_SENDBUFFLEN 256 //定义打印的字符串数组长度
char g_USART_SendBuff[USART_SENDBUFFLEN]; //用于打印的字符串数组
void Printf(USART_TypeDef* USARTx, char* fmt, ...)
{
u16 i = 0;
va_list ap; //清空下标
memset(g_USART_SendBuff,0,USART_SENDBUFFLEN); //清空字符数组
//可变参数列表变量(对象)
va_start(ap,fmt); //指明char*类型的fmt参数后面的才是可变参数的开始
vsprintf(g_USART_SendBuff,fmt,ap); //使用参数列表发送格式化输出到字符串
va_end(ap); //清空参数列表变量(对象)
while(g_USART_SendBuff[i]) //如果字符串数组为NULL则退出打印
{
while((USARTx->SR&0X40)==0);
USARTx->DR = g_USART_SendBuff[i++];
}
}
这里可以把这个USART_SENDBUFFLEN改为100,一般发送不会发送太多数据,100个字节基本够用了。
在SYS.h中添加对应的函数声明。
准备步骤充分了,我们就可以使用里面的函数,发送信息。
注意串口4和串口5是没有S的,少了一个字母。具体可以自己在学习。
#include “sys.h”
#include “usart.h”
#include “delay.h”
#include “led.h”
#include “beep.h”
int main(void)
{
u16 i=0;
int x;
float y;
Nvic_Init(NVIC_PriorityGroup_4);//中断分组第四组 高优先打断低优先
Set_Nvic_Irq(USART1_IRQn,0,3);//设置串口1的中断等级;
Delay_Init();//延时函数默认中断优先级是最低的。
LED_Init();//LED灯初始化
BEEP_Init();//蜂鸣器初始化
uart1_init(115200);//设置串口1的波特率是115200
//uart3_init(115200);//设置串口1的波特率是115200
Usart_SendByte(USART1,'a');//测试单字节发送函数
Usart_SendByte(USART1,'b');//测试单字节发送函数
Usart_SendString(USART1,"tab\r\n");//测试字符串发送函数
printf("hello world\r\n");//这个也能用,测试printf函数
printf("aaa=1,i=%d\r\n",i);//这个也能用,测试printf函数
Printf(USART1,"xxx=0,i=%d\r\n",i);//这个也能用,测试大写的Printf函数
//Printf(USART3,"xxx=0,i=%d\r\n",i);//这个也能用,测试大写的Printf函数
while(1)
{
printf("x=%3d\r\n",x);
delay_ms(500);
printf("y=%0.2f\r\n",y);
delay_ms(500);
}
}
#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "beep.h"
int main(void)
{
u16 i=0;
int x;
float y;
Nvic_Init(NVIC_PriorityGroup_4);//中断分组第四组 高优先打断低优先
Set_Nvic_Irq(USART1_IRQn,0,3);//设置串口1的中断等级;
Delay_Init();//延时函数默认中断优先级是最低的。
LED_Init();//LED灯初始化
BEEP_Init();//蜂鸣器初始化
uart1_init(115200);//设置串口1的波特率是115200
//uart3_init(115200);//设置串口1的波特率是115200
Usart_SendByte(USART1,'a');//测试单字节发送函数
Usart_SendByte(USART1,'b');//测试单字节发送函数
Usart_SendString(USART1,"tab\r\n");//测试字符串发送函数
printf("hello world\r\n");//这个也能用,测试printf函数
printf("aaa=1,i=%d\r\n",i);//这个也能用,测试printf函数
Printf(USART1,"xxx=0,i=%d\r\n",i);//这个也能用,测试大写的Printf函数
//Printf(USART3,"xxx=0,i=%d\r\n",i);//这个也能用,测试大写的Printf函数
while(1)
{
printf("x=%3d\r\n",x);
delay_ms(500);
printf("y=%0.2f\r\n",y);
delay_ms(500);
}
}