PIC 单片机软件异步串行口实现技巧
;串行通信的波特率不能太高,4 MHz工作的PIC单片机一般能实现2400bps的全双工通信。当然,可以通过提高MCU的振荡频率来实现高波特率通信,当PIC单片机工作在20 MHz时,实现9600b/s绰绰有余。 2 起始位中断捕捉、定时采样法 实现此法的硬件条件是PIC单片机有外部脉冲下降沿中断触发功能,在中档以上PIC单片机中有RB0/INT外部中断脚,CCP1/CCP2脉 冲沿捕捉脚,PORTB的第4/5/6/7电平变化中断脚等都可以满足。另外需配备一个定时器,以定时中断方式对接收码元正确采样,或发送串行数据流。其 关键的异步接收工作原理简介如图4所示。 图4 设串行数据位宽度为td。起始位到来时刻(图4 A点)的下降沿触发一个中断并立即响应该中断。在此中断服务中立即关闭本中断使能位(后续的数据流变化无需触发中断),开启定时器,使其在 1.5td后产生定时中断,用于采样第一个数据位(确保S0采样点落在数据位的中心位置处);在处理下降沿中断服务的最后,再检测接收端是否还是0电平, 以区分窄脉冲干扰。在S0点采样到第一个数据位后的所有采样间隔都是1td,直到收到停止位后,关闭定时器中断,重新开放下降沿捕捉中断,准备接收下一个 字节。 异步数据接收和发送的状态机控制流程,除了起始位判断和定时时间参数设置与前述方式不同外,其它几乎一样,此处不再重复。 此法的好处是可以实现较高的通信波特率。对于通信不是很频繁的系统,此软件UART几乎不耗MCU运行带宽,9600b/s接收或发送在4 MHz运行的PIC单片机上即可轻松实现;另外,由于下降沿中断可以唤醒处于睡眠的单片机,故极易实现通信唤醒的功能。缺点是不能全双工通信(除非另外单 独用一个定时器实现发送定时),异步接收的引脚必须有下降沿触发中断的能力。 上面介绍的两种方法在实际产品设计中都得到了很好的验证,最典型的是红外线自动抄表系统。该系统要求收发均为38 kHz红外调制,串行数据1 200bps半双工通讯。用软件实现此UART,并充分利用PIC单片机CCP模块的脉宽调制PWM输出38 kHz载波时,在单片机外除了一个一体化红外接收头和一个红外发射二极管,无需其它任何外围器件,即可完成所有设计要求,最大程度地减化了硬件设计,降低 了成本,提高了系统的可靠性和性能价格比。 以上的侧重点是基本原理的介绍,希望对大家有所帮助。在接收数据的可靠性处理方面没有太多涉及。有兴趣者可以在采样时刻到来时对数据做多次采 样,以消除干扰误码;或有其它处理技巧,欢迎和笔者作进一步交流。 简单的C语言参源程序如下: #i nclude //PIC单片机通用头文件,实际型号为16F84 __CONFIG(XT | PROTECT | PWRTEN | WDTEN);//程序中设定配置信息 //=========================== //定义软件UART发送/接收引脚 //=========================== #define RX_PIN RB0 //串行接收脚 #define TX_PIN RB1 //串行发送脚 //=========================== //定义软件UART状态机控制字 //=========================== #define RS_IDLE 0 //空闲 #define RS_DATA_BIT 1 //数据位 #define RS_STOP_BIT 2 //停止位 #define RS_STOP_END 3 //停止位结束 //=========================== //定义软件UART采样频率 //=========================== #define OSC_FREQ 4000 //单片机工作频率(单位:KHz) #define BAUDRATE 1200 //通讯波特率 #define TMR0PRE 2 //TMR0预分频比1:2 #define TMR0CONST 117 //256 - OSC_FREQ*1000/TMR0PRE/4/(BAUDRATE*3) //=================================================================== // 定义函数类型 void UART_Out(void); void UART_In(void); //=================================================================== // 定义位变量 bit rsTxBusy; //串行发送忙标志 //定义串行发送的数据结构 struct { unsigned char state; //发送状态机控制单元 unsigned char sliceCount; //波特率控制 unsigned char shiftBuff; //字节数据发送移位寄存器 unsigned char shiftCount; //字节数据发送移位计数器 } rsTx; //定义串行接收的数据结构 struct { unsigned char state; //接收状态机控制单元 unsigned char sliceCount; //波特率(采样点)控制 unsigned char shiftBuff; //字节数据接收移位寄存器 unsigned char shiftCount; //字节数据接收移位计数器 unsigned char dataBuff[8]; //接收数据FIFO缓冲队列 unsigned char putPtr, getPtr;//FIFO队列存放/读取指针 } rsRx; //用于串行发送的变量定义 unsigned char outBuff[10]; /
- dsPIC33F系列DSC的 SD存储卡接口设计(01-05)
- 基于dsPIC30F2010的土壤水分测量仪的设计研究(08-27)
- 基于AD7862和dsPIC30F的数据采集系统(08-25)
- 基于DSPIC30F4011单片机的CAN总线通信设计(02-08)
- PICCl8编译器命令行驱动及其应用(02-11)
- 基于dsPIC33F系列单片机的应用程序升级方法(04-03)