我是靠谱客的博主 唠叨老师,最近开发中收集的这篇文章主要介绍STM32----------串口通信(USART),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

#include "stm32f10x.h"
#include "platform_config.h"
#include "stm32f10x_usart.h"
#include "misc.h"
#include "stdarg.h"
USART_InitTypeDef USART_InitStructure;
uint8_t TxBuffer1[] = "USART Interrupt Example: This is USART2 DEMO";
uint8_t RxBuffer1[],rec_f,tx_flag;
__IO uint8_t TxCounter1 = 0x00;
__IO uint8_t RxCounter1 = 0x00;
uint32_t Rec_Len;
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void Delay(__IO uint32_t nCount);
void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...);
char *itoa(int value, char *string, int radix);
void USART_Config(USART_TypeDef* USARTx);
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStruct;
USART_ClockInitTypeDef USART_ClockInitStruct;
void USART_Config(USART_TypeDef* USARTx){
USART_InitStructure.USART_BaudRate = 115200;
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_Rx | USART_Mode_Tx;
//
USART_Init(USARTx, &USART_InitStructure);
//
/* Enable USARTx Receive and Transmit interrupts */
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); //使能接收端中断,TXE发送中断,TC传输完成中断,RXNE接收中断
USART_ITConfig(USART2, USART_IT_TXE, ENABLE);
//使能发送端空中断
/* Enable the USARTx */
USART_Cmd(USART2, ENABLE);
}
int main(void)
{
uint8_t a=0;
/* System Clocks Configuration */
RCC_Configuration();
NVIC_Configuration();
GPIO_Configuration();
USART_Config(USART2);
USART_OUT(USART2,"****(C)
COPYRIGHT 2014 ·
******rn");
USART_OUT(USART2,"*
*rn");
USART_OUT(USART2,"*
*rn");
USART_OUT(USART2,"*
www.ourstm.net
*rn");
USART_OUT(USART2,"*
*rn");
USART_OUT(USART2,"***************************************************rn");
USART_OUT(USART2,"rn");
USART_OUT(USART2,"rn");
while (1)
{
if(rec_f==1){
rec_f=0;
USART_OUT(USART2,"你将发送的数据是 :rn");
USART_OUT(USART2,&TxBuffer1[0]);
if(a==0) {GPIO_SetBits(GPIOB, GPIO_Pin_5); a=1;}
else {GPIO_ResetBits(GPIOB, GPIO_Pin_5);a=0;
}
}
}
}
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
void USART_OUT(USART_TypeDef* USARTx, uint8_t *Data,...){
const char *s;
int d;
char buf[16];
va_list ap;
va_start(ap, Data);
while(*Data!=0){
if(*Data==0x5c){
//''
switch (*++Data){
case 'r':
//
USART_SendData(USARTx, 0x0d);
Data++;
break;
case 'n':
//
USART_SendData(USARTx, 0x0a);
Data++;
break;
default:
Data++;
break;
}
}
else if(*Data=='%'){
//
switch (*++Data){
case 's':
//
s = va_arg(ap, const char *);
for ( ; *s; s++) {
USART_SendData(USARTx,*s);
while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
}
Data++;
break;
case 'd':
//
d = va_arg(ap, int);
itoa(d, buf, 10);
for (s = buf; *s; s++) {
USART_SendData(USARTx,*s);
while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
}
Data++;
break;
default:
Data++;
break;
}
}
else USART_SendData(USARTx, *Data++);
while(USART_GetFlagStatus(USARTx, USART_FLAG_TC)==RESET);
}
}
char *itoa(int value, char *string, int radix)
{
int
i, d;
int
flag = 0;
char
*ptr = string;
/* This implementation only works for decimal numbers. */
if (radix != 10)
{
*ptr = 0;
return string;
}
if (!value)
{
*ptr++ = 0x30;
*ptr = 0;
return string;
}
/* if this is a negative value insert the minus sign. */
if (value < 0)
{
*ptr++ = '-';
/* Make the value positive. */
value *= -1;
}
for (i = 10000; i > 0; i /= 10)
{
d = value / i;
if (d || flag)
{
*ptr++ = (char)(d + 0x30);
value -= (d * i);
flag = 1;
}
}
/* Null terminate the string. */
*ptr = 0;
return string;
} /* NCL_Itoa */
void RCC_Configuration(void)
{
SystemInit();
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_AFIO
, ENABLE);
RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2, ENABLE);
}
void GPIO_Configuration(void)
{
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
//USART2 TX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
//
GPIO_Init(GPIOA, &GPIO_InitStructure);
//
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
//USART2 RX
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//
GPIO_Init(GPIOA, &GPIO_InitStructure);
//
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

上面的是main.c  ,下面是stm32f10x_it.c中断服务程序

<span style="font-size:18px;">#include "stm32f10x_it.h"
#include "stm32f10x_usart.h"
extern uint8_t TxBuffer1[];
extern uint8_t TxBuffer2[];
extern uint8_t RxBuffer1[];
extern uint8_t RxBuffer2[];
extern __IO uint8_t TxCounter1;
extern __IO uint8_t TxCounter2;
extern __IO uint8_t RxCounter1;
extern __IO uint8_t RxCounter2;
extern uint8_t rec_f,tx_flag;
void USART2_IRQHandler(void)
//串口2中断服务函数
{
unsigned int i;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
//判断读寄存器是否为空,也就是是否有数据发送进来,是否发生接收中断
{
RxBuffer1[RxCounter1++] = USART_ReceiveData(USART2);
//将读寄存器的数据存到接收缓冲区里面
if(RxBuffer1[RxCounter1-2]==0x0d&&RxBuffer1[RxCounter1-1]==0x0a)
//判断结束标志位是否为0x0d 0x0a (rn)
也就是是否为回车
</span>

{
for(i=0; i< RxCounter1; i++) TxBuffer1[i]	= RxBuffer1[i];
//将接收区数据送到发送缓冲区,准备转发
rec_f=1;
//接收成功标志
TxBuffer1[RxCounter1]=0;
//发送缓冲区结束符
RxCounter1=0;
}
}
if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET)
//这段是为了STM32 UART 第一个字节发送不出去的BUG
{
USART_ITConfig(USART2, USART_IT_TXE, DISABLE);
//禁止发缓冲器空中断
}
}


STM32笔记之九:打断它来为我办事,EXIT (外部I/O中断)应用

a) 目的:跟串口输入类似,不使用中断进行的IO输入效率也很低,而且可以通过EXTI插入按钮事件,本节联系EXTI中断。

b) 初始化函数定义:

void EXTI_Configuration(void); //定义IO中断初始化函数

c) 初始化函数调用:

EXTI_Configuration();//IO中断初始化函数调用简单应用:

d) 初始化函数:

void EXTI_Configuration(void)

{ EXTI_InitTypeDef EXTI_InitStructure; //EXTI初始化结构定义

EXTI_ClearITPendingBit(EXTI_LINE_KEY_BUTTON);//清除中断标志

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);//管脚选择

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);

     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5);

     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//事件选择

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//触发模式

    EXTI_InitStructure.EXTI_Line = EXTI_Line3 | EXTI_Line4; //线路选择

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;//启动中断

    EXTI_Init(&EXTI_InitStructure);//初始化

}

e) RCC初始化函数中开启I/O时钟

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);

GPIO初始化函数中定义输入I/O管脚。

//IO输入,GPIOA的4脚输入

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;        //上拉输入

    GPIO_Init(GPIOA, &GPIO_InitStructure);              //初始化

f) 在NVIC的初始化函数里面增加以下代码打开相关中断:

    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel; //通道

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//占先级

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //响应级

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //启动

    NVIC_Init(&NVIC_InitStructure); //初始化

g) 在stm32f10x_it.c文件中找到void USART1_IRQHandler函数,在其中添入执行代码。一般最少三个步骤:先使用if语句判断是发生那个中断,然后清除中断标志位,最后给字符串赋值,或做其他事情。

    if(EXTI_GetITStatus(EXTI_Line3) != RESET)                                //判断中断发生来源

{ EXTI_ClearITPendingBit(EXTI_Line3);                                         //清除中断标志

USART_SendData(USART1, 0x41);                                            //发送字符“a”

GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_2)));//LED发生明暗交替

}

h) 中断注意事项:

中断发生后必须清除中断位,否则会出现死循环不断发生这个中断。然后需要对中断类型进行判断再执行代码。

使用EXTI的I/O中断,在完成RCC与GPIO硬件设置之后需要做三件事:初始化EXTI、NVIC开中断、编写中断执行代码。

中断注意事项:

可以随时在程序中使用USART_ITConfig(USART1, USART_IT_TXE, DISABLE);来关闭中断响应。

NVIC_InitTypeDef NVIC_InitStructure定义一定要加在NVIC初始化模块的第一句。

全局变量与函数的定义:在任意.c文件中定义的变量或函数,在其它.c文件中使用extern+定义代码再次定义就可以直接调用了。


最后

以上就是唠叨老师为你收集整理的STM32----------串口通信(USART)的全部内容,希望文章能够帮你解决STM32----------串口通信(USART)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部