创新实验报告.docx
- 文档编号:28801912
- 上传时间:2023-07-19
- 格式:DOCX
- 页数:22
- 大小:691.20KB
创新实验报告.docx
《创新实验报告.docx》由会员分享,可在线阅读,更多相关《创新实验报告.docx(22页珍藏版)》请在冰豆网上搜索。
创新实验报告
专业综合实验
学院:
电气工程及自动化学院
专业:
测控技术与仪器
姓名:
赵闯
学号:
1090110304
一.研究背景
STM32系列基于专为要求高性能、低成本、低功耗的嵌入式应用专门设计的ARMCortex-M3内核。
按性能分成两个不同的系列:
STM32F103“增强型”系列和STM32F101“基本型”系列。
增强型系列时钟频率达到72MHz,是同类产品中性能最高的产品;基本型时钟频率为36MHz,以16位产品的价格得到比16位产品大幅提升的性能,是16位产品用户的最佳选择。
两个系列都内置32K到128K的闪存,不同的是SRAM的最大容量和外设接口的组合。
时钟频率72MHz时,从闪存执行代码,STM32功耗36mA,是32位市场上功耗最低的产品,相当于0.5mA/MHz。
在STM32F105和STM32F107互连型系列微控制器之前,意法半导体已经推出STM32基本型系列、增强型系列、USB基本型系列和增强型系列;新系列产品沿用增强型系列的72MHz处理频率。
内存包括64KB到256KB闪存和20KB到64KB嵌入式SRAM。
新系列采用LQFP64、LQFP100和LFBGA100三种封装,不同的封装保持引脚排列一致性,结合STM32平台的设计理念,开发人员通过选择产品可重新优化功能、存储器、性能和引脚数量,以最小的硬件变化来满足个性化的应用需求。
截至2010年7月1日,市面流通的型号有:
基本型:
STM32F101R6STM32F101C8STM32F101R8STM32F101V8STM32F101RBSTM32F101VB
增强型:
STM32F103C8STM32F103R8STM32F103V8STM32F103RBSTM32F103VBSTM32F103VESTM32F103ZE
STM32型号的说明:
以STM32F103RBT6这个型号的芯片为例,该型号的组成为7个部分,其命名规则如下:
(1)STM32:
STM32代表ARMCortex-M3内核的32位微控制器。
(2)F:
F代表芯片子系列。
(3)103:
103代表增强型系列。
(4)R:
R这一项代表引脚数,其中T代表36脚,C代表48脚,R代表64脚,V代表100脚,Z代表144脚。
(5)B:
B这一项代表内嵌Flash容量,其中6代表32K字节Flash,8代表64K字节Flash,B代表128K字节Flash,C代表256K字节Flash,D代表384K字节Flash,E代表512K字节Flash。
(6)T:
T这一项代表封装,其中H代表BGA封装,T代表LQFP封装,U代表VFQFPN封装。
(7)6:
6这一项代表工作温度范围,其中6代表-40——85℃,7代表-40——105℃。
二.跑马灯实验
1.STM32IO简介
STM32的IO口可以由软件配置成8种模式:
1、输入浮空
2、输入上拉
3、输入下拉
4、模拟输入
5、开漏输出
6、推挽输出
7、推挽式复用功能
8、开漏复用功能
每个IO口可以自由编程,单IO口寄存器必须要按32位字被访问。
STM32的很多IO口都是5V兼容的,这些IO口在与5V电平的外设连接的时候很有优势,具体哪些IO口是5V兼容的,可以从该芯片的数据手册管脚描述章节查到(I/OLevel标FT的就是5V电平兼容的)。
STM32的每个IO端口都有7个寄存器来控制。
他们分别是:
配置模式的2个32位的端口配置寄存器CRL和CRH;2个32位的数据寄存器IDR和ODR;1个32位的置位/复位寄存器BSRR;一个16位的复位寄存器BRR;1个32位的锁存寄存器LCKR;这里我们仅介绍常用的几个寄存器,我们常用的IO端口寄存器只有4个:
CRL、CRH、IDR、ODR。
CRL和CRH控制着每个IO口的模式及输出速率。
STM32的IO口位配置表如表1所示:
表1STM32的IO口位配置表
STM32输出模式配置如表2所示:
表2STM32输出模式配置表
接下来我们看看端口低配置寄存器CRL的描述,如下图所示:
表3端口低配置寄存器CRL各位描述
该寄存器的复位值为0X44444444,从上图可以看到,复位值其实就是配置端口为浮空输入模式。
从上图还可以得出:
STM32的CRL控制着每个IO端口(A~G)的低8位的模式。
每个IO端口的位占用CRL的4个位,高两位为CNF,低两位为MODE。
这里我们可以记住几个常用的配置,比如0X0表示模拟输入模式(ADC用)、0X3表示推挽输出模式(做输出口用,50M速率)、0X8表示上/下拉输入模式(做输入口用)、0XB表示复用输出(使用IO口的第二功能,50M速率)。
CRH的作用和CRL完全一样,只是CRL控制的是低8位输出口,而CRH控制的是高8位输出口。
这里我们对CRH就不做详细介绍了。
给个实例,比如我们要设置PORTC的11位为上拉输入,12位为推挽输出。
代码如下:
GPIOC->CRH&=0XFFF00FFF;//清掉这2个位原来的设置,同时也不影响其他位的设置
GPIOC->CRH|=0X00038000;//PC11输入,PC12输出
GPIOC->ODR=1<<11;//PC11上拉
通过这3句话的配置,我们就设置了PC11为上拉输入,PC12为推挽输出。
IDR是一个端口输入数据寄存器,只用了低16位。
该寄存器为只读寄存器,并且只能以16位的形式读出。
该寄存器各位的描述如下图所示:
图1端口输入数据寄存器IDR各位描述
要想知道某个IO口的状态,你只要读这个寄存器,再看某个位的状态就可以了。
使用起来是比较简单的。
ODR是一个端口输出数据寄存器,也只用了低16位。
该寄存器为可读写,从该寄存器读出来的数据可以用于判断当前IO口的输出状态。
而向该寄存器写数据,则可以控制某个IO口的输出电平。
该寄存器的各位描述如下图所示:
图2端口输出数据寄存器ODR各位描述
在此,我们可以总结一下,对于学过AVR的人来说,我们都知道AVR的IO口由3个寄存器控制:
DDR、PORT、PIN。
这里我们可以拿STM32的IO控制寄存器和AVR的来个类比:
1.STM32的CRL和CRH就相当于AVR的DDR寄存器,用来控制IO口的方向,只不过STM32的CRL和CRH功能更强大一点罢了。
2.STM32的ODR就相当于AVR的PORT,都是用来控制IO口的输出电平或者上下拉电阻的。
3.STM32的IDR就相当于AVR的PIN,都是用来存储IO口当前的输入状态(高低电平)的。
除此之外,STM32还有BSRR、BRR、LCKR等几个寄存器用于控制IO口,这点是AVR所没有的。
2.硬件设计
该实验的硬件电路在ALIENTEMMiniSTM32开发板上默认是已经连接好了的。
DS0接PA8,DS1接PD2。
所以在硬件上不需要动任何东西。
其连接原理图如下:
图3LED与STM32连接原理图
3.软件设计
(1)与硬件相关的代码
#include
#include"led.h"
voidLED_Init(void)
{
RCC->APB2ENR|=1<<2;//使能PORTA时钟
RCC->APB2ENR|=1<<5;//使能PORTD时钟
GPIOA->CRH&=0XFFFFFFF0;
GPIOA->CRH|=0X00000003;//PA8推挽输出
GPIOA->ODR|=1<<8;//PA8输出高
GPIOD->CRL&=0XFFFFF0FF;
GPIOD->CRL|=0X00000300;//PD.2推挽输出
GPIOD->ODR|=1<<2;//PD.2输出高
}
将这段代码保存在HARDWARE->LED文件夹下面,保存为led.c。
该代码里面就包含了一个函数voidLED_Init(void),该函数的功能就是用来实现配置PA8和PD2为推挽输出。
在配置STM32外设的时候,任何时候都要先使能该外设的时钟!
APB2ENR是APB2总线上的外设时钟使能寄存器,其各位的描述如下:
图4寄存器APB2ENR各位描述
我们要使能的PORTA和PORTD的时钟使能位,分别在bit2和bit5,只要将这两位置1就可以使能PORTA和PORTD的时钟了。
在设置完时钟之后就是配置完时钟之后,LED_Init配置了PA8和PD2的模式为推挽输出,并且默认输出1。
这样就完成了对这两个IO口的初始化。
保存led.c代码,然后我们按同样的方法,新建一个led.h文件,也保存在LED文件夹下面。
在led.h中输入如下代码:
#ifndef__LED_H
#define__LED_H
#include"sys.h"
//LED端口定义
#defineLED0PAout(8)//PA8
#defineLED1PDout
(2)//PD2
voidLED_Init(void);//初始化
#endif
(2)主程序流程图
图5程序流程图
(3)主程序
#include
#include"sys.h"
#include"usart.h"
#include"delay.h"
#include"led.h"
intmain(void)
{
Stm32_Clock_Init(9);//系统时钟设置
delay_init(72);//延时初始化
LED_Init();//初始化与LED连接的硬件接口
while
(1)
{
LED0=0;
LED1=1;
delay_ms(300);
LED0=1;
LED1=0;
delay_ms(300);
}
}
4.实验现象
开发板上两个LED交替闪烁,形成流水灯现象。
三.串口实验
1.串口介绍
STM32的串口资源相当丰富的,功能也相当强劲。
STM32最多可提供5路串口(ALIENTEKMiniSTM32使用的是STM32F103RBT6,只有3个串口),有分数波特率发生器、支持同步单线通信和半双工单线通讯、支持LIN、支持调制解调器操作、智能卡协议和IrDASIRENDEC规范(仅串口3支持)、具有DMA等。
串口最基本的设置,就是波特率的设置。
STM32的串口使用起来还是蛮简单的,只要您开启了串口时钟,并设置相应IO口的模式,然后配置一下波特率,数据位长度,奇偶校验位等信息,就可以使用了。
下面,我们就简单介绍下这几个与串口基本配置直接相关的寄存器。
1,串口时钟使能。
串口作为STM32的一个外设,其时钟由外设时钟使能寄存器控制,这里我们使用的串口1是在APB2ENR寄存器的第14位。
APB2ENR寄存器在之前已经介绍过了,这里不再介绍。
只是说明一点,就是除了串口1的时钟使能在APB2ENR寄存器,其他串口的时钟使能位都在APB1ENR寄存器。
2,串口复位。
当外设出现异常的时候可以通过复位寄存器里面的对应位设置,实现该外设的复位,然后重新配置这个外设达到让其重新工作的目的。
一般在系统刚开始配置外设的时候,都会先执行复位该外设的操作。
串口1的复位是通过配置APB2RSTR寄存器的第14位来实现的。
APB2RSTR寄存器的各位描述如下图所示:
图6APB2RSTR寄存器各位描述
串口1的复位设置位在APB2RSTR的第14位。
通过向该位写1复位串口1,写0结束复位。
其他串口的复位位在APB1RSTR里面。
3,串口波特率设置。
每个串口都有一个自己独立的波特率寄存器USART_BRR,通过设置该寄存器就可以达到配置不同波特率的目的。
4,串口控制。
STM32的每个串口都有3个控制寄存器USART_CR1~3,串口的很多配置都是通过这3个寄存器来设置的。
这里我们只要用到USART_CR1就可以实现我们的功能了,该寄存器的各位描述如下图所示:
图7USART_CR寄存器各位描述
该寄存器的高18位没有用到,低14位用于串口的功能设置。
UE为串口使能位,通过该位置1,以使能串口。
M为字长选择位,当该位为0的时候设置串口为8个字长外加n个停止位,停止位的个数(n)是根据USART_CR2的[13:
12]位设置来决定的,默认为0。
PCE为校验使能位,设置为0,则禁止校验,否则使能校验。
PS为校验位选择,设置为0则为偶校验,否则为奇校验。
TXIE为发送缓冲区空中断使能位,设置该位为1,当USART_SR中的TXE位为1时,将产生串口中断。
TCIE为发送完成中断使能位,设置该位为1,当USART_SR中的TC位为1时,将产生串口中断。
RXNEIE为接收缓冲区非空中断使能,设置该位为1,当USART_SR中的ORE或者RXNE位为1时,将产生串口中断。
TE为发送使能位,设置为1,将开启串口的发送功能。
RE为接收使能位,用法同TE。
5,数据发送与接收。
STM32的发送与接收是通过数据寄存器USART_DR来实现的,这是一个双寄存器,包含了TDR和RDR。
当向该寄存器写数据的时候,串口就会自动发送,当收到收据的时候,也是存在该寄存器内。
该寄存器的各位描述如下图所示:
图8USART_DR寄存器各位描述
可以看出,虽然是一个32位寄存器,但是只用了低9位(DR[8:
0]),其他都是保留。
DR[8:
0]为串口数据,包含了发送或接收的数据。
由于它是由两个寄存器组成的,一个给发送用(TDR),一个给接收用(RDR),该寄存器兼具读和写的功能。
TDR寄存器提供了内部总线和输出移位寄存器之间的并行接口。
RDR寄存器提供了输入移位寄存器和内部总线之间的并行接口。
当使能校验位(USART_CR1种PCE位被置位)进行发送时,写到MSB的值(根据数据的长度不同,MSB是第7位或者第8位)会被后来的校验位该取代。
当使能校验位进行接收时,读到的MSB位是接收到的校验位。
6,串口状态。
串口的状态可以通过状态寄存器USART_SR读取。
USART_SR的各位描述如下图所示:
图9USART_SR寄存器各位描述
这里我们关注一下两个位,第5、6位RXNE和TC。
RXNE(读数据寄存器非空),当该位被置1的时候,就是提示已经有数据被接收到了,并且可以读出来了。
这时候我们要做的就是尽快去读取USART_DR,通过读USART_DR可以将该位清零,也可以向该位写0,直接清除。
TC(发送完成),当该位被置位的时候,表示USART_DR内的数据已经被发送完成了。
如果设置了这个位的中断,则会产生中断。
该位也有两种清零方式:
1)读USART_SR,写USART_DR。
2)直接向该位写0。
通过以上一些寄存器的操作外加一下IO口的配置,我们就可以达到串口最基本的配置了。
2.硬件设计
该实验的硬件配置不同于前两个实验,串口1与USB串口默认是分开的,并没有在PCB上连接在一起,需要通过跳线帽来连接一下。
这里我们把P4的RXD和TXD用跳线帽与P3的PA9和PA10连接起来。
如下图所示:
图10硬件连接图
3.软件设计
打开TEST工程,然后在SYSTEM组下双击usart.c,我们就可以看到该文件里面的代码,先介绍uart_init函数,该函数代码如下:
//初始化IO串口1
//pclk2:
PCLK2时钟频率(Mhz)
//bound:
波特率
voiduart_init(u32pclk2,u32bound)
{
floattemp;
u16mantissa;
u16fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp;//得到整数部分
fraction=(temp-mantissa)*16;//得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2;//使能PORTA口时钟
RCC->APB2ENR|=1<<14;//使能串口时钟
GPIOA->CRH=0X444444B4;//IO状态设置
RCC->APB2RSTR|=1<<14;//复位串口1
RCC->APB2RSTR&=~(1<<14);//停止复位
//波特率设置
USART1->BRR=mantissa;//波特率设置
USART1->CR1|=0X200C;//1位停止,无校验位.
#ifdefEN_USART1_RX//如果使能了接收
//使能接收中断
USART1->CR1|=1<<8;//PE中断使能
USART1->CR1|=1<<5;//接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART1_IRQChannel,2);//组2,最低优先级
#endif
}
从该代码可以看出,其初始化串口的过程,和我们前面介绍的一致先计算得到USART1->BRR的内容。
然后开始初始化串口引脚,接着把USART1复位,然之后设置波特率和奇偶校验等。
这里需要注意一点,因为我们使用到了串口的中断接收,必须在usart.h里面定义EN_USART1_RX。
该函数才会配置中断使能,以及开启串口1的NVIC中断。
这里我们把串口1中断放在组2,优先级设置为组2里面的最低。
再介绍一下串口1的中断服务函数USART1_IRQHandler,该函数的名字不能自己定义了,MDK已经给每个中断都分配了一个固定的函数名,我们直接用就可以了。
具体这些函数的名字是什么,我们可以在MDK提供的例子里面,找到stm32f10x_it.c,该文件里面包含了STM32所有的中断服务函数。
USART1_IRQHandler的代码如下:
voidUSART1_IRQHandler(void)
{
u8res;
if(USART1->SR&(1<<5))//接收到数据
{
res=USART1->DR;
if((USART_RX_STA&0x80)==0)//接收未完成
{
if(USART_RX_STA&0x40)//接收到了0x0d
{
if(res!
=0x0a)USART_RX_STA=0;//接收错误,重新开始
elseUSART_RX_STA|=0x80;//接收完成了
}
else//还没收到0X0D
{
if(res==0x0d)USART_RX_STA|=0x40;
else
{
USART_RX_BUF[USART_RX_STA&0X3F]=res;
USART_RX_STA++;
if(USART_RX_STA>63)USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
该函数的重点就是判断接收是否完成,通过检测是否收到0X0D、0X0A的连续2个字节(0X0D后跟0X0A表示回车键)来检测是否结束。
当检测到这个结束序列之后,就会置位USART_RX_STA的最高为来标记已经收到了一次数据。
之后等待外部函数清空该位之后才开始第二次接收。
所接收的数据全部存放在USART_RX_BUF里面,一次接收数据不能超过64个字节,否则被丢弃。
介绍完了这两个函数,我们回到test.c。
其流程图为:
图11流程图
代码为:
#include
#include"sys.h"
#include"usart.h"
#include"delay.h"
#include"led.h"
#include"key.h"
intmain(void)
{
u8t;
u8len;
u16times=0;
Stm32_Clock_Init(9);//系统时钟设置
delay_init(72);//延时初始化
uart_init(72,9600);//串口初始化为9600
LED_Init();//初始化与LED连接的硬件接口
while
(1)
{
if(USART_RX_STA&0x80)
{
len=USART_RX_STA&0x3f;//得到此次接收到的数据长度
printf("\n您发送的消息为:
\n");
for(t=0;t { USART1->DR=USART_RX_BUF[t]; while((USART1->SR&0X40)==0);//等待发送结束 } printf("\n\n");//插入换行 USART_RX_STA=0; } else { times++; if(times%5000==0) { printf("\nMiniSTM32开发板串口实验\n"); printf("正点原子@ALIENTEK\n\n\n"); } if(times%200==0)printf("请输入数据,以回车键结束\n"); if(times%30==0)LED0=! LED0;//闪烁LED,提示系统正在运行. delay_ms(10); } } } 4.实验现象 未发送数据时串口助手显示如下: 图12未发送数据时串口调试助手收到的信息 在输入发送的文字,并按下回车键时候,串口助手显示如下: 图13发送数据后串口助手显示 四.自主创新实验 本实验设计在串口实验的基础上添加了控制功能。 当控制开关按下,指示灯亮,方可进行数据发送,否则即便在发送区输入文字,显示区也不会显示。 #include #include"sys.h" #include"usart.h" #include"delay.h" #include"led.h" #include"key.h" intmain(void) { u8t,m,n u8len; u16times=0; Stm32_Clock_Init(9);//系统时钟设置 delay_init(72);//延时初始化 uart_init(72,9600);//串口初始化为9600 LED_Init();//初始化与LED连接的硬件接口 KEY_Init();//初始化与按键连接的硬件接口 while (1) { m=KEY_Scan();//得到键值 while(m==1) { LED0=0; n=KEY_Scan(); if(n==2)break; if(USART_RX_STA&0x80) { len=USART_RX_STA&0x3f;//得到此次接收到的数据长度 printf("\n您发送的消息为: \n"); for(t=0;t { USART1->DR=USART_RX_BUF[t]; while((USART1->SR&0X40)==0);//等待发送结束 } printf("\n\n");//插入换行 USART_RX_STA=0; } else { times++; if(times%5000==0) {
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 创新 实验 报告