串口是我们调试硬件经常用到的一个外设,本设计所采用的接口芯片为SP3485,芯片的使用方法就不多说了,大家可以自己看芯片手册.
下面贴出usart的驱动程序
/*
* Author :固桐
* History
* --------------------
* Rev : 0.00
* Date : 01/06/2013
*
* create.
* --------------------
*/
//-----------------Include files-------------------------//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <stdarg.h>
#include "stm32f4xx.h"
#include "..\include\usart.h"
#include "..\include\hardware.h"
//-----------------Variable------------------------------//
static int send_string_to_usart2(char * str);
static int send_byte_to_usart2(char data);
static int initialize_usart2(int baudrate);
static int my_printf_uart2(const char * fmt, ...);
//-----------------function------------------------------//
static int initialize_usart2(int baudrate)
{
float temp;
u16 mantissa;
u16 fraction;
RCC->AHB1ENR |= 0x00000001; //open A clock
RCC->APB1ENR &= 0xFFFDFFFF;
RCC->APB1ENR |= 0x00020000;//open usart2 clock
GPIOA->MODER &= 0xFFFFFF0F; //
GPIOA->MODER |= 0x000000A0;
GPIOA->OSPEEDR &= 0xFFFFFFCF; //
GPIOA->OSPEEDR |= 0x00000020;
GPIOA->PUPDR &= 0xFFFFFFCF; //
GPIOA->PUPDR |= 0x00000010;
GPIOA->MODER &= 0xFFFFFFF3; //Configure RS485 DIR(PA.1)
GPIOA->MODER |= 0x00000004;
GPIOA->OTYPER &= 0x0000FFFD;
GPIOA->PUPDR &= 0xFFFFFFF3;
GPIOA->PUPDR |= 0x00000004;
GPIOA->OSPEEDR &= 0xFFFFFFF3;
GPIOA->OSPEEDR |= 0x00000008;
GPIOA->AFR[0] |= 0x00007700; //Configure (PA.2)(PA.3)
temp = 42000000/ (16 * baudrate); //串口使用APB1= 1/4CPU CLK=42M;
temp=(float)(42*1000000)/(baudrate*16);//得到USARTDIV
mantissa=floor(temp); //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
USART2->BRR = mantissa;
//-----------------相应的寄存器操作,参考RM0090数据手册------------------------------//
USART2->CR1 &=~((1<<12) | (1<<10) );//0
USART2->CR1 |= ((1<<3) | (1<<2) | (1<<8) | (1<<5)| (1<<13));//1
USART2->CR2 &=~((1<<13)| (1<<12) | (1<<11)| (1<<10)| (1<<8) );
USART2->CR2 |=(1<<9) ;
USART2->CR3 &=~((1<<8)| (1<<9));
RS485_R; //485芯片处于接收状态
return 0;
}
//-----------------发送字符------------------------------//
static int
send_byte_to_usart2(char data)
{
RS485_T;
USART2->DR= data;
while (!(USART2->SR & 0x00000040 )) ;
RS485_R;
return 0;
}
//-----------------发送字符串------------------------------//
static int
send_string_to_usart2(char * str)
{
RS485_T;
while (*str != '\0') {
while (!((USART2->SR) & 0x00000040 )) ;
USART2->DR = (*str++);
}
while (!(USART2->SR & 0x00000040 )) ;
RS485_R;
return 0;
}
//-----------------中断接收------------------------------//
int
USART2_IRQHandler(void)
{
while (!(USART2->SR & 0x00000020 )) ;
usart2.receive_buffer[usart2.receive_count++] = USART2->DR;
if (usart2.receive_buffer[usart2.receive_count - 1] == '\n') {
usart2.receive_buffer[usart2.receive_count - 1] = 0;
usart2.receive_count = 0;
usart2.receive_ok_flag = 1;
}
return 0;
}
static int
my_printf_uart2(const char * fmt, ...)
{
va_list arg_ptr;
char buf[BUFFER_SIZE];
memset(buf, '\0', sizeof(buf));
va_start(arg_ptr, fmt);
vsprintf(buf, fmt, arg_ptr);
va_end(arg_ptr);
send_string_to_usart2(buf);
return 0;
}
|