- //为何不把程序写得通俗易懂点?超级代码来了!
- //参考了STC官网手册中的程序,但源程序遇到RX脚一直为低电平也会收到数据0x00,这里已经修正
- //柳州市第一职业技术学校 电气自动化专业部 中国欧软 China O Soft! 2012年8月3日
- #include <reg52.h> //使用8052内核单片机
- sbit TX_IO=P3^1; //模拟串口发送IO
- sbit RX_IO=P3^0; //模拟串口接收IO
- sfr AUXR=0x8e; //STC15F系列单片机特殊寄存器,控制定时器时钟来源频率
- bit sending,receing,received; //发送中,接收中,接收完毕标志
- unsigned char rece_bit_count; //接收位计数变量
- unsigned char rece_pls_count; //接收脉冲计数变量
- unsigned char send_bit_count; //发送位计数变量
- unsigned char send_pls_count; //发送脉冲计数变量
- unsigned char receing_data; //正在接收着的临时数据
- unsigned char byte_need_to_send; //要发送出去的字节
- unsigned char byte_received; //已收到的字节
- void send_byte(unsigned char byte_will_send) //发送一个字节
- { //函数开始
- byte_need_to_send=byte_will_send; //传递要发送的数据
- send_pls_count=3; //采样倍率3
- send_bit_count=8; //8位数据一位停止
- TX_IO=0; //发送起始位
- sending=1; //置标志位,中断程序开始发送该字节
- while(sending); //等待数据发送完成
- } //函数结束
- void timer0(void) interrupt 1 //中断服务程序
- { //函数开始
- if(receing) //接收中?
- { //接收中开始
- if(--rece_pls_count==0) //三次脉冲计数够了吗?
- { //接收一位二进制位开始
- rece_pls_count=3; //脉冲计数辅助变量复位
- if(rece_bit_count) //是在接收数据位还是停止位
- { //接收数据位开始
- receing_data=receing_data>>1; //向右移一位,准备拼入一位二进制数据
- if(RX_IO==1){receing_data=receing_data|0x80;}//如果收到的是二进制位"1",则拼入最高位中
- rece_bit_count=rece_bit_count-1; //已接收一位,接收位计数变量计数
- } //接收数据位结束
- else //如果已经收完8位数据
- { //就开始接收停止位
- receing=0; //本字节已接收完毕
- if(RX_IO==1) //停止位是"1"吗
- { //是“1”
- byte_received=receing_data; //将数据输出
- received=1; //摇旗示意数据正确接收完毕
- } //数据输出处理完毕
- } //停止位处理完毕
- } //接收一位二进制位结束
- } //接收中处理结束
- else //还没收到停止位,不是正在接收状态
- { //等待接收开始
- if(RX_IO==0) //是一个起始位到来吗
- { //是.......
- receing=1; //开始接收
- rece_pls_count=3; //置接收起始位脉冲数
- rece_bit_count=8; //置接收二进制位数
- } //起始位处理完毕
- } //等待接收完毕
- //----------------------------------------------------------------------------------------
- if(sending) //是正在发送状态吗
- { //是……
- if(--send_pls_count==0) //脉冲计数够了吗
- { //够了……
- send_pls_count=3; //脉冲计数复位
- if(send_bit_count) //是在发送数据还是要发送停止位
- { //发送数据开始
- TX_IO=byte_need_to_send&0x01; //从最低位开始发送数据
- byte_need_to_send=byte_need_to_send>>1; //移动数据准备下一次发送
- send_bit_count=send_bit_count-1; //已经发送了一位二进制数要记下来
- } //发送数据结束
- else //数据已经发送完成
- { //发送停止位开始
- TX_IO=1; //发送停止位
- sending=0; //放下旗帜表示数据已经发送完成
- } //停止位发送完成
- } //一位二进制位处理完成
- } //发送状态处理完成
- } //中断函数结束
- void main(void) //主程序
- { //开始
- AUXR=0x80; //T0计时脉冲不分频,比传统8051快12倍
- TMOD=0X00; //16位自动重载模式,当TR0=0时向TH0,TL0写入数据将同时写入重载寄存器
- TH0=(65536-(24000000/57600/3))/256; //重载值=65536-(定时器脉冲频率÷波特率÷3)
- TL0=(65536-(24000000/57600/3))%256; //溢出率=定时器脉冲频率÷(65536-重载值)
- TR0=1; //启动定时器,模拟串口开始工作
- EA=1; //打开总中断
- ET0=1; //打开定时器0中断
- PX0=1; //优先保证定时器0中断,确保模拟串口的可靠性
- while(1) //主循环
- { //主循环体开始
- if(received==1) //收到一个字节的数据啦?
- { //是……
- received=0; //知道了……
- send_byte(byte_received); //原封不动打回原籍
- } //收到字节处理完毕
- } //主循环体结束
- } //主程序结束
复制代码
|