一,串口相关寄存器


USART_SR 状态寄存器

USART_DR 数据寄存器

USART_BRR 波特率寄存器

USART_CR1 控制寄存器


USART_SR-状态寄存器:

这里写图片描述
   
  状态寄存器USART_SR,描述串口寄存器的一些状态: 
   
  如位5:读数据寄存器非空 
   
  这里写图片描述 
   
  通过读取这个位的值,判断是否收到了完整的数据 
  串口已经接收到了数据,并且已经写入到了USART_DR寄存器


USART_DR-数据寄存器:

  这里写图片描述
   
  数据寄存器USART_DR,只使用了位0-8,其他位保留 
   
  这里写图片描述

  读寄存器:读取该寄存器获取接收到的数据值 
  写寄存器:向该寄存器写入发送的数据对数据进行发送


USART_BRR-波特率寄存器:

  这里写图片描述
   
  波特率寄存器USART_BRR,只用到了低16位,高16位保留 
   
  这里写图片描述

  0-3位[3:0]  : USART分频器的小数部分DIV_Fraction 
  4-15位[15:4] : USART分频器的整数部分DIV_Mantissa


USART_CR1-控制寄存器:

  这里写图片描述
   
  USART_BRR波特率寄存器,设置串口寄存器使能位 
   
  如:接收使能,发送使能 
   
  这里写图片描述


二,波特率的计算方法

波特率发生器

  这里写图片描述

如图:

    波特率由波特率发生器和PCLKx共同产生

    PCLKx的值由串口本身决定

    通过配置USART_BRR寄存器确定波特率发生器的值

    经过USARTDIV分频器除以16得到最终的波特率

波特率计算方法:

  这里写图片描述

设置串口1波特率为115200MHz

串口1的时钟来自PCLK2=72MHz


由公式得到:

    USARTDIV=72000000/(115200*16)=39.0625


整数部分DIV_Mantissa=39=0x27

小数部分DIV_Fraction=16*0,0625=1=0x01


所以设置USART->BRR=0x0271,就可以实现设置串口1的波特率为115200MHz


三,串口操作相关库函数


获取状态标志位函数-操作USART_SR寄存器


// 获取状态标志位

FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);

// 清除状态标志位

void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);

// 获取中断状态标志位

ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);

// 清除中断状态标志位

void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);


接收发送数据函数-操作USART_DR寄存器


// 发送数据到串口(通过写USART_DR寄存器发送数据)

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);

// 接收数据(从USART_DR寄存器读取接收到的数据)

uint16_t USART_ReceiveData(USART_TypeDef* USARTx);


串口配置函数


// 串口初始化:波特率,数据字长,奇偶校验,硬件流控以及收发使能

void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);

// 使能串口

void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);

// 使能相关中断

void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);


四,串口硬件连接


PA9-RXD

PA10-TXD

CH340  USB转串口    将USB虚拟为串口使用


五,串口配置的步骤


1,串口时钟使能,GPIO时钟使能

     RCC_APB2PeriphClockCmd()

2,串口复位

     USART_DeInit();

3,GPIO端口模式设置

     GPIO_Init();

4,串口参数初始化

     USART_Init()

5,开启中断并初始化NVIC

     NVIC_Init();

     USART_ITConfig();

6,使能串口

     USART_Cmd();

7,中断函数逻辑

     USARTx_IRQHandler();

8,串口数据发送

     void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);

     uint16_t USART_ReceiveData(USART_TypeDef* USARTx);

9,串口传输状态获取

     ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT);

     void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);


六,串口测试程序设计


程序功能:


 电脑通过USB线连接开发板,开发板通过USB转串口实现和电脑的通信

 电脑使用串口工具想单片机发送数据,单片机收到数据后返回给电脑


 注:以串口1为例实现


七,串口测试程序实现分析


1,使能GPIO时钟


串口1的发送,接收引脚为PA9和PA10

所以我们要使能GPIOA和串口1的时钟

串口1和GPIOx时钟源为APB2

所以使用RCC_APB2PeriphClockCmd函数进行初始化


stm32f10x_rcc.c找到RCC_APB2PeriphClockCmd函数源码:


/**

  * @brief  Enables or disables the High Speed APB (APB2) peripheral clock.

  * @param  RCC_APB2Periph: specifies the APB2 peripheral to gates its clock.

  *   This parameter can be any combination of the following values:

  *     @arg RCC_APB2Periph_AFIO, RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB,

  *          RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,

  *          RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG, RCC_APB2Periph_ADC1,

  *          RCC_APB2Periph_ADC2, RCC_APB2Periph_TIM1, RCC_APB2Periph_SPI1,

  *          RCC_APB2Periph_TIM8, RCC_APB2Periph_USART1, RCC_APB2Periph_ADC3,

  *          RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,

  *          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11

  * @param  NewState: new state of the specified peripheral clock.

  *   This parameter can be: ENABLE or DISABLE.

  * @retval None

  */

void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)

{

  /* Check the parameters */

  assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));

  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (NewState != DISABLE)

  {

    RCC->APB2ENR |= RCC_APB2Periph;

  }

  else

  {

    RCC->APB2ENR &= ~RCC_APB2Periph;

  }

}


stm32f10x_rcc.h找到IS_RCC_APB2_PERIPH函数声明:


/** @defgroup APB2_peripheral

  * @{

  */


#define RCC_APB2Periph_AFIO              ((uint32_t)0x00000001)

#define RCC_APB2Periph_GPIOA             ((uint32_t)0x00000004)

#define RCC_APB2Periph_GPIOB             ((uint32_t)0x00000008)

#define RCC_APB2Periph_GPIOC             ((uint32_t)0x00000010)

#define RCC_APB2Periph_GPIOD             ((uint32_t)0x00000020)

#define RCC_APB2Periph_GPIOE             ((uint32_t)0x00000040)

#define RCC_APB2Periph_GPIOF             ((uint32_t)0x00000080)

#define RCC_APB2Periph_GPIOG             ((uint32_t)0x00000100)

#define RCC_APB2Periph_ADC1              ((uint32_t)0x00000200)

#define RCC_APB2Periph_ADC2              ((uint32_t)0x00000400)

#define RCC_APB2Periph_TIM1              ((uint32_t)0x00000800)

#define RCC_APB2Periph_SPI1              ((uint32_t)0x00001000)

#define RCC_APB2Periph_TIM8              ((uint32_t)0x00002000)

#define RCC_APB2Periph_USART1            ((uint32_t)0x00004000)

#define RCC_APB2Periph_ADC3              ((uint32_t)0x00008000)

#define RCC_APB2Periph_TIM15             ((uint32_t)0x00010000)

#define RCC_APB2Periph_TIM16             ((uint32_t)0x00020000)

#define RCC_APB2Periph_TIM17             ((uint32_t)0x00040000)

#define RCC_APB2Periph_TIM9              ((uint32_t)0x00080000)

#define RCC_APB2Periph_TIM10             ((uint32_t)0x00100000)

#define RCC_APB2Periph_TIM11             ((uint32_t)0x00200000)


#define IS_RCC_APB2_PERIPH(PERIPH) ((((PERIPH) & 0xFFC00002) == 0x00) && ((PERIPH) != 0x00))


从参数定义验证了GPIOA-GPIOG 和串口1(USART1)的时钟使能由RCC_APB2PeriphClockCmd()控制


所以使能GPIOA和串口1时钟代码为:


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);     //使能GPIOA时钟源

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);    //使能串口1时钟源


2,初始化GPIOA的工作模式

通过查找STM32中文参考手册确定串口1引脚工作模式配置:

  这里写图片描述

如图:

串口1接收发送引脚配置

    发送端PA9配置为推挽复用输出

    接收端PA10配置为浮空输入或上拉输入


代码:


GPIO_InitTypeDef GPIO_InitStrue;


//发送端PA9配置

GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;            //发送端-TXD

GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;      //推挽输出

GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;

GPIO_Init(GPIOA, &GPIO_InitStrue);


//接收端PA10配置

GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;           //接收端-RXD

GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入

GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;

GPIO_Init(GPIOA, &GPIO_InitStrue);


3,串口初始化


stm32f10x_usart.h头文件找到USART_Init函数声明:


void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct);


stm32f10x_usart.h找到入参USART_InitTypeDef结构体声明


/**

  * @brief  USART Init Structure definition

  */

typedef struct

{

  uint32_t USART_BaudRate;               // 设置波特率

  uint16_t USART_WordLength;             // 字长8或9(停止位)

  uint16_t USART_StopBits;               // 停止位

  uint16_t USART_Parity;                 // 奇偶校验

  uint16_t USART_Mode;                   // 发送接收使能

  uint16_t USART_HardwareFlowControl;    // 硬件流控制

} USART_InitTypeDef;


USART_HardwareFlowControl-硬件流参数有效性验证


/** @defgroup USART_Hardware_Flow_Control

  * @{

  */

#define USART_HardwareFlowControl_None       ((uint16_t)0x0000)

#define USART_HardwareFlowControl_RTS        ((uint16_t)0x0100)

#define USART_HardwareFlowControl_CTS        ((uint16_t)0x0200)

#define USART_HardwareFlowControl_RTS_CTS    ((uint16_t)0x0300)

#define IS_USART_HARDWARE_FLOW_CONTROL(CONTROL)\

                              (((CONTROL) == USART_HardwareFlowControl_None) || \

                               ((CONTROL) == USART_HardwareFlowControl_RTS) || \

                               ((CONTROL) == USART_HardwareFlowControl_CTS) || \

                               ((CONTROL) == USART_HardwareFlowControl_RTS_CTS))


USART_Mode-使能参数有效性验证


/** @defgroup USART_Mode

  * @{

  */



#define USART_Mode_Rx ((uint16_t)0x0004) #define USART_Mode_Tx ((uint16_t)0x0008) #define IS_USART_MODE(MODE) ((((MODE) & (uint16_t)0xFFF3) == 0x00) && ((MODE) != (uint16_t)0x00))


USART_Parity-奇偶校验参数有效性


/** @defgroup USART_Parity

  * @{

  */



#define USART_Parity_No ((uint16_t)0x0000) #define USART_Parity_Even ((uint16_t)0x0400) #define USART_Parity_Odd ((uint16_t)0x0600) #define IS_USART_PARITY(PARITY) (((PARITY) == USART_Parity_No) || \ ((PARITY) == USART_Parity_Even) || \ ((PARITY) == USART_Parity_Odd))


USART_StopBits-停止位参数有效性


/** @defgroup USART_Stop_Bits

  * @{

  */


#define USART_StopBits_1                     ((uint16_t)0x0000)

#define USART_StopBits_0_5                   ((uint16_t)0x1000)

#define USART_StopBits_2                     ((uint16_t)0x2000)

#define USART_StopBits_1_5                   ((uint16_t)0x3000)

#define IS_USART_STOPBITS(STOPBITS) (((STOPBITS) == USART_StopBits_1) || \

                                     ((STOPBITS) == USART_StopBits_0_5) || \

                                     ((STOPBITS) == USART_StopBits_2) || \

                                     ((STOPBITS) == USART_StopBits_1_5))


USART_WordLength-字长参数有效性


/** @defgroup USART_Word_Length

  * @{

  */






#define USART_WordLength_8b ((uint16_t)0x0000) #define USART_WordLength_9b ((uint16_t)0x1000) #define IS_USART_WORD_LENGTH(LENGTH) (((LENGTH) == USART_WordLength_8b) || \ ((LENGTH) == USART_WordLength_9b))


串口初始化代码:


USART_InitTypeDef     USART_InitStrue;


USART_InitStrue.USART_BaudRate=115200;                      //设置波特率-115200MHz

USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件流控制-不使用

USART_InitStrue.USART_Mode=USART_Mode_Rx| USART_Mode_Tx;    //使能设置-发送接收都使能

USART_InitStrue.USART_Parity=USART_Parity_No;               //奇偶校验-不使用奇偶校验

USART_InitStrue.USART_StopBits=USART_StopBits_1;            //停止位-一个停止位

USART_InitStrue.USART_WordLength=USART_WordLength_8b        //字长-8位字长


USART_Init(USART1, &USART_InitStrue);


4,使能串口1:


stm32f10x_usart.h头文件找到USART_Cmd函数定义


void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);

USART_Cmd(USART1, ENABLE);


5,由于使用了中断首先要配置中断优先级分组-在主函数


misc.h头文件中找到NVIC_PriorityGroupConfig函数声明:


void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

1

1

misc.c中找到NVIC_PriorityGroupConfig函数实现:


void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)

{

  /* Check the parameters */

  assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));


  /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */

  SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;

}


查看参数IS_NVIC_PRIORITY_GROUP有效性校验-misc.h


#define NVIC_PriorityGroup_0         ((uint32_t)0x700) /*!< 0 bits for pre-emption priority

                                                            4 bits for subpriority */

#define NVIC_PriorityGroup_1         ((uint32_t)0x600) /*!< 1 bits for pre-emption priority

                                                            3 bits for subpriority */

#define NVIC_PriorityGroup_2         ((uint32_t)0x500) /*!< 2 bits for pre-emption priority

                                                            2 bits for subpriority */

#define NVIC_PriorityGroup_3         ((uint32_t)0x400) /*!< 3 bits for pre-emption priority

                                                            1 bits for subpriority */

#define NVIC_PriorityGroup_4         ((uint32_t)0x300) /*!< 4 bits for pre-emption priority

                                                            0 bits for subpriority */


#define IS_NVIC_PRIORITY_GROUP(GROUP) (((GROUP) == NVIC_PriorityGroup_0) || \

                                       ((GROUP) == NVIC_PriorityGroup_1) || \

                                       ((GROUP) == NVIC_PriorityGroup_2) || \

                                       ((GROUP) == NVIC_PriorityGroup_3) || \

                                       ((GROUP) == NVIC_PriorityGroup_4))


中断分组配置代码:


//配置中断分组为2,即2位抢占优先级和2位响应优先级

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)


6,开启接收中断


stm32f10x_usart.h头文件中找到USART_ITConfig函数声明:


void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState);


stm32f10x_usart.c中找到USART_ITConfig函数实现:


void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)

{

  uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00;

  uint32_t usartxbase = 0x00;

  /* Check the parameters */

  assert_param(IS_USART_ALL_PERIPH(USARTx));

  assert_param(IS_USART_CONFIG_IT(USART_IT));

  assert_param(IS_FUNCTIONAL_STATE(NewState));

  /* The CTS interrupt is not available for UART4 and UART5 */

  if (USART_IT == USART_IT_CTS)

  {

    assert_param(IS_USART_123_PERIPH(USARTx));

  }


  usartxbase = (uint32_t)USARTx;


  /* Get the USART register index */

  usartreg = (((uint8_t)USART_IT) >> 0x05);


  /* Get the interrupt position */

  itpos = USART_IT & IT_Mask;

  itmask = (((uint32_t)0x01) << itpos);


  if (usartreg == 0x01) /* The IT is in CR1 register */

  {

    usartxbase += 0x0C;

  }

  else if (usartreg == 0x02) /* The IT is in CR2 register */

  {

    usartxbase += 0x10;

  }

  else /* The IT is in CR3 register */

  {

    usartxbase += 0x14;

  }

  if (NewState != DISABLE)

  {

    *(__IO uint32_t*)usartxbase  |= itmask;

  }

  else

  {

    *(__IO uint32_t*)usartxbase &= ~itmask;

  }

}


第二个参数USART_IT的有效性校验IS_USART_CONFIG_IT: 

stm32f10x_usart.h头文件找到IS_USART_CONFIG_IT声明:


#define USART_IT_PE                          ((uint16_t)0x0028)

#define USART_IT_TXE                         ((uint16_t)0x0727)

#define USART_IT_TC                          ((uint16_t)0x0626)

#define USART_IT_RXNE                        ((uint16_t)0x0525)

#define USART_IT_IDLE                        ((uint16_t)0x0424)

#define USART_IT_LBD                         ((uint16_t)0x0846)

#define USART_IT_CTS                         ((uint16_t)0x096A)

#define USART_IT_ERR                         ((uint16_t)0x0060)

#define USART_IT_ORE                         ((uint16_t)0x0360)

#define USART_IT_NE                          ((uint16_t)0x0260)

#define USART_IT_FE                          ((uint16_t)0x0160)

#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \

                               ((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \

                               ((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \

                               ((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR))


串口1初始化代码:


//打开串口1的接收中断,当串口1接收到数据时会触发此中断

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);


6,中断优先级的设置


初始化NVIC,设置中断的抢占优先级和响应优先级 

参考:NVIC


NVIC_InitTypeDef     NVIC_InitTypeStrue;


NVIC_InitTypeStrue.NVIC_IRQChannel=USART1_IRQn;    // 哪个通道-stm32f10x.h顶层头文件包含参数定义

NVIC_InitTypeStrue.NVIC_IRQChannelCmd=ENABLE;      // 是否开启中断通道-使能

NVIC_InitTypeStrue.NVIC_IRQChannelPreemptionPriority=1;     // 抢占优先级

NVIC_InitTypeStrue.NVIC_IRQChannelSubPriority=1;   // 响应优先级,子优先级


NVIC_Init(&NVIC_InitTypeStrue);


7,编写中断服务函数


格式: USARTx_IRQHandler();


在启动文件startup_stm32f10x_hd.s中找到串口123的中断服务函数

               DCD     USART1_IRQHandler          ; USART1

               DCD     USART2_IRQHandler          ; USART2

               DCD     USART3_IRQHandler          ; USART3


中断服务函数代码


void USART1_IRQHandler(void){

     u8 res;

     //判断中断类型

     //参数1:哪个串口  参数2:中断类型

     if(USART_GetITStatus(USART1, USART_IT_RXNE)){//接收数据中断

          res = USART_ReceiveData(USART1);//读取串口1接收到的数据

          //回发

          USART_SendData(USART1, res);

     }

}


八,串口程序完整代码


USER文件夹新建main.c函数:


#include "stm32f10x.h"


// 主函数

int main(void)

{   

    // 设置中断优先级分组位2 - 2位抢占2位相应

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);


    // 调用函数 初始化USART1相关引脚配置

    My_USART1_Init();


    while(1);

}


// 串口初始化函数

void My_USART1_Init(void)

{

    GPIO_InitTypeDef GPIO_InitStrue;

    USART_InitTypeDef USART_InitStrue;

    NVIC_InitTypeDef NVIC_InitStrue;


    // 1,使能GPIOA,USART1时钟

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);


    // 2,设置PGIO工作模式-PA9 PA10复用为串口1

    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP;

    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9;

    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;

    GPIO_Init(GPIOA,&GPIO_InitStrue);


    GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING;

    GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10;

    GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz;

    GPIO_Init(GPIOA,&GPIO_InitStrue);


    // 3,串口1初始化配置

    USART_InitStrue.USART_BaudRate=115200;

    USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

    USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;

    USART_InitStrue.USART_Parity=USART_Parity_No;

    USART_InitStrue.USART_StopBits=USART_StopBits_1;

    USART_InitStrue.USART_WordLength=USART_WordLength_8b;


    USART_Init(USART1,&USART_InitStrue);


    // 4,打开串口1

    USART_Cmd(USART1,ENABLE);


    // 5,使能串口1中断-接收数据完成中断

    USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);


    // 6,设置中断优先级-主函数中设置中断优先级分组

    NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn;

    NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE;

    NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=1;

    NVIC_InitStrue.NVIC_IRQChannelSubPriority=1;

    NVIC_Init(&NVIC_InitStrue);


}


// 中断服务函数

void USART1_IRQHandler(void)

{

    u8 res;

    if(USART_GetITStatus(USART1,USART_IT_RXNE))// 接收到数据

    {

        res= USART_ReceiveData(USART1); // 获得串口1接收到的数据

        USART_SendData(USART1,res);     // 通过串口1发送数据

    }

}


以上代码实现:

    电脑通过串口助手发送数据给单片机

    单片机接收数据进入接收数据串口中断

    读取DR寄存器中接收到的数据

    将接收到的数据再通过串口回写给电脑


(function () {(function () {('pre.prettyprint code').each(function () { var lines = (this).text().split(′\n′).length;var(this).text().split(′\n′).length;varnumbering = $('

').addClass('pre-numbering').hide(); (this).addClass(′has−numbering′).parent().append((this).addClass(′has−numbering′).parent().append(numbering); for (i = 1; i


关键字:STM32  USART 引用地址:STM32的USART讲解

上一篇:stm32功能严重异常的几个常见原因
下一篇:STM32 MDK常见错误与解决

推荐阅读

2018世界机器人大会上各种机器人的展示,让许多人相信,“家家都有机器人”的梦想在不久的将来也许真的能够照进现实。 行业热度不减市场份额扩大机器人的发展速度越来越超出人们的预期,不久前在北京举办的世界机器人大会上,所展示的各种机器人样品让人大开眼界。工业机器人、服务机器人、特种机器人,形状各异、功能多样。 大会展区内,一个会现场制作...
机器人,已经渐渐地进入到了我们的生活,虽说机器人在我国的很多行业中都有着应用,但大多数都是大型企业,很多的中小型企业都没有使用工业机器人进行生产。为了解决人工缺失的问题,有些工厂将生产线搬到了不发达的国家,来减低生产成本。造成这种局面的主要有这几个方面。 首先是工业机器人的成本高。现在应用的这些工业机器人,基本属于精密器件,需...
对叮当快药来说,无人配送车的意义不仅在于提升安全系数和效率,还在于有望持续降低配送成本。8月28日,叮当快药的首款无人配送车正式亮相北京海淀区永丰嘉园,引来群众驻足围观。据介绍,叮当快药的无人配送车采用红色外观设计搭配智能语音提示,设有12个储物柜;融合了激光雷达、超声波雷达、双目摄像头、智能导航、智能数控、智能温控、传感器、计算元件...
ISTOBAL中国首次在CIAACE展示其龙门式洗车机,旨在提高盈利能力并改善用户体验•适应中国市场的ISTOBAL M&#39;1 和 M&#39;START龙门式洗车机以其高水平的可靠性、灵活性、生产力和在 5 分钟内提供高效清洗能力而脱颖而出。•针对汽车经销商、加油站和洗美店,产品极具竞争力和可靠性,有能力每次洗涤回收高达 80% 的水。•将自身定位成技术合作伙伴...

史海拾趣

问答坊 | AI 解惑

arm linux驱动make发生的错误,大家帮忙看看

编的一个驱动,用的是2.6.22内核,交叉编译器是arm-linux-gcc 3.4.1。 下面是我的makefile文件: KERNELDIR :=/home/arm/linux-2.6.22.19 PWD :=$(shell pwd) CFLAGS =-D__KERNEL__ -DMODULE -I$(KERNELDIR)/include/ CROSS_COMPILE =/home/ar ...…

查看全部问答∨

问一个有关消息队列的问题

这几天做相关项目的测试,有个问题不解: 在vxworks环境下有两个任务A和B,B的优先级高 B接收消息并通过驱动函数转发出去,消息队列中最大消息个数为500个,添加了流量控制,每转发3包个则延迟1个tick 而测试任务A我设定每向B发送20个消息(一个 ...…

查看全部问答∨

avr或单片机可以运行wince操作系统吗

如题,如果可以怎么做,不可以请大家帮我推荐可以在那样的单片机里运行的操作系统,谢谢了…

查看全部问答∨

求大侠来给点指点。

  小弟马上要上手一个水文项目,具体就是做一个RTU设备,能够采集雨量水位等的信息,然后通过GPRS或是GSM方式发送到监控中心,监控中心也能发指令从RTU上取数据,RTU上要带键盘输入LCD的置数器,修改参数等。最好能将这个RTU扩展至很多的 ...…

查看全部问答∨

LPC2132 驱动ILI9320 TFT 程序问题

  这是一个TFT显示一幅红色图片的程序,但是在板上运行时,显示完一幅完整的图片要得差不多一个小时,不知道是什么原因, 请各位大侠 挥指知之间 指点指点 ..................不胜感激.     #include<LPC214X.h>//#include\ ...…

查看全部问答∨

求四川师范的LM3S 资料

以前在论坛上下一个LM3S的课件(应该是四川师范的课件) 感觉写的很好 但是现在电脑丢了 资料也没了。。。。。 现在急需 但是在论坛上找不到了。。。。。。。有谁知道在哪啊。。…

查看全部问答∨

求个单片机最小系统原理图和PCB图

&nbsp; 为了完成作业,需要设计一个单片机最小系统,想找个作为参考,不知道谁那儿有啊?可以分享一下,感激不尽!…

查看全部问答∨

跪求解释此硬件电路~~~~~

原文:由于轮椅控制器采用的是双极性模式,有四个功率管:T1、T2、T3、T4,其中 T1 和 T4 的 PWM 脉冲信号是相同的,T2 和 T3 的 PWM 脉冲是相同的,T1 与 T2 的 PWM 脉冲是互补的。而从 DSP 出来的只有一对互补的信号,因此利用 CD74ACT157 再复制 ...…

查看全部问答∨

理解模拟电路:有源器件

本帖最后由 dontium 于 2015-1-23 12:42 编辑 这也是TI的,文章中说了几种有源器件:晶体管、JFET、MOSFET、运放、比较器等的特性 …

查看全部问答∨

TI 的LED 驱动器应用中升压转换器的简单开路保护

给大家转发一篇TI 工程师关于LED驱动的升压模块转换器的使用电路,,很值得一看,,, 作者:John Caldwell,德州仪器 (TI) 模拟应用工程师 Gregory Amidon,德州仪器 (TI) 模拟应用工程师 引言 驱动高亮度 LED 的一种方法是对标准升压转换器拓 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved