高级会员

- 积分
- 598
- 金钱
- 598
- 注册时间
- 2014-4-14
- 在线时间
- 76 小时
|
发表于 2016-7-18 11:05:51
|
显示全部楼层
你边接收边处理数据,那肯定处理不过来啊!!处理数据不能放中断里面,中断只做接收,不然得话,当你来了一大堆数据,你FLASH还是写完,剩下的数据全部因为没法进入中断,全丢失了,送你个串口1的封装好的程序,写个usart1.c和usart.h 然后直接调用接口,你可以参考下,usart1.c文件如下
[mw_shl_code=c,true]/* Includes ------------------------------------------------------------------*/
#include <string.h>
#include "usart1.h"
#include "delay.h"
/* 最大缓存 */
#define MAXRECV USART1_BUFF
static char RX_BUFF[MAXRECV]={0}; //接收缓冲
static int RX_SIZ=0; //接收到的数据长度
#if (USART1_485_EN == 1)
#define RS485_TX_EN PAout(8) //485模式控制.0,接收;1,发送.
#endif
/*********************************************************
* @function usart1_Configuration
* @role USART1串口初始化
* @input bound:波特率
* @output None
* @return None
********************************************************/
void usart1_Configuration(int bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
#if (USART1_MAP_EN == 0)
/* config USART1 clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//PA9 TX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//PA10 RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
#else
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);//开启端口B和复用功能时钟
GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);//使能端口重映射
//uart 的GPIO重映射管脚初始化
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//悬空输入
GPIO_Init(GPIOB,&GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
#endif
#if (USART1_485_EN == 1)
//RE PA.8
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //输入输出控制IO
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
#endif
/* USART1 mode config */
USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位数据长度
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;///奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //使能串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级3级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
USART_Cmd(USART1, ENABLE); //使能串口
USART_ClearFlag(USART1, USART_FLAG_TC); // 清标志
RX_SIZ = 0;
#if (USART1_485_EN == 1)
RS485_TX_EN=0; //默认为接收模式
#endif
}
/*********************************************************
* @function USART1_IRQHandler
* @role 串口接收中断
* @input None
* @output None
* @return None
********************************************************/
void USART1_IRQHandler(void)
{
char buff = 0;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收到数据
{
if(RX_SIZ < MAXRECV){
buff = USART_ReceiveData(USART1);//记录接收到的值
if(buff || RX_SIZ){
RX_BUFF[RX_SIZ++] = buff;
}
}
USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志.
}
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET)//溢出
{
USART_ClearFlag(USART1,USART_FLAG_ORE);//读SR
USART_ReceiveData(USART1);//读DR
}
}
/*********************************************************
* @function usart1_Send
* @role 发送len个字节.
* @input 要发送的数据与长度,
(为了和本代码的接收匹配,这里建议不要超过 MAXRECV 个字节)
* @output None
* @return None
********************************************************/
void usart1_Send(char *buf,int len)
{
int t;
#if (USART1_485_EN == 1)
RS485_TX_EN=1;
#endif
for(t=0;t<len;t++) //循环发送数据
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
USART_SendData(USART1,buf[t]);
}
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET){//发送一个字符完成产生中断
USART_ClearITPendingBit(USART1 ,USART_IT_TXE);//清发送中断
}
#if (USART1_485_EN == 1)
RS485_TX_EN=0;
#endif
}
/*********************************************************
* @function usart1_Receive
* @role RS232查询接收到的数据
* @input buf:接收缓存首地址,与缓存长度
* @output None
* @return 接收的数据长度
********************************************************/
int usart1_Receive(char *buf, int buflen)
{
int rxlen=RX_SIZ;
int i=0;
int ret = 0; //默认为0
delay_ms(10); //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
if(rxlen==RX_SIZ && rxlen)//接收到了数据,且接收完成了
{
for(i=0;(i < rxlen) && (i < (buflen - 1));i++)
{
buf=RX_BUFF;
RX_BUFF = 0;
}
buf='\0';
ret=i; //记录本次数据长度
RX_SIZ=0; //清零
}
return ret;
}
/*********************************************************
* @function usart1_FreeBuff
* @role 清空缓存中的数据
* @input None
* @output None
* @return None
********************************************************/
void usart1_FreeBuff(void)
{
int rxlen=RX_SIZ;
int i=0;
delay_ms(10); //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
while(rxlen)
{
if(rxlen==RX_SIZ && rxlen)//接收到了数据,且接收完成了
{
for(i=0;(i<rxlen) && (i < (MAXRECV-1)) ;i++){
RX_BUFF = 0;
}
RX_SIZ=0; //清零
}
delay_ms(10); //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束
rxlen=RX_SIZ;
}
}[/mw_shl_code]
usart.h文件如下
[mw_shl_code=c,true]#ifndef __USART1_H_
#define __USART1_H_
#include "sys.h"
#define USART1_BUFF 200 //接收数据缓存
#define USART1_485_EN 0 //1 开启485功能,0 关闭485功能
#define USART1_MAP_EN 0 //1 开启重定向功能,0关闭重定向功能
void usart1_Configuration(int bound);
void usart1_Send(char *buf,int len);
int usart1_Receive(char *buf, int buflen);
void usart1_FreeBuff(void);
#endif[/mw_shl_code]
然后是sys.h文件
[mw_shl_code=c,true]#ifndef __SYS_H
#define __SYS_H
#include "stm32f10x.h"
//0,不支持ucos
//1,支持ucos
#define SYSTEM_SUPPORT_UCOS 1 //定义系统文件夹是否支持UCOS
//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<<CM3权威指南>>第五章(87页~92页).
//IO口操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum))
//IO口地址映射
#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C
#define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C
#define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C
#define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C
#define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408
#define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808
#define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08
#define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08
//IO口操作,只对单一的IO口!
//确保n的值小于16!
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //输出
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //输入
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //输出
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //输入
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //输出
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //输入
typedef enum {FALSE = 0, TRUE = !FALSE} bool;
#endif[/mw_shl_code] |
|