嵌入式STM32

您所在的位置:网站首页 耐克在中国有哪些工厂生产 嵌入式STM32

嵌入式STM32

2024-06-03 10:28:12| 来源: 网络整理| 查看: 265

在这里插入图片描述

嵌入式STM32--实验四、串口通信实验 一、 实验目的二、 实验设备三、 实验原理3.1、状态寄存器`USART_SR`及函数3.2、USATR1 发送一个字节3.3、接收一个字节的数据3.4、串口编程为如下步骤: 四、实验内容4.1、用STM32设计一个与计算机进行串口通讯的实验。STM32向PC发送 123ABC,用串口调试助手显示出来,查询方式完成。(代码:实验4-1)4.2、用STM32设计一个与计算机进行串口通讯的实验。PC向STM32发送 456789 ,STM32接收后,将 每位数值+3 发送给PC,用 串口调试助手 显示出来,用中断方式完成。(代码:实验4-2)4.2.3、用STM32设计一个与计算机进行串口通讯的实验,利用PC控制LED的亮灭。(代码:实验4-3)4.4、利用定时器结合串口实现 电子时钟的功能。(代码:实验4-4) 五、实验总结实验四代码下载链接

​ 自律 学习 坚强 ,拒绝迷茫。

作者:行走的皮卡丘

时间:2021/4/4

喜欢就去追,这个红灯等不到,说不定下一个红灯等到了,嘻嘻!!!!!!!

一、 实验目的

1、 掌握STM32串口通信原理。

2、 学习编程实现STM32的UART通信。

二、 实验设备

硬件:

​ PC机 一台

​ STM32开发板 一套

软件:

​ MDK V4.0 一套

​ Windows 7 一套

​ 调试助手 一套

三、 实验原理 3.1、状态寄存器USART_SR及函数

img

第5、6位 RXNE 和TC

RXNE(读数据寄存器非空),当该位被置1的时候,就是提示已经有数据被接收到了,并且可以读出来了。

TC(发送完成),当该位被置位的时候,表示USART_DR内的数据已经被发送完成了。

在固件库函数里面,读取串口状态的函数是:

FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG );

这个函数的第二个入口参数非常关键,它是标示我们要查看串口的哪种状态,比如上面讲解的RXNE(读数据寄存器非空)以及TC(发送完成)。

例如:要判断读寄存器是否非空(RXNE),操作库函数的方法是:

USART_GetFlagStatus(USART1,USART_FLAG_RXNE);

要判断发送是否完成(TC),操作库函数的方法是:

USART_GetFlagStatus(USART1,USART_FLAG_TC); 3.2、USATR1 发送一个字节 /**************************************************************** USATR1 发送一个字节 功能:发送一个字节的数据 入口参数:发送到数据 出口参数:无 *****************************************************************/ void Send_OneByte(uint8_t onebyte) { while(RESET == USART_GetFlagStatus(USART1, USART_FLAG_TC));//等待发送完毕 USART_SendData(USART1, onebyte); } 3.3、接收一个字节的数据 /**************************************************************** 功能:接收一个字节的数据 入口参数:无 出口参数:返回收到的数据 *****************************************************************/ uint8 rxdata;//存储收到的数据 uint8 Receive_OneByte(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET)//串口收到数据 { rxdata = USART_ReceiveData(USART1); } return rxdata; } 3.4、串口编程为如下步骤: //1) 串口时钟使能, GPIO 时钟使能 //配置时钟,由于使用串口是在复用IO口,需要打开串口时钟和相应的IO口时钟。 //2) GPIO 端口模式设置 //串口相应的IO口需要配置,输出口配置成复用推挽输出,输出速度根据需要配置,输入口配置为悬空输入。 //3) 串口参数初始化,使能串口。(***\*串口调试助手 与之一致\**** ) USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = ***\*115200\****; //波特率 USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位 USART_InitStructure.USART_StopBits = USART_StopBits_1; //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 //USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启接收中断。若无中断,该项不需要 USART_Cmd(USART1, ENABLE); //使能串口1 //4) 初始化 NVIC且开启中断(若开启中断才需要该步骤) NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0) NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ; //抢占优先级0,级别可自己设定 ,下面的子优先级可自定 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 //5) 编写中断处理函数 (有中断才需要该步骤) 四、实验内容

1、用STM32设计一个与计算机进行串口通讯的实验。STM32向PC发送 123ABC ,用串口调试助手 显示出来,用查询方式完成。

2、用STM32设计一个与计算机进行串口通讯的实验。PC向STM32发送 456789 ,STM32接收后,将 每位数值+3 发送给PC,用 串口调试助手显示出来,用中断方式完成。

3、用STM32设计一个与计算机进行串口通讯的实验,利用PC控制LED的亮灭。

1)PC向STM32发送 A ,控制LED1,LED2,LED3同时亮灭,间隔时间0.5S,同时在 串口调试助手显示LED1,LED2,LED3同时亮灭”。

2)PC向STM32发送 B ,控制LED1,LED2,LED3正向流水亮灭,间隔时间1S,同时在串口调试助手显示LED1,LED2,LED3正向流水亮灭”。

3)PC向STM32发送 C ,控制LED1,LED2,LED3反向流水亮灭,间隔时间2S,同时在 串口调试助手显示LED1,LED2,LED3反向流水亮灭”。

4、利用定时器结合串口实现 电子时钟的功能。功能如下:

1)定时器完成 1S 的定时。

2)串口调试助手*上显示时间,格式参考如下 12:34:56 ,每秒递增。串口调试助手每2秒刷新一次。

③在LCD上显示时间,格式参考如下 12:34:56 ,每秒递增。例程可参考 FSMC-液晶显示-英文的配套例程。

4.1、用STM32设计一个与计算机进行串口通讯的实验。STM32向PC发送 123ABC,用串口调试助手显示出来,查询方式完成。(代码:实验4-1)

img

usart.c函数

#include "sys.h" #include "usart.h" #pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; }; FILE __stdout; //定义_sys_exit()以避免使用半主机模式 void _sys_exit(int x) { x = x; } //重定义fputc函数 int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 USART1->DR = (u8) ch; return ch; } //串口1中断服务程序 //注意,读取USARTx->SR能避免莫名其妙的错误 u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节. //接收状态 //bit15, 接收完成标志 //bit14, 接收到0x0d //bit13~0, 接收到的有效字节数目 u16 USART_RX_STA=0; //接收状态标记 void uart_init(u32 bound){ //GPIO端口设置 GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟 //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //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_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_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(USART1, &USART_InitStructure); //初始化串口1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_Cmd(USART1, ENABLE); //使能串口1 } void USART1_IRQHandler(void) //串口1中断服务程序 { u8 Res; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { Res =USART_ReceiveData(USART1); //读取接收到的数据 if((USART_RX_STA&0x8000)==0)//接收未完成 { if(USART_RX_STA&0x4000)//接收到了0x0d { if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始 else USART_RX_STA|=0x8000; //接收完成了 } else //还没收到0X0D { if(Res==0x0d)USART_RX_STA|=0x4000; else { USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ; USART_RX_STA++; if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收 } } } } }

usart.h函数

#ifndef __USART_H #define __USART_H #include "stdio.h" #include "sys.h" #define USART_REC_LEN 200 //定义最大接收字节数 200 #define EN_USART1_RX 1 //使能(1)/禁止(0)串口1接收 extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 extern u16 USART_RX_STA; //接收状态标记 //如果想串口中断接收,请不要注释以下宏定义 void uart_init(u32 bound); #endif

main函数

#include "delay.h" #include "sys.h" #include "usart.h" /************************************************** * Function main * @author 行走的皮卡丘 * @date 2021/4/4 * @brief * @param[in] * @param[out] void * @retval void * @par History 无 * TXD PA.9 * RXD PA.10 *************************************************/ int main(void) { u16 t; u8 data[10]="123ABC"; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 while(1) { printf("\r\nSTM32发送的消息为: "); for(t=0;t char String[]="0123456789ABCDEFG"; u8 i; u8 data; u16 len; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 while(1) { if(USART_RX_STA&0x8000) { len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度 USART_RX_BUF[len] = 0; printf("\r\n PC发送的消息为:%s\r\n",USART_RX_BUF); printf(" STM32发送的消息为:"); for(i = 0;i GPIO_InitTypeDef GPIO_InitStr; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);// GPIO_InitStr.GPIO_Mode=GPIO_Mode_Out_PP;//推挽 GPIO_InitStr.GPIO_Pin=GPIO_Pin_0; GPIO_InitStr.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStr); // PB0 LED1 GPIO_InitStr.GPIO_Pin=GPIO_Pin_4; GPIO_Init(GPIOC,&GPIO_InitStr); // PC4 LED2 GPIO_InitStr.GPIO_Pin=GPIO_Pin_3; GPIO_Init(GPIOC,&GPIO_InitStr); // PC3 LED3 GPIO_SetBits(GPIOB,GPIO_Pin_0); GPIO_SetBits(GPIOC,GPIO_Pin_4); GPIO_SetBits(GPIOC,GPIO_Pin_3); } int main(void) { u16 i=0; u16 len; u16 data; LED_Init(); //LED端口初始化 delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 while(1) { if(USART_RX_STA&0x8000) //接收数据 { len = USART_RX_STA&0x3f; for(i = 0;i data = 0; printf("LED1,LED2,LED3同时亮灭\r\n"); LED1=1; LED2=1; LED3=1; while(USART_RX_STA==0) { LED1=~LED1; LED2=~LED2; LED3=~LED3; delay_100ms(5); } } if(data == 'B') { data = 0; printf("LED1,LED2,LED3正向流水亮灭\r\n"); while(USART_RX_STA==0) { LED1=1; LED2=1; LED3=0; delay_100ms(10); LED1=1; LED2=0; LED3=1; delay_100ms(10); LED1=0; LED2=1; LED3=1; delay_100ms(10); } } if(data == 'C') { data = 0; printf("LED1,LED2,LED3反向流水亮灭\r\n"); LED1=1; LED2=1; LED3=1; while(USART_RX_STA==0) { LED1=0; LED2=1; LED3=1; delay_100ms(20); LED1=1; LED2=0; LED3=1; delay_100ms(20); LED1=1; LED2=1; LED3=0; delay_100ms(20); } } } } } 4.4、利用定时器结合串口实现 电子时钟的功能。(代码:实验4-4)

定时器完成 1S 的定时。

形参设置为arr=9999,psc=7199即可

img

串口调试助手上显示时间,格式参考如下 12:34:56 ,每秒递增。串口调试助手每2秒刷新一次。

主函数中的死循环,其中flay在定时器2的中断中累加,即一秒以1累加。

img

在LCD上显示时间,格式参考如下 12:34:56,每秒递增。例程可参考FSMC-液晶显示-英文的配套例程。

img

main函数

#include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "timer.h" #include "lcd.h" /************************************************** * Function main * @author 行走的皮卡丘 * @date 2021/4/4 * @brief * @param[in] * @param[out] void * @retval void * @par History 无 * TXD PA.9 * RXD PA.10 *************************************************/ int main(void) { ILI9341_Init(); ILI9341_GramScan( 6 ); //设置默认扫描方向,其中 6 模式为大部分液晶例程的默认显示方向 LCD_SetColors(GBLUE,BLACK); //设置颜色 ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH); LCD_SetFont(&Font16x24); LCD_SetTextColor(GREEN); //设置文本颜色 delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级 uart_init(115200); //串口初始化为115200 LED_Init(); //LED端口初始化 TIM2_Int_Init(9999,7199); //一秒一次中断 72 000 000 /7200=10000 10000/10000=1hz 1/1hz=1s while(1) { if( flay==2 ) { flay = 0; printf("%s\r\n",TimeStr); } } } 五、实验总结

加油!!!行走的皮卡丘!!!!

实验四代码下载链接


【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭