STM32 串行通信 USART 程序例举

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);

}

程序运行前的仿真界面:

程序运行后的仿真界面:

STM32 串行通信 USART 程序例举

时间: 2024-10-27 00:41:40

STM32 串行通信 USART 程序例举的相关文章

STM32串行通信USART解说笔记

STM32串行通信USART程序例举链接:http://blog.csdn.net/dragon12345666/article/details/24883111 1.STM32串行通信USART的相关介绍: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZHJhZ29uMTIzNDU2NjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > w

stm32之USART通信

任何USART通信,需要用到2个对外连接的引脚:RxD,TxD: RxD是输入引脚,用于串行数据接收: TxD是输出引脚,用于串行数据发送: SCLK引脚:发生器时钟输出(同步模式下,异步模式下不需要) 在IrDA模式(红外模式)下需要下列引脚: IrDA_RDI: 红外模式下的数据输入: IrDA_TDO:红外模式下的数据输出: 调制解调模式下需要: nCTS:清除发送: nRTS:发送请求: 数据的接收/发送过程示意图: 异步串行通信协议需要定义以下5个内容: 1.起始位 2.数据位(8/9

例举法(创新技法4)

例举法和检核表法都是一种列表法.例举法表示:一.缺点列举法: 缺点例举法是美国通用公司的发明的一种创新方法,方法是通过对事物的分析,着重找出它的缺点和不足,然后再根据主次和因果,采取改进措施.从而在原有的基础上创造一个新的成果.任何一个产品都会有优点和缺点,这个优缺点当然是以人们的需求来作为判断的,缺点一般都是产品在某个方面不能满足人们的需求,或者对环境和人们本身有损害,因此对产品的缺点进行改进就是一种很基本的需求.因此缺点例举法是非常自然而然的一种改进和完善产品的基本方法.事物的缺点一般分为造

C#学习日志 day 6 ------ 常用正则表达式例举

c#支持正则表达式匹配文本,这里讨论一下正则表达式的使用方法以及例举一些常用的正则表达式的匹配. 1.在vs中使用正则表达式 在vs中使用正则表达式,需要using System.Text.RegularExpressions命名空间. 该命名空间包涵以下几个类 Capture 用于单个表达式捕获结果 CaptureCollection 用于一个序列进行字符串捕获 Group 表示单个捕获的结果 GroupCollection 表示捕获组的集会 Match 表示匹配单个正则表达式结果 Match

[stm32] NRF24L01+USART搞定有线和无线通信

前言 一般进行远程监控时,2.4G无线通信是充当远程数据传输的一种方法.这时就需要在现场部分具备无线数据发送装置,而在上位机部分由于一般只有串口,所以将采集到的数据送到电脑里又要在上位机端设计一个数据接收的适配器.这里基于stm32分别设计了现场部分和适配器部分,这里只是基本通信功能实现的讲解,一些复杂的技术比如加密.可靠等要根据具体的应用来设计~ 总体说明 这里采用stm32作为MCU,采用nRF24L01作为2.4G通信模块.其中适配器中仅仅采用了USART和NRF24L01两个主要部分,负

STM32的USART中断死循环,形成死机。

直接说重点:我用的是 STM32F103 芯片 USART2_IRQHandler 总是中断,程序死循环. 1.出现问题: 原程序的中断处理程序是: void USART2_IRQHandler(void){  u8 key = 0;  USART_ClearFlag(USART2,USART_FLAG_TC ); //清除中断标志  if(USART_GetITStatus(USART2,USART_IT_RXNE)!=Bit_RESET)//检查指定的usart是否发生了中断  {     

STM32之usart

1.uart与usart的区别 UART:universal asynchronous receiver and transmitter 通用 异步 接收 发送 [总线信号] TX , RX USART:universal synchronous asynchronous receiver and transmitter 通用 同步 异步 接收 发送 [总线信号] TX, RX, CK 总体来说,usart只是比uart多了一个同步信号,usart可以使用同步方式进行信息的收发 同步传输与异步传

一个STM32的IAP程序,测试可以用

注意使用的是keil5.11a 自己根据开发指南写的一个IAP程序.在mini板上成功跑一个app.因为RB是128K的flash,所以将rom分割为 27K 1K 100K.其中27K 用来存储IAP.1K 用来存储一些信息,目前暂未使用到.100K就是app用的啦.    IAP程序的大致流程是这样的,上电后,在5s内(实际测试发现大于5s,暂时不管这个误差),轮询串口是否发送:updata;(update这个可以随意,保证:;中间有6个字母就好).如果超时没有收到:update;那么程序跳

STM32的USART

一.STM32常见波特率图标. USART1是由APB2总线提供时钟,而USART2~USART5是由APB1总线提供时钟,APB1的时钟是36Mhz,比APB2总线时钟要慢一半,所以USART1实际上可以在高速一点的波特率传输的时候要比USART2~USART5稳定. 二.STM32具有硬件流控制 三.STM32与printf()函数 四.串口数据的实时性计算 注:以下是常有的串口接口: