#ifndef uchar
#define uchar unsigned char
#define uint unsigned int
#endif
//__CONFIG(0x2129)
bit rec_flag //串口中断标志位,有串口中断,置1
uchar uartdata //串口数据保存到此位置中
void Uart_char(uchar dat)//串口发送一个数信返据
/*************************************************************
函数原型:void main(void)
功能:等待串口发送中断到来握陵,将接收到的设计再通过串口发回
*************************************************************/
void main(void)
{
TRISB1=1
TRISB2=1
SPBRG=0X19 //设置波特率为9600BPS
TXSTA=0X24 //使能串口发送,选择高速波特率
RCSTA=0X90 //使能串口工作,连续接收
RCIE=0X1 //使能接收中断
GIE=0X1 //开放全局中断
PEIE=0X1 //使能外部中断
//INTCON=0X00
/* while(1) //查询模式下
{
RCIE=1
while(RCIF==0)
RCIE=0
Send_char(RCREG)
}
*/
while(1) //中断模式下,等待中断的到来
{
if(rec_flag==1) //如果接收中断到来
{
rec_flag=0//接收标志清零
Uart_char(uartdata)//将接收来的数据发送到串口
}
}
}
/**********************************************
函数原型:void Uart_char(uchar dat)
功能:将dat数据通过串口传送出去
**********************************************/
void Uart_char(uchar dat)
{
TXREG=dat //将dat数据存入TXREG
// TXEN=1 //启动发送,TSR开始移滑皮饥位 *** 作。
while (TRMT==0) //判断是否TSR发送完毕,未完等待。
// TXEN=0 //关发送功能,防止TXREG空时,TXIF产生置位
}
/**********************************************
函数原型:void interrupt usart(void)
功能:串口接收到数据,接受发来的数据将接
收到数据标志位rec_flag置1
**********************************************/
void interrupt usart(void)
{
if(RCIF) //判断是否为串口接收中断
{
rec_flag = 1
//RCIF=0
uartdata = RCREG// 接收数据并存储
//TXREG=recdata //把接收到的数据发送回去
}
}
这段程序应该对你有用
//摘要: 掌握 UART0配置及使用,程序中将UART0 配置到P0.0、 P0.1。利中岁用串口调试助手,波特率设置为4800,并选择十六进制发送和显示,十六进制发送为偶数个,不然会少返回一个数,详见程序注释。#include "c8051f020.h"
unsigned char data1
void SYSCLK_Init()
void PORT_Init()
void UART0_Init()
void SYSCLK_Init()
{
unsigned int i
OSCXCN=0X67//0X67=0110,0111
for(i=0i<256i++)//等待>1ms
while(!(OSCXCN&0X80)) //等待XTLVLD变为1
OSCICN=0X88//时钟失效监测器,选择外部时钟源作为系统时钟
}
void PORT_Init()
{
XBR0 = 0x27/*交叉开关配置,URAT总线TX0置到P0.0口,RX0置到P0.1口, SPI总线SCK配置到P0.2口,
MOSI为P0.4口卖袜睁, NSS为P0.5,MISO配置到P0.3口,IIC总线SDA置到P0.6口�SCK置到P0.7 TX1,RX1配置到P1.0,P1.1,CEX0,CEX1,配置到P1.2,P1.3,外部中断int0配置到P1.4 */
XBR1 = 0x04
XBR2 = 0x44 /*允许功能选择开关有效*/
P0MDOUT = 0x1A/*SCK、MOSI和NSS为推拉式输出,MISO为开漏式.*/
P74OUT =0xff
}
void UART0_Init()
{
SCON0=0x50 //串口方式1
TMOD=0X20//选用定时器1作为波特率发好桥生器
TH1=0xF4 //波特率为4800
TL1=0xF4
ES0=1 //开启串口中断0
TF1=0
TR1=1 //定时器启动
PCON=0X80//波特率加倍 波特率为9600
TI0=1
}
void UART0_ISR() interrupt 4 using 1
{
if(RI0)
{
RI0=0//中断接收标志清零
data1=SBUF0//接收数据
SBUF0=data1//发送数据
while(TI0==0)
TI0=0//发送标志清零
}
}
main()
{
WDTCN=0XDE
WDTCN=0XAD
SYSCLK_Init()
PORT_Init()
UART0_Init()
EA=1
while(1)
}
// 问题1:为什么要先左移这个和程序设计相关了,你要后左移也可以,就要更改程序结构了。最下面我把执行过程写出来,你看看就明白了
// 问题2:if(RXD):什么意思这个IF了里面不用表达式么?
一个变量也是表达式(参考C语言教材,“表达式”相关章节),闹迟所以如果 RXD 收到数据为 1,就会执行 dat |= 0x80,从而 dat 最高位就变成 1 了,否则不执行,则 dat 最高位是 0,这就达到把接收的数据保存在 dat 变量里的目的了
// 问题3:这或上0x80什么意思?单片机串数据到电脑先穿低位,这个是先传 高位么????、
放在高位是没错,接着会循环左移,就跑低位去了呀,那么先传的低位左移后就在最左边了,就是最低位了
// 问题4:这里为什么要返回这个子函数做空语句不行么????
如果不返回这个数据的早坦话,你在别的地方就不能用 变量=UART_rev_byte() 来获得收到的数据了呀。具体学习的话,请参考C语言教材,“函数返回值”相关章节的内容
假设收到数据:11110001,你可以把循环语句打印出来看看效果:
len| dat | 说明
8 | 10000000| dat 左移后 dat = 10000000,收到的数据 11110001 最低位 1,if(RXD)为真,执行 dat |= 0x80,dat 最高位为 1, 结果 dat = 10000000
7 | 01000000| dat 左移后 dat = 01000000,收到的数据 11110001 左二位 0,if(RXD)为假,不执行 dat |= 0x80,dat 最高位为 0,结果 dat = 01000000
6 | 00100000| dat 左移后 dat = 00100000,收到的数据 11110001 左三位 0,if(RXD)为假,不执行 dat |= 0x80,dat 最高位为 0,结果 dat = 00100000
5 | 00010000| dat 左移后 dat = 00010000,收到的数据 11110001 左四位 0,if(RXD)为假,不执行 dat |= 0x80,dat 最高位为 0,结果 dat = 00010000
4 | 10001000| dat 左移后 dat = 10001000,收到的数据 11110001 左五位 1,if(RXD)为真,执行 dat |= 0x80,dat 最高位为 1, 结果 dat = 10001000
3 | 11000100| dat 左移后 dat = 11000100,收到的数据 11110001 左六位 1,if(RXD)为真,执行 dat |= 0x80,dat 最高位为 1, 结果 dat = 11000100
2 | 11100010| dat 左移后 dat 陆弯桐= 11100010,收到的数据 11110001 左七位 1,if(RXD)为真,执行 dat |= 0x80,dat 最高位为 1, 结果 dat = 11100010
1 | 11110001| dat 左移后 dat = 11110001,收到的数据 11110001 左八位 1,if(RXD)为真,执行 dat |= 0x80,dat 最高位为 1, 结果 dat = 11110001
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)