码迷,mamicode.com
首页 > 其他好文 > 详细

STM32 串行通信 USART 程序例举

时间:2014-05-05 13:23:11      阅读:345      评论:0      收藏:0      [点我收藏+]

标签:stm32   串行通信   usart   stm32串行通信程序例举   中南赵小龙   

STM32 串行通信 USART 的笔记讲解连接http://blog.csdn.net/dragon12345666/article/details/24484185

1、串行通信 软件仿真STM32通过串口USART1发送26个英文字母

/**************************************************************************************************
 *	硬件平台:STM32F103VC
 *	学习重点:GPIOx的位绑定
 *	实现功能:软件仿真,实现STM32通过USART1发送数据
 *	配置寄存器实现(其中打开系统时钟和GPIO引脚的配置是通过库函数实现的,后面会具体讲解)
 **************************************************************************************************/

 /*=============================================================================
 * 位绑定公式:
 * 1、SRAM区域 :0X2200 0000 ----0X200F FFFF
 *    Aliasaddr = 0X22000000 + ( A -0X20000000 )*32 + n*4
 * 2、片上外设区域 :0X4200 0000 ----0X400F FFFF
 *    Aliasaddr = 0X42000000 + ( A -0X40000000 )*32 + n*4
 * 参数解释:
 *          Aliasaddr : 设置“端口GPIOx的第n位”的寄存器_相应位的实际地址
 *          A : 端口GPIOx的基地址(GPIOx_BASE) + 相应寄存器的偏移地址
 *          n : 配置的是相应寄存器的第n位
 * 寄存器的偏移地址 :CRL  CRH  IDR  ODR  BSRR  BRR  LCKR
 *                    00H  04H  08H  0CH  10H   14H  18H 
 =============================================================================*/


/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"	  //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。
#include "stm32f10x_map.h"


/******************************快速位绑定**********************************************************/
/*----------------1、宏定义要操作的寄存器地址---------------------------------------------*/
 #define GPIOA_ODR (GPIOA_BASE + 0X0C)
 #define GPIOA_IDR (GPIOA_BASE + 0X08)

 #define GPIOB_ODR (GPIOB_BASE + 0X0C)
 #define GPIOB_IDR (GPIOB_BASE + 0X08)

 #define GPIOC_ODR (GPIOC_BASE + 0X0C)
 #define GPIOC_IDR (GPIOC_BASE + 0X08)

 #define GPIOD_ODR (GPIOD_BASE + 0X0C)
 #define GPIOD_IDR (GPIOD_BASE + 0X08)

 #define GPIOE_ODR (GPIOE_BASE + 0X0C)
 #define GPIOE_IDR (GPIOE_BASE + 0X08)

/*----------------2、获取端口GPIOx(A-E)的对应寄存器的某一操作位的位地址-------------------*/
// #define BitBand(Addr , BitNum) *( (volatile unsigned long *)(Addr & 0xf0000000) + 0x2000000 + ((Addr&0xfffff)*32) + (BitNum*4) ) 
// 因为 左移、右移 语句的执行速度比乘除法语句的运动速度快,所以将上述语句改成如下方式
 #define BitBand(Addr , BitNum) *( (volatile unsigned long *)( (Addr & 0xf0000000) + 0x2000000 + ((Addr&0xfffff)<<5) + (BitNum<<2) ) ) 
  
/*----------------3、宏定义函数,对固定的位绑定 进行功能封装------------------------------*/
 #define PAout(n) BitBand(GPIOA_ODR , n) 
 #define PAin(n)  BitBand(GPIOA_IDR , n)

 #define PBout(n) BitBand(GPIOB_ODR , n) 
 #define PBin(n)  BitBand(GPIOB_IDR , n)

 #define PCout(n) BitBand(GPIOC_ODR , n) 
 #define PCin(n)  BitBand(GPIOC_IDR , n)

 #define PDout(n) BitBand(GPIOD_ODR , n) 
 #define PDin(n)  BitBand(GPIOD_IDR , n)

 #define PEout(n) BitBand(GPIOE_ODR , n) 
 #define PEin(n)  BitBand(GPIOE_IDR , n)


/*----------------函数声明部分---------------*/
void delay1ms(int t) ;
void RCC_Configuration(void) ;
void GPIO_Configuration(void) ;


/* Private functions -----------------------------------------------------------------------------*/ 
/**************************************************************************************************
* Function Name  : main
* Description    : 从GPIOA.8-.16输入一个电平信号,GPIOA.0-.7口分别将对应引脚输入的电平信号输出
* Input          : None
* Output         : None
* Return         : None
****************************************************************************************************/
int main(void)
{

	float Div; 	//计算波特率时公式里面的除数
	u16 M,F;    //临时存储Div的整数部分的数字和小数部分的数字
	u32 Bound,BRR;	//Bound:要设置的波特率 , BRR:是Div的整数部分和小数部分整合后存入寄存器USART1->BRR中的值
	u8  data=‘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) ;
	}

}

/*******************************************************************************
* Function Name  : Delay_Ms
* Description    : delay 1 ms.
* Input          : dly (ms)
* Output         : None
* Return         : None
*******************************************************************************/
void delay1ms(int t)
{
	//机器周期T = 1/(72000000/12)s = 1/6000000 s = 1/6 us
	int temp = 6000/4 ;
	while(t--)
	{
		while(temp--)
		{ ; }	
	}

}


/*******************************************************************************
* Function Name  : RCC_Configuration
* Description    : Configures the different system clocks.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void RCC_Configuration(void)
{
	//----------使用外部RC晶振-----------
	RCC_DeInit();			//初始化为缺省值
	RCC_HSEConfig(RCC_HSE_ON);	//使能外部的高速时钟 
	while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);	//等待外部高速时钟使能就绪
	
	//FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);	//Enable Prefetch Buffer
	//FLASH_SetLatency(FLASH_Latency_2);		//Flash 2 wait state
	
	RCC_HCLKConfig(RCC_SYSCLK_Div1);		//HCLK = SYSCLK
	RCC_PCLK2Config(RCC_HCLK_Div1);			//PCLK2 =  HCLK
	RCC_PCLK1Config(RCC_HCLK_Div2);			//PCLK1 = HCLK/2
	RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);	//PLLCLK = 8MHZ * 9 =72MHZ
	RCC_PLLCmd(ENABLE);			//Enable PLLCLK

	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);	//Wait till PLLCLK is ready
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);	//Select PLL as system clock
	while(RCC_GetSYSCLKSource()!=0x08);		//Wait till PLL is used as system clock source
	
	//---------打开相应外设时钟--------------------
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);	//使能APB2外设的GPIOA的时钟	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);	//使能APB2外设的GPIOC的时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	//GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);	 
		 
}

/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : 初始化GPIO外设
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/ 
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure USARTx_Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* Configure USARTx_Rx as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

}

程序运行前的仿真界面:

bubuko.com,布布扣

程序运行后的仿真界面:

bubuko.com,布布扣






























STM32 串行通信 USART 程序例举,布布扣,bubuko.com

STM32 串行通信 USART 程序例举

标签:stm32   串行通信   usart   stm32串行通信程序例举   中南赵小龙   

原文地址:http://blog.csdn.net/dragon12345666/article/details/24883111

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!