/
File: mainc
功能:使用串口UART0接收上位机发送的数据,当接收到8个连续数据后,取反LED控制,并将
数据原封不动地发送回上位机
/
#include "configh"
#define LED1CON 0x00000400 /LED(DS11)控制,低电平点亮,用于通信指示/
/定义Fpclk值,用于设置串口波特率/
#define FPCLK 2764800L
/定义串口模式设置数据结构/
typedef struct UartMode
{ uint8 datab; //字长度,5/6/7/8
uint8 stopb; //停止位,1/2
uint8 parity; //奇偶校验位,0为无校验,1为奇数校验,2位偶数校验
} UARTMODE;
uint8 rcv_buf[8]; //UART0数据接收缓冲区
uint8 rcv_new; //接收新数据标志
/
名称: IRQ_UART0(void)
功能: 串口UART0接收中断
/
void __irq IRQ_UART0(void)
{ uint32 i;
i=IOSET; //读取当前LED控制值
if((i&LED1CON)==0) //控制LED输出
{ IOSET=LED1CON;
}
else
{ IOCLR=LED1CON;
}
if(0x04==(U0IIR&0x0F))rcv_new=1; //设置接收到新的数据标志
for(i=0;i<7;i++)
{ rcv_buf[i]=U0RBR; //读取FIFO的数据,并清除中断标志
}
VICVectAddr=0x00; //中断处理结束
}
/
名称: SendByte()
功能: 向串口发送字节数据
入口参数:data 要发送的数据
/
void SendByte(uint8 data)
{ U0THR=data;
while((U0LSR&0x20)==0); //等待数据发送
}
/
名称: ISendBuf()
功能: 将缓冲区的数据发送回主机,并等待发送完毕
/
void ISendBuf(void)
{ uint8 i;
for(i=0;i<7;i++)SendByte(rcv_buf[i]);
while((U0LSR&0x20)==0); //等待数据发送
}
/
名称: UART0_Ini()
功能: 初始化串口0 设置其工作模式及波特率
入口参数: baud 波特率
set 模式设置 (UARTMODE数据结构)
出口参数:返回值为1时表示初始化成功,为0表示参数出错
/
uint8 UART0_Ini(uint32 baud,UARTMODE set)
{ uint32 bak;
/参数过滤/
if((0==baud)||(baud>115200))return(0);
if((setdatab<5)||(setdatab>8))return(0);
if((0==setstopb)||(setstopb>2))return(0);
if(setparity>4)return(0);
/设置串口波特率/
U0LCR=0x80; //DLAB位置1
bak=(FPCLK>>4)/baud;
U0DLM=bak>>8;
U0DLL=bak&0xff;
/设置串口模式/
bak=setdatab-5; //设置字长度
if(2==setstopb)bak|=0x04; //判断是否为2位停止位
if(0!=setparity){setparity=setparity-1;bak|=0x08;}
bak|=setparity<<4; //设置奇偶校验
U0LCR=bak;
return(1);
}
/
名称: main()
功能: 初始化串口,并等待接收到串口数据
/
int main(void)
{ UARTMODE uart0_set;
PINSEL0=0x00000005; //设置I/O连接到UART0
PINSEL1=0x00000000;
IODIR=LED1CON; //设置LED控制口为输出,其它I/O为输入
rcv_new=0;
uart0_setdatab=8; //8位数据位
uart0_setstopb=1; //1位停止位
uart0_setparity=0; //无奇偶校验位
UART0_Ini(9600,uart0_set); //初始化串口模式,波特率9600
U0FCR=0x81; //使能FIFO,并设置触发点为8字节
U0IER=0x01; //允许RBR中断,即接收中断
/设置中断允许/
VICIntSelect=0x00000000; //设置所有通道为IRQ中断
VICVectCntl0=0x26; //UART0中断通道分配到IRQ Slot0,即优先级最高
VICVectAddr0=(int)IRQ_UART0; //设置UART0向量地址
VICIntEnable=0x00000040; //使能UART0中断
while(1) //等待中断
{
if(1==rcv_new)
{
ISendBuf(); //将接收到的数据发送回主机
rcv_new=0;
}
}
return(0);
}
我是你唐璜哥哥,快给钱。
可靠的接受程序!!从LZ 的display(a1a10)看出来这程序就不咋样,如果显示函数 还是 用 延时做的,可靠的接受程序给LZ 也是 白瞎……
以下是 UART 驱动程序
/10位异步收发串口通讯驱动——火柴天堂作品-20130119/
/源程序硬件环境:52单片机,110592MHz晶振,定时器1作为波特率发生器,通讯波特率9600 bit/s/
//
#define UART_H
#include"REG52h" //包含52头文件
#include"UARTh" //包含串口头文件
#define th1 0xfa //651us at 110592MHz Fosc for 8bit auto reload mode
static uchar UART_DataR; //串口接收数据寄存器
static uchar bdata Flag=0; //标志位 寄存器
sbit UART_ReFlag=Flag^0; //串口接收标志位 0:无数据 1:新数据
sbit UART_SendFlag=Flag^1; //串口发送标志位 0:空闲中 1:发送中
void UART()interrupt 4 //串口中断函数
{
if(RI) //若串口接收完成
{
RI=0; //清 串口接收溢出位
UART_DataR=SBUF; //将串口收到的数据存进 UART_DataR
UART_ReFlag=TRUE; //串口接收标志位 置位(有新数据)
}
if(TI) //若串口发送完成
{
TI=0; //清 串口发送溢出位
UART_SendFlag=FALSE; //清串口发送标志位(空闲中)
}
}
void UART_Init() //串口初始化函数
{
SCON=0x50; //选择通讯方式:10位异步收发,串口中断使能
PCON=0x80; //波特率倍频
TMOD&=0x0f; //定时器1控制位清0
TMOD|=0x20; //定时器1工作模式2(8位自重装,做波特率发生器)
TH1=th1; //定时器初值
TL1=th1; //定时器初值
TR1=1; //开始计时
ES=1; //允许串口中断
EA=1; //允许系统中断
}
bit UART_SendByte(uchar send_data) //串口发送字节函数,发送内容send_data,返回值:0 *** 作失败,1 *** 作成功
{
if(!UART_SendFlag) //若串口空闲中,则
{
SBUF=send_data; //将发送内容 送到 串口寄存器
UART_SendFlag=TRUE; //置位串口发送标志位(进入忙态)
return TRUE; //返回1, *** 作成功
}
return FALSE; //否则,返回0, *** 作失败
}
uchar ASCII_ToHex(uchar ascii_data) //ASCII 转 Hex 函数
{
uchar hex_data=0; //定义 Hex变量存储转换结果
if(ascii_data>='0' && ascii_data<='9') hex_data=ascii_data-'0'; //若 转换内容为 字符'0-9',则转成对应数字0-9
else if(ascii_data>='a' && ascii_data<='f') hex_data=ascii_data-'a'+10; //若 转换内容为 字符'a-f',则转成数字10-15
else if(ascii_data>='A' && ascii_data<='F') hex_data=ascii_data-'A'+10; //若 转换内容为 字符'A-F',则转成数字10-15
return hex_data; //返回转换结果,非以上字符,不在Hex(0-F)范围内,默认0
}
bit UART_ReadByte(uchar p_data,bit data_mode) //串口读字节函数,返回值0 无数据,1 有数据,将data_mode模式(ASCII_Mode或HEX_Mode)转成Hex结果存到p_data指向地址
{
if(!UART_ReFlag) return FALSE; //若无新数据,则返回 0(无数据)
UART_ReFlag=FALSE; //否则,清 串口接收标志位
if(data_mode==HEX_Mode) p_data=UART_DataR; //Hex模式,将串口接收结果存到p_data指向地址
if(data_mode==ASCII_Mode) p_data=ASCII_ToHex(UART_DataR); //ASCII模式,将串口接收结果转成Hex后,存到p_data指向地址
return TRUE; //返回 1(有数据)
}
在STM32中UART和USART是不相同的,在官方的文档中,大部分配置的都是USART2和UASRT3,对于UART4和UART5却很少有人配置,由于最近在集成项目,所以要用到多种串口,所以索性就配置了UART4和UART5
例如:
简单区分同步和异步就是看通信时需不需要对外提供时钟输出,我们平时用的串口通信基本都是UART。
USART支持同步模式,因此USART需要同步时钟信号USART_CK(如STM32 单片机),通常情况同步信号很少使用,因此一般的单片机UART和USART使用方式是一样的,都使用异步模式。
UART需要固定的波特率,就是说两位数据的间隔要相等。 UART总线是异步串口,一般由波特率产生器(产生的波特率等于传输波特率的16倍)、UART接收器、UART发送器组成,硬件上有两根线,一根用于发送,一根用于接收。 显然,如果用通用IO口模拟UART总线,则需一个输入口,一个输出口。
UART是一个并行输入成为串行输出的芯片,通常集成在主板上,多数是16550AFN芯片。因为计算机内部采用并行数据,不能直接把数据发到Modem,必须经过UART整理才能进行异步传输,其过程为:CPU先把准备写入串行设备的数据放到UART的寄存器(临时内存块)中,再通过FIFO(First Input First Output,先入先出队列)传送到串行设备,若是没有FIFO,信息将变得杂乱无章,不可能传送到Modem。
作为接口的一部分,UART还提供以下功能:将由计算机内部传送过来的并行数据转换为输出的串行数据流。将计算机外部来的串行数据转换为字节,供计算机内部使用并行数据的器件使用。在输出的串行数据流中加入奇偶校验位,并对从外部接收的数据流进行奇偶校验。在输出数据流中加入启停标记,并从接收数据流中删除启停标记。处理由键盘或鼠标发出的中断信号(键盘和鼠标也是串行设备)。可以处理计算机与外部串行设备的同步管理问题。
USART收发模块一般分为三大部分:时钟发生器、数据发送器和接收器。控制寄存器为所有的模块共享。时钟发生器由同步逻辑电路(在同步从模式下由外部时钟输入驱动)和波特率发生器组成。发送时钟引脚XCK仅用于同步发送模式下,发送器部分由一个单独的写入缓冲器(发送UDR)、一个串行移位寄存器、校验位发生器和用于处理不同浈结构的控制逻辑电路构成。使用写入缓冲器,实现了连续发送多浈数据无延时的通信。接收器是USART模块最复杂的部分,最主要的是时钟和数据接收单元。数据接收单元用作异步数据的接收。除了接收单元,接收器还包括校验位校验器、控制逻辑、移位寄存器和两级接收缓冲器(接收UDR)。接收器支持与发送器相同的帧结构,同时支持桢错误、数据溢出和校验错误的检测。USART是一个全双工通用同步/异步串行收发模块,该接口是一个高度灵活的串行通信设备。
综上可以看出,USART相对UART来说是在异步通信的基础上还有同步的功能,USART能够提供主动时钟。
先来看一下引脚图
[上传失败(image-5879a4-1545558491497)]
可以看到USART1、USART2、UASRT3、UART4、UART5对应的引脚,下面我们就来配置!
初始化程序:
初始化程序:
初始化程序:
初始化程序:
初始化程序:
对比一下不难发现UASRT的初始化和UART的初始化几乎相同!!!!!
以上就是关于用51单片机读取sim900里的短信程序怎么写全部的内容,包括:用51单片机读取sim900里的短信程序怎么写、串口发送数据时单片机能执行其他程序吗、关于嵌入式应用技术中的UART0的问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)