|
发表于 2009-4-29 15:46:43
|
显示全部楼层
不多说,这个PDF是做过处理的,COPY出来的并非完全一致.至少我COPY出来的并非完全一致.
为方便大家,附上个人写的程序,今天看了一下我个人的回复,才想起这个帖子.所以进来补上.晚上睡觉之前手打的.尚未测试其实用性.因为比较忙.
可能在"朦胧"中会有笔误.请调试OK的朋友.指正.
下附程序.TimerToUart.c
////////////////////////////////////////////////////////////
//
// AVR 一个定时器实现全双工模拟串口
//
//设计原理: 本文通信波特率为9600bps,使用1个定时器(频率38400Hz)
// 通过3次分频,为TX和RX二个通道同时提供准确的时钟驱动.
// RX不需要使用外部中断.直接由定时器进行IO扫描.
//设计模式: 异步操作模式.
//试验环境: ATmega16(L). 16MHz外部晶振.
//试验结果: 经过24小时不间断随机数据测试无一错误.
//后期扩展: 提供更高的时钟支持更多的串口同时扫描.
//
////////////////////////////////////////////////////////////
#include <API/TYPEOEF.H> //类型定义
//IO定义
#define GPRS_SET_TX() PORTD |= (1<<1)
#define GPRS_CLR_TX() PORTD &=~(1<<1)
#define GPRS_PIN_RX() PIND&(1<<0)
//38400时钟
#define TIMEBASE OxFE0D
//为RX提供32字节的FIFO支持
#define MAX_FIFO 32
static unsigned char ReceiverFIFO[MAX_FIFO];
static unsigned char FIFOI,FIFOT;
extern unsigned int TIMEBASE;
extern unsigned char TX_TIME;
static unsigned char RXBIT,TXCOUNT,RXBUF;
static unsigned char TXBIT,TXBUF;
//初始化
void UartInit(void)
{
////////////////////////////////
RXBIT=0;
RXCOUNT=1;
FIFOI=0;
FIFOT=0;
////////////////////////////////
//配置IO模式
DDRD|= (1<<1); //TX PD1
DDRD&=~(1<<0); //RX PD0
}
//发送一个字节
void WriteByte(unsigned char value)
{
TXBUF=value;
TXBIT=0;
while((TXBIT&0x80)==0);
}
//发送一个字符串
void WriteStr(unsigned char *str)
{
while(*str)
{
WriteByte(*str+);
}
}
//获取RX FIFO收到的长度
unsigned char GetFIFOCout(void)
{
if(FIFOI==FIFOT)
{
return 0;
}
else if(FIFOI>FIFOT)
{
FIFOT=0;
return (FIFOI-FIFOT);
}
else
{
return ((MAX_FIFO-FIFOT)+FIFOI);
}
}
//从RX FIFO中获取一个字节
unsigned char ReadByte(void)
{
unsigned char RET=ReceiverFIFO[FIFOT++];
if(FIFOT>MAX_FIFO-1)
{
FIFOT=0;
return RET;
}
}
//AVR Timer中断函数
//注意:为了保证代码在限定的时间下顺利完成,应尽量减少使用乘除法.
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
char RXB=GPRS_PIN_RX;
TCNTIH=TIMEBASE/256;
TCNT1L=TIMEBASE%256;
///////////////////////////////////
//接收部分
if(RXBIT&0x80) //判断接收是否完成
{
if(RXB)
{
RXBIT=0;
}
}
else if(RXBIT==0&&RXB==0)
{
RXBIT=RXCOUNT;
RXBUF=0;
}
else if((RXCOUNT==(RXBIT$0X11))&&RXBIT)
{
BYTE rxbitpos=RXBIT>>2;
switch(rxbitpos)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
RXBUF>>1;
if(RXB)
{
RXBUF|=0x80;
}
RXBIT=(RXBIT&0x11)|((rxbitpos+1)<<2);
break;
case 7:
RXBUF>>=1;
if(RXB)
{
RXBUF|=0x80;
RXBIT=0;
}
else RXBIT=0x80;
/////////////////////////////
//接收数据存放入FIFO
ReceiveFIFO[FIFOI++]=RXBUF;
if(FIFOI>MAX_FIFO-1)
{
FIFOI=0;
}
break;
}
}
if(RXCOUN==3)
{
RXCOUN=1;
}
else RXCOUN++;
if(TX_TIME==2)
{
if((TXBIT&0x80)==0)
{
switch(TXBIT)
{
case 0:
GPRS_CLR_TX();
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
if(TXBUF&0x01)
{
GPRS_SET_TX();
}
else GPRS_CLR_TX();
TXBUF>>=1;
break;
case 9:
GPRS_SET_TX();
break;
case 10:
TXBIT|=0x80;
break;
}
TXBIT++;
}
PORTD|=(1<<2);
TX_TIME=0;
}
else
{
PORTD&=~(1<<2);
TX_TIME++;
}
} |
|