STM32 串行通信 USART 程序例举
2014-05-02 19:07
316 查看
STM32 串行通信 USART 的笔记讲解连接/article/9902798.html
1、串行通信
程序运行前的仿真界面:
程序运行后的仿真界面:
2、串行通信
首先:在主函数部分先要(调用自己编写的函数)对USART要用到的I/O端口进行配置、打开系统时钟配置和对USART1进行参数配置
下图是通过调用库函数对USART1的参数进行配置,将其配置成异步收发模式、波特率用户可以自定的串口:
源程序:
程序运行前:
程序运行后:
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); }
程序运行前的仿真界面:
程序运行后的仿真界面:
2、串行通信
软件仿真STM32通过串口USART1发送26个英文字母(调用库函数)
首先:在主函数部分先要(调用自己编写的函数)对USART要用到的I/O端口进行配置、打开系统时钟配置和对USART1进行参数配置下图是通过调用库函数对USART1的参数进行配置,将其配置成异步收发模式、波特率用户可以自定的串口:
源程序:
/************************************************************************************************** * 硬件平台:STM32F103VC * 学习重点:调用库函数来实现对USART的操作 * 实现功能:软件仿真,实现STM32通过USART1发送数据 * 作 者:赵小龙 **************************************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_lib.h" //包含了所有的头文件 它是唯一一个用户需要包括在自己应用中的文件,起到应用和库之间界面的作用。 #include "stm32f10x_map.h" /*----------------函数声明部分---------------*/ void delay1ms(int t) ; void RCC_Configuration(void) ; void GPIO_Configuration(void) ; void USART_Configuration(u32 BaudRate) ; /* Private functions -----------------------------------------------------------------------------*/ /************************************************************************************************** * Function Name : main * Description : 软件仿真,从USART1发送26个大写的英文字母 * Input : None * Output : None * Return : None ****************************************************************************************************/ int main(void) { u8 i,data; /*--------配置开启系统时钟、配置USART1发送/接收使用的两个I/O口、配置USART1---------------------------------------------*/ RCC_Configuration(); GPIO_Configuration(); USART_Configuration(19600); /*--------发送一串字符‘A’--‘Z’到USART1的DR-----------------------------------------------------------------------------*/ data='A'; for(i=0;i<26;i++) { USART_SendData(USART1, data) ; data++ ; while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) ;//发送完成标志位为1时便是数据发送完毕,若为0时则应让程序等待(等待数据发送发送完成) /*注意:这里最好不要按照以下形式书写,否则会出错,具体原因我暂且还不知道 u8 status ; status = USART_GetFlagStatus(USART1, USART_FLAG_TC) ; //将查看状态寄存器的函数的返回值赋值给变量status while(status == RESET) ; */ } } /******************************************************************************* * 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); } /******************************************************************************* * Function Name : USART_Configuration * Description : 初始化串口USART1(异步收发模式) * Input : BaudRate (要设置的波特率) * Output : None * Return : None *******************************************************************************/ void USART_Configuration(u32 BaudRate) { //1、定义一个用于初始化USART的结构体 USART_InitTypeDef USART_InitStructure; //2、给结构体元素赋值,设置 波特率、数据帧的位数、停止位的位数、奇偶校验位、硬件流控制位、USART模式(发送、接收) USART_InitStructure.USART_BaudRate = BaudRate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //3、调用函数USART_Init();用上面的结构体值作为参数对USART1进行初始化 USART_Init(USART1, &USART_InitStructure); //4、调用函数USART_Cmd();对USART1进行使能 USART_Cmd(USART1, ENABLE); }
程序运行前:
程序运行后:
相关文章推荐
- 基于Mahout的电影推荐系统(MVC架构)
- 基于WebServices简易网络聊天工具的设计与实现
- 委托与事件
- 基于WebServices简易网络聊天工具的设计与实现
- poj 1113 Wall
- 解决Win 7桌面图标无法删除的问题
- OK6410开发板ARM基本介绍(一)S3C6410的地址映射
- codechef Factorial 算法 fread读入数据
- Apache Spark源码走读之5 -- DStream处理的容错性分析
- 如何通过Html网页调用本地安卓app
- Making the Grade(poj1527)
- Socket的正确关闭(改良版)
- 五月学习笔记
- 如何构建一个优秀的移动网站?谷歌教你25招
- 基于jquery的滚动鼠标放大缩小图片效果
- Shells作为cronjobs运行
- c语言中longjmp的个人心得
- 关于Qt窗口保持宽高比的研究
- HDU 2897巴什博弈变形
- Java加密解密与数字证书的操作