STM32 串行通信 USART 程序例举
扫描二维码
随时随地手机看文章
1、串行通信 软件仿真STM32通过串口USART1发送26个英文字母(配置寄存器)
/**************************************************************************************************
*硬件平台:STM32F103VC
*学习重点:GPIOx的位绑定
*实现功能:软件仿真,实现STM32通过USART1发送数据
*配置寄存器实现(其中打开系统时钟和GPIO引脚的配置是通过库函数实现的,后面会具体讲解)
**************************************************************************************************/
/*=============================================================================
*位绑定公式:
*1、SRAM区域:0X22000000----0X200FFFFF
*Aliasaddr=0X22000000+(A-0X20000000)*32+n*4
*2、片上外设区域:0X42000000----0X400FFFFF
*Aliasaddr=0X42000000+(A-0X40000000)*32+n*4
*参数解释:
*Aliasaddr:设置“端口GPIOx的第n位”的寄存器_相应位的实际地址
*A:端口GPIOx的基地址(GPIOx_BASE)+相应寄存器的偏移地址
*n:配置的是相应寄存器的第n位
*寄存器的偏移地址:CRLCRHIDRODRBSRRBRRLCKR
*00H04H08H0CH10H14H18H
=============================================================================*/
/*Includes------------------------------------------------------------------*/
#include"stm32f10x_lib.h"//包含了所有的头文件它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。
#include"stm32f10x_map.h"
/******************************快速位绑定**********************************************************/
/*----------------1、宏定义要操作的寄存器地址---------------------------------------------*/
#defineGPIOA_ODR(GPIOA_BASE+0X0C)
#defineGPIOA_IDR(GPIOA_BASE+0X08)
#defineGPIOB_ODR(GPIOB_BASE+0X0C)
#defineGPIOB_IDR(GPIOB_BASE+0X08)
#defineGPIOC_ODR(GPIOC_BASE+0X0C)
#defineGPIOC_IDR(GPIOC_BASE+0X08)
#defineGPIOD_ODR(GPIOD_BASE+0X0C)
#defineGPIOD_IDR(GPIOD_BASE+0X08)
#defineGPIOE_ODR(GPIOE_BASE+0X0C)
#defineGPIOE_IDR(GPIOE_BASE+0X08)
/*----------------2、获取端口GPIOx(A-E)的对应寄存器的某一操作位的位地址-------------------*/
//#defineBitBand(Addr,BitNum)*((volatileunsignedlong*)(Addr&0xf0000000)+0x2000000+((Addr&0xfffff)*32)+(BitNum*4))
//因为左移、右移语句的执行速度比乘除法语句的运动速度快,所以将上述语句改成如下方式
#defineBitBand(Addr,BitNum)*((volatileunsignedlong*)((Addr&0xf0000000)+0x2000000+((Addr&0xfffff)<<5)+(BitNum<<2)))
/*----------------3、宏定义函数,对固定的位绑定进行功能封装------------------------------*/
#definePAout(n)BitBand(GPIOA_ODR,n)
#definePAin(n)BitBand(GPIOA_IDR,n)
#definePBout(n)BitBand(GPIOB_ODR,n)
#definePBin(n)BitBand(GPIOB_IDR,n)
#definePCout(n)BitBand(GPIOC_ODR,n)
#definePCin(n)BitBand(GPIOC_IDR,n)
#definePDout(n)BitBand(GPIOD_ODR,n)
#definePDin(n)BitBand(GPIOD_IDR,n)
#definePEout(n)BitBand(GPIOE_ODR,n)
#definePEin(n)BitBand(GPIOE_IDR,n)
/*----------------函数声明部分---------------*/
voiddelay1ms(intt);
voidRCC_Configuration(void);
voidGPIO_Configuration(void);
/*Privatefunctions-----------------------------------------------------------------------------*/
/**************************************************************************************************
*FunctionName:main
*Description:从GPIOA.8-.16输入一个电平信号,GPIOA.0-.7口分别将对应引脚输入的电平信号输出
*Input:None
*Output:None
*Return:None
****************************************************************************************************/
intmain(void)
{
floatDiv;//计算波特率时公式里面的除数
u16M,F;//临时存储Div的整数部分的数字和小数部分的数字
u32Bound,BRR;//Bound:要设置的波特率,BRR:是Div的整数部分和小数部分整合后存入寄存器USART1->BRR中的值
u8data='A';//存放要发送的数据
RCC_Configuration();//配置开启系统时钟
GPIO_Configuration();//配置IO口
/*--------USART1模块的设置:UE位使能、M位来定义字长、停止位的位数、TE位、BRR寄存器选择要求的波特率----------------*/
USART1->CR1|=(1<<13);//位于寄存器CR1的第13位。UE=1;对USART1进行使能。(=0时,分频器和输出被禁止)
USART1->CR1&=~(1<<12);//位于寄存器CR1的第12位。M=0;无奇偶校验位,起始位+8位数据+停止位(=1时,带一位奇偶校验位)
USART1->CR2&=~(3<<12);//位于寄存器CR2的第13-12位。STOP=00;1位停止位。(=01;0.5位。=10;2位。=11;1.5位)
USART1->CR1|=(1<<3);//位于寄存器CR1的第3位。USART1的发送使能位。TE=1;发送使能(=0时,禁止发送)
Bound=9600;//设置波特率
Div=(float)(72*1000*1000)/(Bound*16);//乘以16是因为该芯片是16位的。(寄存器也是16位的)
M=Div;
F=(Div-M)*16;
BRR=M<<4|F;
USART1->BRR=BRR;
/*--------发送一串字符‘A’--‘Z’到USART1的DR-----------------------------------------------------------------------------*/
for(F=0;F<26;F++)
{
USART1->DR=data;
data++;
while((USART1->SR&(1<<6))==0);
}
}
/*******************************************************************************
*FunctionName:Delay_Ms
*Description:delay1ms.
*Input:dly(ms)
* Output