寄存器与固件库的区别
基于寄存器的编程方式:
基于寄存器的编程方式是直接用语句操作寄存器。相对于固件库来说,如果想使用基于寄存器的编程方式,就需要对于各个寄存器的使用比较熟悉,相对于新手来说,比较难上手。
基于固件库的编程方式:
固件库就是函数的集合,固件库函数的作用是向下负责与寄存器直接打交道,向上提供用户函数调用的接口(API)。也就是说,我们先调用固件库中的函数,然后固件库调用的函数来操作寄存器。虽然不能完全抛弃对寄存器的使用,但是相对对寄存器的编程方式而言,基于固件库的编程方式对于新手而言就更加友好。
STM32的USART串口通讯
提示:本篇文章是基于正点原子芯片STM32f103精英版。
串口作为 MCU 的重要外部接口,同时也是软件开发重要的调试手段, 其重要性不言而喻。
现在基本上所有的 MCU 都会带有串口, STM32 自然也不例外。
串口设置的一般步骤
- 串口时钟使能 GPIO 时钟使能
- 串口复位
- GPIO 端口模式设置
- 串 口 参数 初始化
- 开启中断 并且初始化 NVIC (如果需要开启中断才需要这个步骤)
- 使能串口
- 编写 中断处理函数
串口输出与中断输出
首先打开正点原子历程中的工程文件:串口实验
再根据正点原子的历程进行修改,实现以下三个任务:
1)设置波特率为115200,1位停止位,无校验位。
2)STM32系统给上位机(win10)连续发送“hello windows!”,上位机接收程序可以使用“串口调试助手“,也可自己编程。
3)当上位机给stm32发送“Stop,stm32”后,stm32停止发送。
主函数
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
int main(void)
{
u16 t;
u16 len;
u16 times=0;
u8 s[]={"停止发送!"};
u8 b[]={"开始发送!"};
u16 flag=1,flag_s,flag_b;//设定标志位
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
KEY_Init(); //初始化与按键连接的硬件接口
while(1)
{
flag_s=1;
flag_b=1;
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
for(t=0;t<len;t++)
{
if(s[t]!=USART_RX_BUF[t]) flag_s=0;
if(b[t]!=USART_RX_BUF[t]) flag_b=0;
USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
}
printf("\r\n\r\n");//插入换行
if(flag_s==1)
{
flag=0;
}
if(flag_b==1)
{
flag=1;
}
USART_RX_STA=0;
}else
{
if(flag==1) times++;
if(times%200==0&&flag==1)printf("Hello HuYue!\n");
if(times%30==0&&flag==1)LED0=!LED0;//闪烁LED,提示系统正在运行.
delay_ms(10);
}
}
}
调试结果
串口调试助手参数设置如下图所示:
打开串口,传输数据:
分析:打开串口,发送数据“Hello HuYue!”,向串口发送数据“停止发送”,串口标志位置为0,即停止发送数据;向串口发送数据“开始发送”,将串口标志位置为1,即串口又开始发送数据。
当串口在发送数据的时候,LED灯在不断的闪烁;当串口停止发送数据的时候,LED灯不再闪烁。
以下图是在正常传输数据的时候的LED灯的状态:
总结
基于固件库和寄存器的两种编程方式都可以对STM32进行编程,但相对于新手来说,固件库的编程方式会更加友好,因为没有用到特别多的寄存器的使用方法。STM32的串口可以向上位机发送数据,上位机也可以向STM32发送数据,以达到控制STM32的目的。