最近要驱动了SIM800L发现自己用的程序好乱,今天写个死的
#include "USART.h"
#include "stdio.h"
#include "string.h"
#include "delay.h"
/**
*@function:把串口接收到的数据都存在USART_RX_BUF[]中,把它定义成为全局变量以供使用
* 另外,接收完成之后,USART1_RX_STA的第15位还是1的状态,使用完数据记得清零
* 不然无法进行第二次接收
*/
/**用库函数配置优先级,最近喜欢库函数和寄存器两种混着用
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
*/
u8 USART1_RX_BUF[USART1_Receive_Len];//一个字节长度类型的数组
u16 USART1_RX_STA=0; //接收状态标记
void GenralUSART_Init(int pclk2,int bound)
{
float temp;
u16 mantissa;//存放波特率的整数部分
u16 fraction;//存放波特率的小数部分
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分
mantissa<<=4;
mantissa+=fraction;
RCC->APB2ENR|=1<<2; //使能PORTA口时钟
RCC->APB2ENR|=1<<14; //使能串口时钟
GPIOA->CRH&=0XFFFFF00F;//IO状态设置PA9PA10
GPIOA->CRH|=0X000008B0;//IO状态设置
RCC->APB2RSTR|=1<<14; //复位串口1
RCC->APB2RSTR&=~(1<<14);//停止复位
//波特率设置
USART1->BRR=mantissa; // 波特率设置
USART1->CR1|=0X200C; //1位停止,无校验位.
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART1_IRQn,2);//组2,最低优先级
}
/*通过串口发送一个字符串*/
void SendStrToUSART1(u8* str)
{
int i,j;
i=strlen((const char*)str);
for(j=0;j<i;j++)
{
USART1->DR=str[j];
while(((USART1->SR)&(1<<6))==0);//等待发送完成
}
}
/*查看USART接收的数据是否含有自己的字符串*/
u8* USART_Check_CMD(u8* str)
{
char* Rstr=0;
if(USART1_RX_STA&0x8000)//接受到一个串数据,第15位在接收完成一个以
结尾的字符串后才会被置一
{
USART1_RX_BUF[USART1_RX_STA&0X7FFF]=0;//添加结束符,这里没看明白
Rstr=strstr((const char*)USART1_RX_BUF,(const char*)str);
}
return (u8*)Rstr;
}
/**
*@par:cmd:发送的命令
* ack:期望的响应
* waittime:超时时间,n*10ms
*@ret:0成功 1失败
*/
u8 USART_Send_CMD(u8* cmd,u8* ack,u16 waittime)
{
USART1_RX_STA=0;
SendStrToUSART1(cmd);
if(waittime&&ack)
{
while(--waittime)
{
delay_ms(10);
if(USART1_RX_STA&0x8000)//接受到数据
{
if(USART_Check_CMD(ack))
{
//接收到对应的响应,跳出while循环
break;
}
//接收到数据后清除状态位
USART1_RX_STA=0;
}
if(waittime==0)return 1;//到时间未得到响应
}
}
return 0;
}
/**
*@function:一次中断处理一个字节数据
*@Attention:0x0d:/r 0x0a:/n
*/
void USART1_IRQHandler(void)
{
u8 res;
if(USART1->SR&(1<<5)) //接收寄存器非空
{
res=USART1->DR;//取出数据寄存器的一个字节的数据
if((USART1_RX_STA&0x8000)==0)//接收未完成
{
if(USART1_RX_STA&0x4000)//如果接收到/r,那么如果数据没有错误现在接收到的应该是/n
{
if(res!=0x0a)USART1_RX_STA=0;//如果接收到的不是/n,那就表示接收错误,重新开始
else USART1_RX_STA|=0x8000; //如果是,则表示接收完成了
}else //还没收到/r
{
if(res==0x0d)USART1_RX_STA|=1<<14;//标记已经接收到/r,此时随后又执行一次接收数据,即接收/n
else
{
USART1_RX_BUF[USART1_RX_STA&0X3FFF]=res;//USART_RX_STA&0X3FFF表示数据长度
USART1_RX_STA++;//数据长度+1
if(USART1_RX_STA>(USART1_Receive_Len-1))USART1_RX_STA=0;//数据长度大于定义的最大接收长度,接收数据错误,重新开始接收
}
}
}
}
}
/************************printf()函数*************************************/
struct __FILE
{
int handle;
/* Whatever you require here. If the only file you are using is */
/* standard output using printf() for debugging, no file handling */
/* is required. */
};
///* FILE is typedef’ d in stdio.h. */
FILE __stdout;
//重定向fputc函数
//printf的输出,指向fputc,由fputc输出到串口
//这里使用串口1(USART1)输出printf信息
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//等待上一次串口数据发送完成
USART1->DR = (u8) ch; //写DR,串口1将发送数据
return ch;
}
/************************printf()函数*************************************/