|
#include "uart.h"
**********************************************************************
函數(shù)功能:uart初始化函數(shù)
函數(shù)形參:baud 波特率void Uart1_Init(u32 baud)//9600
{
double USARTDIV = 0.0;
u32 DIV_MAN = 0;//保存整數(shù)
u32 DIV_FRA = 0;//保存小數(shù)
//1. 配置GPIO口 PA9 和 PA10
RCC->AHB1ENR |= (0x1 << 0);//(1)打開GPIOA的時(shí)鐘
GPIOA->MODER &= ~(0xf << 18);
GPIOA->MODER |= (0xa << 18);//(2)配置PA9和PA10的端口模式(復(fù)用功能)
GPIOA->AFR[1] &= ~(0xff << 4);
GPIOA->AFR[1] |= (0x77 << 4);//(3)將PA9和PA10復(fù)用給UART1
//2. 配置uart1 (四要素)
RCC->APB2ENR |= (0x1 << 4);//(1)打開USART1的時(shí)鐘
//(2)配置CR1寄存器(數(shù)據(jù)位、校驗(yàn)位)
USART1->CR1 = 0;//整體清零 有些配置就是希望它是0
USART1->CR1 |= (0x1 << 2);//使能接收器
USART1->CR1 |= (0x1 << 3);//使能發(fā)送器
/*
16 倍過采樣
1 起始位, 8 數(shù)據(jù)位, n 停止位
禁止奇偶校驗(yàn)控制(無)
*/
USART1->CR2 &= ~(0x3 << 12);//(3)配置CR2寄存器(1個(gè)停止位)
//(4)配置波特率(求USARTDIV,再把USARTDIV的值寫到BRR)
USARTDIV = 84000000.0 / baud / 16;//546.875
DIV_MAN = USARTDIV;//得到了整數(shù)
DIV_FRA = (USARTDIV - DIV_MAN) * 16 + 0.5;//0.5四舍五入
USART1->BRR = DIV_MAN << 4 | DIV_FRA;//將整數(shù)和小數(shù)寫入相應(yīng)的位
//設(shè)置usart1的中斷優(yōu)先級(jí)
NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(7-2, 1, 1));
//是NIVC響應(yīng)USART1中斷
NVIC_EnableIRQ(USART1_IRQn);
//使能模塊中斷
USART1->CR1 |= (0x1 << 5);//使能usart1的接收中斷
USART1->CR1 |= (0x1 << 13);//(5)使能USART1
}
//全局變量 系統(tǒng)默認(rèn)會(huì)幫他們進(jìn)行初始化為0
u8 rev_buf[50];
u8 rev_ok;
u32 rev_time;
u8 rev_start;
u8 rev_i;
//編寫usart1的中斷服務(wù)函數(shù) NVIC根據(jù)標(biāo)志位搶CPU的
//只要usart1接收到數(shù)據(jù),SR寄存器的第五位就會(huì)置起來
//只要SR寄存器的第五位置起來,NVIC就將CPU拉倒這個(gè)中斷服務(wù)函數(shù)里面來
void USART1_IRQHandler(void)//公共入口
{
// u8 ret = 0;
if(USART1->SR & (0x1 << 5))//接收中斷標(biāo)志
{
rev_buf[rev_i] = USART1->DR;//讀取DR寄存器清接收中斷標(biāo)志
rev_i++;
rev_start = 1;
rev_time = 0;
//printf("%c", ret);
}
}
/*
**********************************************************************
函數(shù)功能:uart1發(fā)送字符串函數(shù)
函數(shù)形參:字符串首地址
函數(shù)返回值:None
備注:字符串以'\0'結(jié)尾
日期:2020年3月6日
作者
版本:V0.0
**********************************************************************
*/
void Uart1_Send_String(u8 *p)
{
while(*p != '\0')
{
while( !(USART1->SR & (0x1 << 7)) );//等待發(fā)送緩沖區(qū)為空 標(biāo)志位為1,核心就在這里等
USART1->DR = *p;
p++;
}
}
/*
**********************************************************************
函數(shù)功能:uart1接收字符串函數(shù)
函數(shù)形參:None
函數(shù)返回值:None
備注:字符串以'\0'結(jié)尾 超時(shí)接收。 如果
日期:2020年3月14日
作者
版本:V0.0
**********************************************************************
*/
void Uart_Revcie_String(void)//LED_ON
{
if(rev_time > 200 ) //定時(shí)器中斷10us一次 若rev_time > 100 說明1ms沒接收到數(shù)據(jù)
{
if(rev_buf[rev_i-1] == '#')
{
rev_buf[rev_i-1] = '\0';
}
else if(rev_buf[rev_i-1] == '\n')
{
rev_buf[rev_i-2] = '\0';
}
else
{
rev_buf[rev_i] = '\0'; //即沒有接收到 # 也沒有接收到\r\n 超時(shí)接收到字符串
}
rev_i = 0;
rev_start = 0;
rev_time = 0;
rev_ok = 1; //接收完成標(biāo)志
}
}
#pragma import(__use_no_semihosting_swi) //取消半主機(jī)狀態(tài)
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
int fputc(int ch, FILE *f) {
while((USART1->SR &(0X01<<7))==0);//等待發(fā)送緩沖區(qū)為空
USART1->DR=ch;
return (ch);
}
int ferror(FILE *f) {
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch) {
while((USART1->SR &(0X01<<7))==0);
USART1->DR=ch;
}
void _sys_exit(int return_code) {
label: goto label; /* endless loop */
}
|
|