#include "STC15W4K.H"
#define TRUE 1
#define FALSE 0
volatile unsigned char Flag=FALSE;
unsigned char uart1temp;
void UART_init(void)
{
// 下面代码设置定时器1
TMOD = 0x20; // 0010 0000 定时器1工作于方式2(8位自动重装方式)
TH1 = 0xFA; // 波特率:9600 /22.1184MHZ
TL1 = 0xFA; // 波特率:9600 /22.1184MHZ
TR1 = 1;
// 下面代码设置定串口
AUXR = 0x00; // 很关键,使用定时器1作为波特率发生器,S1ST2=0
SCON = 0x50; // 01010 0000 SM0.SM1=01(最普遍的8位通信),REN=1(允许接受)
// 下面代码设置中断
ES = 1; // 关键:开启了中断就必须编写相应的中断函数,哪怕是中断空函数,
// 但必须有,否则程序进入中断入口地址后(这里是0023H)不能跳出,必然出错
EA = 1;
}
/***************************************************************************
* 描 述 : 串口1发送数据函数
* 入 参 : uint8 数据
* 返回值 : 无
**************************************************************************/
void SendDataByUart1(uint8 dat)
{
SBUF = dat; //写数据到UART数据寄存器
while(TI == 0); //在停止位没有发送时,TI为0即一直等待
TI = 0; //清除TI位(该位必须软件清零)
}
/***************************************************************************
* 描 述 : 串口1中断服务函数
* 入 参 : 无
* 返回值 : 无
**************************************************************************/
void Uart1() interrupt 4 using 1
{
ES = 0; // 串口1中断关闭
Flag=TRUE; //接收到数据,接收标识符有效
if (RI) //串行接收到停止位的中间时刻时,该位置1
{
RI = 0; //清除RI位 (该位必须软件清零)
uart1temp = SBUF;
}
ES = 1; // 串口1中断打开
}
/**************************************************************************************
* 描 述 : 串口1接收到数据后发送出去
* 入 参 : 无
* 返回值 : 无
**************************************************************************************/
void UART1_Tx_Puts(void)
{
if(Flag) //有新数据通过串口被接收到
{
ES = 0; //串口1中断关闭
SendDataByUart1(uart1temp); //发送字符
SendDataByUart1(0x0D); //发送换行符
SendDataByUart1(0x0A); //发送换行符
ES = 1; //串口1中断打开
Flag=FALSE; //清除接收标识符
}
}
int main()
{
P3M1 &= 0xFE; P3M0 &= 0xFE; //设置P3.0为准双向口
P3M1 &= 0xFD; P3M0 |= 0x02; //设置P3.1为推挽输出
UART_init(); // 串口初始化
EA = 1; //总中断打开
while(1)
{
UART1_Tx_Puts(); //串口接收到一个字符后返回该字符
}
}
经大神指点,去掉了中断里 TI 部分的语句。
这个程序是之前为了完成功能,从两个程序里拼凑出的一个程序,现在看起来的确有些繁冗。
但对于当时的我来说已经是一个很大的进步了。
串口部分的内容后续还会有很多要学习,我会继续深挖。
感谢大神对我的指导,看到大神对我提出的意见我还是很忐忑的,但是也正是因为忐忑才驱使我进步,是大神让我有机会看到了之前看不到的程序写法。
再次感谢大神的批评和指导,请大神们不吝赐教,继续鞭策、斧正。