STM32
直播中

孔妞妞

12年用户 481经验值
私信 关注
[问答]

USART和UATR的配置流程是怎样的

USART与UATR相比有何优势?
USART和UATR的配置流程是怎样的?



回帖(1)

李洁

2021-12-10 15:47:19
1、USART和UATR

USART:通用同步/异步串行接收/发送器
UART:通用异步收发传输器
  相比于UART可以看出USART多出了同步串行接收/发送功能。
  2、配置流程






  1) 串口时钟使能,GPIO 时钟使能
  2) 串口复位
  3) GPIO 端口模式设置
  4) 串口参数初始化
  5) 开启中断并且初始化 NVIC
  6) 使能串口
  7) 编写中断处理函数

  !注意!:在CT117E平台需使用USART2
  串口-管脚-总线映射表:
[tr]串口USART1USART2USART3[/tr]
管脚(TX/RX)PA9/PA10PA2/PA3PB10/PB11
总线APB2APB1APB1
  关于硬件流控制:
  硬件流:RTS/CTS (Request To Send/Clear To Send)即请求发送/清除发送协议,用于半双工时的收发切换,半双工的意思是说,发的时候不收,收的时候不发。那么怎么区分收发呢?缺省时是DCE向DTE发送数据,当DTE决定向DCE发数据时,先有效RTS,表示DTE希望向DCE发送。一般DCE不能马上转换收发状态,DTE就通过监测CTS是否有效来判断可否发送,这样避免了DTE在DCE未准备好时发送所导致的数据丢失。
  简单的说就是:在发送之前告诉你我要发送数据(有效RTS),通过检测CTS来查看这个时候总线是否空闲,来决定是否可以发送数据
  在低速场合不用。
  3、部分源码

  实验目的:实现响应上位机命令(发送字符1):串口发送RTC时间(本次实验是在上次RTC附加闹钟版工程上基础上写的)
  main.c:

#include "Headfile.h"


/**
* @file                 main.c
* @brief                 实现响应上位机命令(发送字符1):串口发送RTC时间
* @version        1.1
* @author         JosephCooper
* @date                 2020年8月27日
*/


void Delay_Ms(u32 nTime);
/** 滴答定时器实现延时中间变量 */
u32 TimingDelay = 0;
/** 闹钟状态标志位 */
u8 AlarmFlag = 0;
/** 闹钟状态标志位 */
u8 USART_StringBuffer[20];


//Main Body
int main(void)
{
        u8 Index = 0;
        SysTick_Config(SystemCoreClock/1000);
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
       
        Delay_Ms(200);
       
        LEDInit();//LED初始化
        //关闭所有LED
        LEDCmd(Bit_SET);
        GPIO_Write(GPIOC,GPIO_ReadOutputData(GPIOC) | 0xFF00);
        LEDCmd(Bit_RESET);
       
        STM3210B_LCD_Init();
        LCD_Clear(Blue);
        LCD_SetBackColor(Blue);
        LCD_SetTextColor(White);


        USART2_Init(9600);
        BuzzerInit();//蜂鸣器初始化
        RTCInit(23,59,55);//实时时钟初始化
        AlarmEXITInit();
        //AlarmSet(23,59,59);
       
        while(1)
        {
                if(USART_RX_Buffer[0] == '1')
                {
                        RTCtoString(USART_StringBuffer);
                        USART2_SendString(USART_StringBuffer);
                        //清空USART接受数据缓冲区
                        for(Index = 0;Index < 20;Index ++)
                        {
                                USART_RX_Buffer[Index] = 0;
                        }
                        USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
                }
        }
}


//
void Delay_Ms(u32 nTime)
{
        TimingDelay = nTime;
        while(TimingDelay != 0);       
}




  USART.c:


#include "Headfile.h"


/** USART接受数据缓冲区 */
u8 USART_RX_Buffer[20];


void USART2_Init(u32 Bound)
{
       
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        //串口时钟及GPIOA时钟使能
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
        //串口复位
        USART_DeInit(USART2);
        //GPIO设置 PA2复用推挽输出 PA3浮空
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        //串口参数初始化
        USART_InitStructure.USART_BaudRate = Bound;//波特率
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位字长
        USART_InitStructure.USART_StopBits = USART_StopBits_1;//1位停止位
        USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验
        USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;//收发双模式
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件流控制
        USART_Init(USART2,&USART_InitStructure);
        //初始化NVIC
        NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
       
        USART_Cmd(USART2,ENABLE);//使能串口
        USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//开启USART2接收中断
}


void USART2_SendString(u8 *Str)
{
        u8 Index = 0;
        while(Str[Index] != 0)
        {
                USART_SendData(USART2,Str[Index]);
                while(USART_GetFlagStatus(USART2,USART_FLAG_TXE) == 0);
                Index ++;
        }
}


void USART2_IRQHandler(void)
{
        u16 Temp;
        u8 USART_RX_Cnt = 0;
        if(USART_GetFlagStatus(USART2,USART_IT_RXNE) == 1)
        {
                USART_ClearFlag(USART2,USART_IT_RXNE);
                Temp = USART_ReceiveData(USART2);
                if(Temp == 'n')
                {
                        USART_RX_Cnt = 0;
                        USART_ITConfig(USART2,USART_IT_RXNE,DISABLE);
                }
                else
                {
                        USART_RX_Buffer[USART_RX_Cnt++] = Temp;
                }
        }
}


  RTC.c:(只需要注意RTCtoString函数就行其他同上一节RTC章节中的闹钟部分.c文件相同)


... ...


void RTCtoString(u8 *str)
{
        u32 Time = 0;
        u8 Hour = 0,Min = 0,Sec = 0;
        Time = RTC_GetCounter();
        RTC_WaitForLastTask();
        if(Time >= (23*3600 + 59*60 + 59))
        {
                RTC_SetCounter(0);
                RTC_WaitForLastTask();
        }
       
        Hour = Time / 3600;
        Min = (Time % 3600) / 60;
        Sec = (Time % 3600) % 60;
        sprintf((char *)str,"%.2d:%.2d:%.2dn", Hour, Min, Sec);


}


... ...


注意!:推荐将串口接收中断优先级设为当前所有中断中的最高级。
  效果实现图(推荐使用自己熟悉的串口助手调试完成后再使用AccessPort调试):


举报

更多回帖

发帖
×
20
完善资料,
赚取积分