delay.c
#include "delay.h"
static u8 fac_us=0; //us延时倍乘数
static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个节拍的ms数
//初始化延迟函数
//当使用OS的时候,此函数会初始化OS的时钟节拍
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数
}
//延时nus
//nus为要延时的us数.
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//延时 S
//最大为18s
void delay_s(u8 s)
{
delay_ms(s*100);//1
delay_ms(s*100);//2
delay_ms(s*100);//3
delay_ms(s*100);//4
delay_ms(s*100);//5
delay_ms(s*100);//6
delay_ms(s*100);//7
delay_ms(s*100);//8
delay_ms(s*100);//9
delay_ms(s*100);//10
}
delay.h
#ifndef __DELAY_H
#define __DELAY_H
#include "sys.h"
void delay_init(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);
void delay_s(u8 s);
#endif
sys.c
#include "sys.h" sys.h
#ifndef __SYS_H
#define __SYS_H
#include "stm32f10x.h"
//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<
>第五章(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) //输入
#endif
usart.c
#include "sys.h"
#include "usart.h"
/*
当串口不发送数据时TC标志位为0。当TC(发送完成),该位被置位为1,
表示 USART_DR内的数据已经被发送完成了。如果设置了这个位的中断,
则会产生中断。该位也有两种清零方式:
1)读 USART_SR,写USART_DR。
2)直接向该位写 0。
*/
//重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
//发送一个字节数据到串口
USART_SendData(USART1, (uint8_t) ch);//等价于 USART1->DR = (u8) ch;
//循环发送,直到发送完毕。while (0);跳出循环,while(1);代码不再向下执行
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);//等价于while((USART1->SR&0X40)==0);
return (ch);
}
void uart_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//使能USART1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
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); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断
USART_Cmd(USART1, ENABLE); //使能串口1
}
/*RXNE(读数据寄存器非空),默认情况下也就是没有数据接收时,该寄存器值为0
当有数据被接收到时,该位会被自动置1,就可以读出来了。这时候我们要做的就
是尽快去读取USART_DR,通过读USART_DR可以将该位清零,也可以向该位写0,直接清除。*/
//一个汉字是2个字节,一个英文字母(不分大小写)是一个字节,中文标点占三个字节, 英文标点占一个字节.
u8 USART_RX_BUF[USART_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.
u16 USART_RX_STA=0;//接收状态标记
/*
当接收到从电脑发过来的数据,把接收到的数据保存在 USART_RX_BUF 中,同时在
接收状态寄存器(USART_RX_STA)中计数接收到的有效数据个数,当收到回车(回车的
表示由 2 个字节组成:0X0D 和 0X0A)的第一个字节 0X0D 时,计数器将不再增加,等待
0X0A 的到来,而如果 0X0A 没有来到,则认为这次接收失败,重新开始下一次接收。如
果顺利接收到 0X0A,则标记 USART_RX_STA 的第 15 位,这样完成一次接收,并等待该
位被其他程序清除,从而开始下一次的接收,而如果迟迟没有收到 0X0D,那么在接收数
据超过 USART_REC_LEN 的时候,则会丢弃前面的数据,重新接收。
—————————————————————————————————————————————————————————————————
| USART_RX_STA
—————————————————————————————————————————————————————————————————
| bit15 | bit14 | bit13~0 |
—————————————————————————————————————————————————————————————————
| 接收完成标志 | 接收到0x0D标志 | 接收到有效数据的个数|
—————————————————————————————————————————————————————————————————
*/
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 ucTemp;
if(USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET) //如果发生了接收中断RXNE会自动置位为1 (接收到的数据必须是0x0d 0x0a结尾)
{
ucTemp =USART_ReceiveData(USART1);//读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成(每次进入中断服务函数都要判断bit15接收完成标志位是否置位为1)
{
if(USART_RX_STA&0x4000)//接收到了回车符,也就是0x0D (如果bit15接收完成标志位未置位为1,就要判断是否接收到了回车符的第一个字节。USART_RX_STA是0还是1)
{
if(ucTemp!=0x0A)//没有接收到回车符的第二个字节0x0A(在确定接收到0x0d后要判断是否接受到了0x0a,才能确定接收正确)
USART_RX_STA=0;//接收错误,重新开始
else
USART_RX_STA|=0x8000;//接收完成了(或运算是用来置位的,接收到0x0d也就收到了0x0a说明接收正确接收完成,把bit15接收完成标志位置1)
}
else //没有接收到了回车符,也就是没有收到0x0D,中断来了继续接收数据
{
if(ucTemp==0x0D)//中断来了继续接收数据,也要先判断一下是否接受到了接收到回车符的第一个字节
USART_RX_STA|=0x4000;//如果接收到回车符的第一个字节0x0D,就要将接收到回车的bit14位0x0D标志位置1
else//中断来了继续接收数据,如果还没有接收到回车符的第一个字节,就要把接收到的数据存到缓冲区USART_RX_BUF[]
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=ucTemp;//把寄存器USART_RX_STA的bit13~0做清零处理,用来存放接收到的数据ucTemp
USART_RX_STA++;//每次接收到一个新数据就要把USART_RX_STA的值加1
if(USART_RX_STA>(USART_REC_LEN-1))
USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
usart.h
#ifndef __USART_H
#define __USART_H
#include "stdio.h"
#include "sys.h"
#define USART_REC_LEN 200 //定义最大接收字节数 200
extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 USART_RX_STA; //接收状态标记
void uart_init(u32 bound);
#endif
delay.c
#include "delay.h"
static u8 fac_us=0; //us延时倍乘数
static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个节拍的ms数
//初始化延迟函数
//当使用OS的时候,此函数会初始化OS的时钟节拍
//SYSTICK的时钟固定为HCLK时钟的1/8
//SYSCLK:系统时钟
void delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数
}
//延时nus
//nus为要延时的us数.
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//延时 S
//最大为18s
void delay_s(u8 s)
{
delay_ms(s*100);//1
delay_ms(s*100);//2
delay_ms(s*100);//3
delay_ms(s*100);//4
delay_ms(s*100);//5
delay_ms(s*100);//6
delay_ms(s*100);//7
delay_ms(s*100);//8
delay_ms(s*100);//9
delay_ms(s*100);//10
}
delay.h
#ifndef __DELAY_H
#define __DELAY_H
#include "sys.h"
void delay_init(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);
void delay_s(u8 s);
#endif
sys.c
#include "sys.h" sys.h
#ifndef __SYS_H
#define __SYS_H
#include "stm32f10x.h"
//位带操作,实现51类似的GPIO控制功能
//具体实现思想,参考<>第五章(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) //输入
#endif
usart.c
#include "sys.h"
#include "usart.h"
/*
当串口不发送数据时TC标志位为0。当TC(发送完成),该位被置位为1,
表示 USART_DR内的数据已经被发送完成了。如果设置了这个位的中断,
则会产生中断。该位也有两种清零方式:
1)读 USART_SR,写USART_DR。
2)直接向该位写 0。
*/
//重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
//发送一个字节数据到串口
USART_SendData(USART1, (uint8_t) ch);//等价于 USART1->DR = (u8) ch;
//循环发送,直到发送完毕。while (0);跳出循环,while(1);代码不再向下执行
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);//等价于while((USART1->SR&0X40)==0);
return (ch);
}
void uart_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//使能USART1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
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); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接收中断
USART_Cmd(USART1, ENABLE); //使能串口1
}
/*RXNE(读数据寄存器非空),默认情况下也就是没有数据接收时,该寄存器值为0
当有数据被接收到时,该位会被自动置1,就可以读出来了。这时候我们要做的就
是尽快去读取USART_DR,通过读USART_DR可以将该位清零,也可以向该位写0,直接清除。*/
//一个汉字是2个字节,一个英文字母(不分大小写)是一个字节,中文标点占三个字节, 英文标点占一个字节.
u8 USART_RX_BUF[USART_REC_LEN];//接收缓冲,最大USART_REC_LEN个字节.
u16 USART_RX_STA=0;//接收状态标记
/*
当接收到从电脑发过来的数据,把接收到的数据保存在 USART_RX_BUF 中,同时在
接收状态寄存器(USART_RX_STA)中计数接收到的有效数据个数,当收到回车(回车的
表示由 2 个字节组成:0X0D 和 0X0A)的第一个字节 0X0D 时,计数器将不再增加,等待
0X0A 的到来,而如果 0X0A 没有来到,则认为这次接收失败,重新开始下一次接收。如
果顺利接收到 0X0A,则标记 USART_RX_STA 的第 15 位,这样完成一次接收,并等待该
位被其他程序清除,从而开始下一次的接收,而如果迟迟没有收到 0X0D,那么在接收数
据超过 USART_REC_LEN 的时候,则会丢弃前面的数据,重新接收。
—————————————————————————————————————————————————————————————————
| USART_RX_STA
—————————————————————————————————————————————————————————————————
| bit15 | bit14 | bit13~0 |
—————————————————————————————————————————————————————————————————
| 接收完成标志 | 接收到0x0D标志 | 接收到有效数据的个数|
—————————————————————————————————————————————————————————————————
*/
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 ucTemp;
if(USART_GetITStatus(USART1, USART_IT_RXNE)!= RESET) //如果发生了接收中断RXNE会自动置位为1 (接收到的数据必须是0x0d 0x0a结尾)
{
ucTemp =USART_ReceiveData(USART1);//读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成(每次进入中断服务函数都要判断bit15接收完成标志位是否置位为1)
{
if(USART_RX_STA&0x4000)//接收到了回车符,也就是0x0D (如果bit15接收完成标志位未置位为1,就要判断是否接收到了回车符的第一个字节。USART_RX_STA是0还是1)
{
if(ucTemp!=0x0A)//没有接收到回车符的第二个字节0x0A(在确定接收到0x0d后要判断是否接受到了0x0a,才能确定接收正确)
USART_RX_STA=0;//接收错误,重新开始
else
USART_RX_STA|=0x8000;//接收完成了(或运算是用来置位的,接收到0x0d也就收到了0x0a说明接收正确接收完成,把bit15接收完成标志位置1)
}
else //没有接收到了回车符,也就是没有收到0x0D,中断来了继续接收数据
{
if(ucTemp==0x0D)//中断来了继续接收数据,也要先判断一下是否接受到了接收到回车符的第一个字节
USART_RX_STA|=0x4000;//如果接收到回车符的第一个字节0x0D,就要将接收到回车的bit14位0x0D标志位置1
else//中断来了继续接收数据,如果还没有接收到回车符的第一个字节,就要把接收到的数据存到缓冲区USART_RX_BUF[]
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=ucTemp;//把寄存器USART_RX_STA的bit13~0做清零处理,用来存放接收到的数据ucTemp
USART_RX_STA++;//每次接收到一个新数据就要把USART_RX_STA的值加1
if(USART_RX_STA>(USART_REC_LEN-1))
USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
usart.h
#ifndef __USART_H
#define __USART_H
#include "stdio.h"
#include "sys.h"
#define USART_REC_LEN 200 //定义最大接收字节数 200
extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
extern u16 USART_RX_STA; //接收状态标记
void uart_init(u32 bound);
#endif
举报