2019년 11월 12일

 

A, USART 소개

  동기 범용 비동기 수신기 전송기 (USART)는 산업 표준 NRZ 외부 장치 비동기 직렬 데이터 포맷 사이의 양방향 데이터 교환을 사용하는 유연한 방법을 제공한다. USART 선택의 넓은 범위를 제공 발전기 분수 전송 속도를 보드 (baud).

  아주 풍부한 자원의 STM32 무리, 매우 강력한 기능. STM32F103ZET6는 LIN (로컬 인터넷), 스마트 카드 프로토콜과의 IrDA (적외선 데이터 협회 (Infrared Data Association)) SIR ENDEC 사양과 모뎀을 지원, 분수 전송 속도 발생기, 단방향 통신과 반이중 동기 단일 유선 통신을 지원해야, 5 개 시리얼 포트를 제공합니다 (CTS / RTS) 동작. 또한 멀티 프로세서 통신을 허용한다. DMA는, 다중 모드 구성을 사용하여 버퍼 고속의 데이터 통신을 달성 할 수있다.

두, USART 기능 개요

  세 핀은 다른 장치와의 인터페이스에 의해 서로 연결된다. 데이터 입력 (RX) 및 송신 데이터 출력 (TX)를 수신 : 모든 USART 양방향 통신은 적어도 두 개의 다리가 필요하다.
  RX는 : 직렬 데이터 입력을 수신하는 단계. 데이터를 복구하는 기술을 오버 샘플링하여 데이터 및 소음을 구별합니다.
  TX : 송신 데이터 출력. 송신기가 디스 에이블 될 때, 출력 단자는 I / O 포트 구성으로 복원된다. 송신기가 활성화되고, 데이터가 전송되지 않는 경우, TX 핀이 높다. 그리고 인라인 스마트 카드 모드는,이 I / O 포트를 전송하고 데이터를 수신 모두에 사용됩니다.

  직렬 주변기기는 주로 세 개의 부분, 즉, 전송 속도 제어부, 및 송신으로 구성 및 제어 데이터 저장 부 반송 부를 수신한다.

  1, 전송 속도 제어

  전송 속도, 즉, 전송 속도를 변경할 수있는 시계를 제어하여 표시되는 B / s (초당 비트)와, 초당 전송되는 비트의 수. 전송 속도를 구성 할 때, 우리는 등록 시리얼 클럭 디바이더 값 USARTDIV를 수정할 수있는 전송 속도 쓰기 매개 변수를 USART_BRR. USART_BRR 레지스터는 두 부분, 즉 DIV_Mantissa (USARTDIV 정수부) 및 DIVFraction 구성 (USARTDIV 부분) 부분, 결국, 다음과 같이 계산된다 :

      USARTDIV DIV_Mantissa = + (DIVFraction / 16).

  도 2를 참조하면, 전송 속도의 일부분을 생성

  정수 및 분수 USARTDIV 레지스터의 수신기 및 송신기의 전송 속도의 값이 동일하게 설정되어야한다.
    송 / 수신 전송 속도 = FCK / (16 * USARTDIV)

  FCK 여기 USARTDIV 부호없는 고정 소수점 수있다 (USART2,3,4,5, USART1위한 PCLK2위한 PCLK1) 주변 시계이다. USART_BRR 설정이 12 비트 레지스터 값.

  참고 : USART_BRR를 작성 후, 전송 속도 카운터 레지스터가 새로운 값으로 대체되는 속도 전송. 따라서, 전송 속도는 통신 레지스터의 값을 변경하지 않는다.

  이 APB2 버스의 클럭 소스 fPCLK2에 장착되어 있기 때문에,위한 USART1 주파수 분할 직렬 클록 소스 USARTDIV 주변이고, 상기 APB1 USART2,3에 장착 클럭 소스이었다 fPCLK1는 분배기를 통해 USARTDIV 직렬 클록 소스를 수신하는 송신기 클럭과 수신기 클럭과 송신 타이밍 제어를 출력한다. 

  (3) 송신 및 수신 제어

  CR1, CR2, CR3, SR, 즉 세 USART 제어 레지스터 (제어 레지스터) 및 상태 레지스터 (상태 레지스터) : 송신기와 수신 제어부, 레지스터 번호 좋은 주변. 상기 USART 인터럽트를 제어하는, 등의 패리티 비트, 스톱 비트와 같은 다양한 제어 파라미터, 컨트롤 송수신에 기록하여 레지스터, 상태 레지스터가 언제 조회 할 수로부터 직렬 상태가 얻어진다. 특정 제어 및 상태 확인 우리 달성 라이브러리 함수를 사용하고, 이것은 이들 레지스터 비트의 상세한 분석이 아니다.

  저장 부 (4), 전송 데이터

  우리 트랜시버 제어기 구성 레지스터에 따르면, 시프트 데이터 전송 수단은 제어 레지스터에 저장.

  우리는 전송 데이터를 메모리 (변수)에서 데이터를 기록 (다음 장에서의 데이터 전송 모드) 데이터 또는 핵심 DMA 주변을 전송해야하는 경우, 전송 컨트롤러가 자동으로 적시에 데이터에서 TDR 등록 TDR이 상기 전송 시프트 레지스터에로드되고, 그 후 직렬 회선 송신을 통해, 데이터는 비트 단위를 보낼 때, 데이터는 시프트 레지스터의 TDR로부터 전송되는, 전송 레지스터 빈 TDR TXE의 이벤트 발생 때 시프트의 데이터 발송 모든 레지스터는, 이러한 이벤트는 상태 레지스터를 확인하실 수 있습니다, 데이터 완료 이벤트 TC를 전송해야합니다.

  데이터는 역방향 프로세스는 수신 회선 수신 직렬 시프트 레지스터에서 비트에 의해 데이터 입력 비트이며, 자동으로 데이터를 레지스터에 전송 받는다 메모리 또는 DMA 코어 명령 (가변)로 최종 자세히 더불어 RDR 수신 .

셋째, 직렬 포트 설정

  IO 기능을 다중화, 먼저 GPIO 클럭을 활성화 GPIO 모드 보레이트, 스톱 비트를 포함하는, 직렬 포트 초기화 파라미터를 상기 다중화 기능에 대응하는 모드로 설정 설정해야하면서 시계 기능을 다중화 가능 등의 매개 변수를 설정합니다. 직렬 포트를 설정 한 후 사용할 수 있습니다. 동시에, 당신은 인터럽트 서비스 루틴을 작성하는 마지막 물론, 직렬 포트 인터럽트를 열 NVIC는 인터럽트 우선 순위를 설정 초기화하고, 경우.

  직렬 일반적 절차 세트는 다음 단계로 요약 될 수있다 :

    1) 직렬 클럭 GPIO 클럭 인 에이블 활성화

    2) 직렬 재설정

    3) GPIO 포트 모드

    4) 직렬 포트 파라미터를 초기화

    5) 인터럽트를 활성화하고 NVIC를 초기화 (중단 활성화 된 경우에만이 단계가 필요합니다)

    6) 직렬 포트를 활성화

    7) 인터럽트 핸들러를 작성

  여러 펌웨어 라이브러리 함수를 직접 시리얼 포트의 기본 구성과 관련된. 이 기능을 주로 stm32f10x_usart.h 및 stm32f10x_usart.c 파일에 정의.

  1 직렬 클록 활성화.

  (가) 기능 활성화 아래 직렬 인터페이스는 상기 주변 APB2 장착되어
    RCC_APB2PeriphClockCmd (RCC_APB2Periph_USART1)를;

  2 리셋 포트.

  예외가 리셋 주연의 리셋에 의해 제공된 상기 주변에서 발생하고, 경우 다음 재 작업을 위해 허용 주변 재구성. 시스템 구성 주연 시작되면 일반적 주연 리셋 제 1 동작을 수행한다. 리셋은의 기능 USART_DeInit ()로 수행됩니다
    무효 USART_DeInit (USART_TypeDef * USARTx); // 리셋 포트

  예를 들어, 포트 1에있어서 재설정 :
    USART_DeInit합니다 (USART1)을 // 리셋 포트 1

  3, 시리얼 포트 초기화 변수.

  USART_Init 직렬 포트 초기화 함수 ()에 의해 달성된다
    공극 USART_Init (USART_TypeDef * USARTx, USART_InitTypeDef USART_InitStruct *);

  이 함수의 첫 번째 항목 매개 변수가 지정된 일련 번호를 초기화, USART1을 선택합니다. 두번째 매개 변수는 USART_InitTypeDef 입구 구조 포인터 타입, 시리얼 포트의 파라미터를 설정하기 위해이 구조 포인터 멤버 변수이다. 일반 구현 형식 :

1 USART_InitStructure.USART_BaudRate는 바인딩 = // 일반적으로 9600로 설정, 
2 = USART_InitStructure.USART_WordLength USART_WordLength_8b // 8 비트 워드 길이의 데이터 포맷을 
3 USART_InitStructure.USART_StopBits = USART_StopBits_1 // 정지 비트 
4 USART_InitStructure.USART_Parity = USART_Parity_No / / 패리티 비트 
5 USART_InitStructure.USART_HardwareFlowControl. 
6 = USART_HardwareFlowControl_None //없이 하드웨어 흐름 제어. 
7 USART_InitStructure.USART_Mode USART_Mode_Rx = | USART_Mode_Tx // 송수신기 모드 
8 USART_Init (USART1, USART_InitStructure) ; //는 시리얼 포트를 초기화하지

  전송 속도, 단어 길이, 정지 비트, 패리티 비트, 하드웨어 흐름 제어 모드 (송수신) 위의이 포맷 초기화 초기화를 알 수에서 파라미터는 설정 될 필요가있다. 우리는 이러한 매개 변수를 설정할 수 있습니다.

  도 4는 데이터 송수신.

  STM32 송수신은 이중 USART_DR 레지스터를 레지스터 데이터를 통해 달성 된 TDR과 RDR 포함된다. 데이터는이 레지스터에 기록되는 경우, 직렬 포트를 자동으로 데이터가 수신되면, 전송되며, 또한, 레지스터 내에 존재한다.

  함수 라이브러리 함수 STM32 송신 데이터 레지스터 동작 USART_DR이다
    공극 USART_SendData (USART_TypeDef * USARTx, 데이터는 uint16_t)
  USART_DR 기능을 통해 직렬 레지스터에 데이터를 기록한다.

  STM32 라이브러리 함수 USART_DR 상기 수신 직렬 데이터 판독 동작 레지스터의 함수이다 :
    USART_ReceiveData (USART_TypeDef * USARTx) uint16_t,
  직렬 수신 된 데이터가이 방법으로 판독 할 수있다.

  5, 포트 상태.

   직렬 상태는 상태 레지스터 USART_SR 통해 판독 될 수있다. USART_SR 모두 설명 그림 1 :

 

레지스터 비트의도 1 USART_SR 정보

  두 비트, 5, 6 위 RXNE 및 TC 봐.

  RxNE (판독 데이터가 비어 있지 않은 레지스터)이 비트는 그 데이터를 수신 시사 1로 설정하고, 판독 할 수있는 경우. 우리가해야 할이 시간이 곧 USART_DR를 읽을 가능한 한이다,이 비트가 USART_DR를 읽어 해제 할 수 있습니다, 당신은 또한이 비트, 직접 제거에 0을 쓸 수 있습니다.

  송신 된 데이터가 나타내는 USART_DR 완료된 때 비트가 설정 TC (송신 완료). 당신이 인터럽트 비트를 설정하면 인터럽트를 생성합니다. 1) USART_SR 읽기, 쓰기 USART_DR :이 비트는 두 가지 방법이 있습니다, 삭제됩니다. 2) 직접 작성 0.

  내부에 우리의 펌웨어 라이브러리 함수에서 읽기, 시리얼 상태 기능은 다음과 같습니다
    FlagStatus USART_GetFlagStatus (USART_FLAG uint16_t USART_TypeDef * USARTx,);

  두 번째 항목이 기능에 중요한 파라미터이며, 이러한 RxNE 상술 한 바와 같이 직렬 인터페이스 (판독 데이터가 비어 있지 등록) 된 상태를 나타내는 표시, 및 TC (송신 완료)된다. 예를 들어, 읽기 레지스터 (RXNE) 비우 여부 라이브러리 함수의 동작 방법 판단하기 :
    USART_GetFlagStatus합니다 (USART1, USART_FLAG_RXNE을);

  도서관 기능을 동작시키는 방법인지 여부 송신 (T 최종 C)를 결정하는 방법 :

    USART_GetFlagStatus (USART1, USART_FLAG_TC);

  매크로 정의에 의해 정의되는이 MDK 식별 번호 :

1 #DEFINE USART_IT_PE ((uint16_t) 0x0028) 
 2 #DEFINE USART_IT_TXE ((uint16_t) 0x0727) 
 3 #DEFINE USART_IT_TC ((uint16_t) 0x0626) 
 4 #DEFINE USART_IT_RXNE ((uint16_t) 0x0525) 
 5 #DEFINE USART_IT_IDLE ((uint16_t) 0x0424) 
 6 #DEFINE USART_IT_LBD ((uint16_t) 0x0846) 
 7 #DEFINE USART_IT_CTS ((uint16_t) 0x096A) 
 8 #DEFINE USART_IT_ERR ((uint16_t) 0x0060) 
 9 #DEFINE USART_IT_ORE ((uint16_t) 0x0360) 
10 #DEFINE USART_IT_NE ((uint16_t) 0x0260) 
11 #DEFINE USART_IT_FE ((uint16_t) 0x0160)

  6, 직렬 포트를 사용할 수있는 것입니다.

  직렬 포트가 활성화 () 함수에있어서, 사용이 용이하게 이해되고, USART_Cmd 의해 달성된다 :

    USART_Cmd (USART1는 ENABLE); // 시리얼 가능 

  도 7은 직렬 포트 인터럽트 응답을 연다.

  직렬 포트 인터럽트를 여는 데 필요한 때로는 때, 당신은 또한 직렬 포트 인터럽트를 활성화해야합니다, 인터럽트는 직렬 포트의 함수이다 :
    무효 USART_ITConfig (USART_IT, uint16_t USART_TypeDef * USARTx,
                             FunctionalState NewState)
  이 함수의 두 번째 입력 매개 변수를 사용 표지 활성화 된 인터럽트 시리얼 종류, 많은 종류가 있기 때문에 인터럽트 직렬 포트. 예를 들어, 인터럽트 다음 인터럽트가 온 방법 생성하기 위해 상기 수신 된 데이터를 (RxNE 데이터가 비어 있지 않은 레지스터 읽기)
    USART_ITConfig합니다 (USART1, USART_IT_RXNE 상기는 ENABLE)를 // 인터럽트를 인 에이블 인터럽트 데이터를 수신

  전송 데이터의 끝에서 인터럽트를 생성 (TC가 전송이 완료 될 때), 상기 방법은 :
    USART_ITConfig합니다 (USART1, USART_IT_TC가 활성화);

  도 8은, 해당하는 인터럽트 상태를 얻었다. 인터럽트가 발생했을 때 우리가 인터럽트를 사용할 때, 상태 레지스터에 플래그를 설정합니다. 우리는 종종, 인터럽트는 인터럽트를 사용하는 함수를 결정하는 인터럽트 핸들러 :
    (USART_IT uint16_t USART_TypeDef * USARTx) ITStatus USART_GetITStatus;

  인터럽트가 발생하면, 예를 들어, 전체 인터럽트를 전송하기 위해 직렬 포트를 활성화 한 후, 사용자는 단부에있어서 인터럽트 직렬 송신 완료인지의 여부를 판정하는 인터럽트 핸들러에이 함수를 호출 할 수
    USART_GetITStatus합니다 (USART1, USART_IT_TC);

  반환 값은 명령이 완료 직렬 포트 인터럽트가 발생하고, SET입니다.

넷 uart_init () 함수

  다음과 같이 소개 uart_init 기능은 어떤 코드입니다 :

// 초기화 GPIO와 시리얼 포트 1 
 @ 2 바인딩 : 보 
 . 3 보이드 uart_init (U32 바인딩) 
 . (4) { 
 . 5 GPIO_InitTypeDef GPIO_InitStructure] 
 . 6 USART_InitTypeDef USART_InitStructure] 
 . 7 NVIC_InitTypeDef NVIC_InitStructure] 
 . 8 ① // 직렬 클럭 인 에이블 클럭 GPIO를 사용 클럭 인 에이블 멀티플렉싱 
 . 9 RCC_APB2PeriphClockCmd (RCC_APB2Periph_USART1 | 
10 RCC_APB2Periph_GPIOA 상기 활성화); // USART1, GPIOA 클럭 인 에이블 
(11) // ② 리셋 포트 
12 USART_DeInit (USART1) // 리셋 포트 1. 
13 인 ③GPIO 포트 모드 // 
14 = GPIO_Pin_9 GPIO_InitStructure.GPIO_Pin // ISART1_TX PA.9 
15 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
16 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP // 푸시 풀 출력 다중화
17 GPIO_Init (GPIOA, GPIO_InitStructure) ; // 초기화 GPIOA.9 
27 = USART_HardwareFlowControl_None // 어떤 하드웨어 흐름 제어되지
GPIO_InitStructure.GPIO_Pin GPIO_Pin_10 = 18; // USART1_RX PA.10 
19 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING]. // 입력 부동 
20 GPIO_Init (GPIOA, GPIO_InitStructure는) // 초기화 GPIOA.10 
21 ④ // 초기화 직렬 포트 파라미터 
22 USART_InitStructure.USART_BaudRate = 바인딩 // 설정된 전송률 
23 USART_InitStructure.USART_WordLength = USART_WordLength_8b // 워드 길이가 8 비트 인 
24 USART_InitStructure.USART_StopBits = USART_StopBits_1, 정지 비트 // 
25 USART_InitStructure.USART_Parity = USART_Parity_No // 패리티 
26 USART_InitStructure.USART_HardwareFlowControl 
29 USART_Init (USART1, USART_InitStructure) ; //는 시리얼 포트를 초기화
28 USART_InitStructure.USART_Mode USART_Mode_Rx = | USART_Mode_Tx // 모드 트랜시버 
(30)의 #if EN_USART1_RX // 활성화 된 경우, 수신기 
(31) // ⑤ NVIC 초기화 
32 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 
33 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3이 // 선점 우선 순위 (3) 
34 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 하위 우선 순위 3. 
35 = NVIC_InitStructure.NVIC_IRQChannelCmd 에이블 // IRQ가 채널 활성화 
36 NVIC_Init (NVIC_InitStructure) // 인터럽트 우선 순위 레벨을 초기화를 
37 // ⑤ 인터럽트를 활성화 
38 USART_ITConfig (USART1, USART_IT_RXNE // 인터럽트를 인 에이블) 활성화 
#endif 다음 39 
40 // 있도록 직렬 ⑥ 
), 41 USART_Cmd (USART1을 에이블 //는 시리얼 포트를 인 에이블 
(42)}                    

  마찬가지로 우리의 이전에 설명과 일치하는 프로세스의 시리얼 포트를 초기화 코드에서 볼 수 있습니다. 우리는 순서를 표시 번호 ① ~ ⑥을 사용합니다 :

    ① 시리얼 클럭 활성화, GPIO 시계 활성화
    ② 시리얼 리셋
    ③ GPIO 포트 모드
    ④ 포트 초기화 매개 변수를
    NVIC에게 ⑤ 초기화 및 인터럽트 활성화
    시리얼을 가능 ⑥

다섯째,  

  1, 전이중 시리얼 포트를 구성 1

    TX (PA9) 핀은 푸쉬 - 풀 출력 다중화로 구성하는 단계;

    입력 또는 당겨 입력 핀을 플로팅 RX (PA10).

  모드 구성 표 1은 다음을 참조하십시오 :

표 1 모드 GPIO 포트 설정 테이블

  2, 참고는 EN_USART1_RX 1 usart.h 설정해야합니다 인터럽트 수신, 직렬 포트를 사용하는 경우 있음 (기본 설정은 1입니다). 이 기능을 활성화 인터럽트를 구성하고, 시리얼 포트 1 NVIC 인터럽트를 엽니 다. 2 군 여기서 직렬 인터럽트 포트 1은 가장 낮은 우선 순위 그룹 (2)는 내부에 설정되어있다.

  그런 다음 인터럽트 서비스 루틴을 작성해야합니다. USART1_IRQHandler 1의 시리얼 인터럽트 서비스 루틴.

  다음 두 문장에서 3 초점 모습 미안 () 함수 :

    USART_SendData (USART1, USART_RX_BUF [t]는 ) // 시리얼 포트로 송신 한 데이터.
    그동안 (USART_GetFlagStatus합니다 (USART1, USART_FLAG_TC) 세트! =)를;

  첫 번째 문장 사실, 직렬 포트에 바이트를 전송하는 것입니다. 두 번째 문장은, 즉, 우리는 데이터가 완료 보냈습니다 여부를 감지하는 후 직렬 포트에 우리의 데이터를 전송합니다. USART_FLAG_TC 데이터 전송 매크로 정의 식별자를 종료한다.


추천

출처www.cnblogs.com/dpc666/p/11844636.html