
³ÌÐòÎļþ
[code="c"]
/*********************************************************************************************************
** AVRÈí¼þ ´®¿ÚÇý¶¯
** (c) Copyright 2010, limaokui
** All Rights Reserved
**
** V1.0.0
**
**
**--------------ÎļþÐÅÏ¢--------------------------------------------------------------------------------
**ÎÄ ¼þ Ãû:iousart.c
**´´ ½¨ ÈË: www.avrvi.com
**×îºóÐÞ¸ÄÈÕÆÚ: 2010Äê5ÔÂ7ÈÕ
**Ãè Êö: AVRÈí¼þ ´®¿ÚÇý¶¯,Õ¼Óö¨Ê±Æ÷1,ÎÞÒý½ÅÖжÏ
**×¢ Òâ: Èí¼þºÄʱ±È½Ï¶à,×¢Ò⿪ÖжÏ.
*********************************************************************************************************/
#include "config.h"
unsigned char Baud=0;
volatile unsigned char SimComBuf;
volatile unsigned char SimComTxSampleCycle=0;
volatile unsigned char bSimComTxing;//ÕýÔÚ·¢ËͱêÖ¾
unsigned char bSimComWaitCheck;//Êܵ½Ò»ÌõÃüÁî,µÈ´ý´¦Àí
unsigned char bSimComRxLoadBit;//ÒѽÓÊܵ½¿ªÊ¼Î»
volatile unsigned char bSimComRxDropEdge;//Õì²â¿ªÊ¼Î»µÄµÚÒ»ÖÜÆÚÒÑ¿ªÊ¼
volatile unsigned char SimComRxBitCount;//½ÓÊÜÒ»¸ö×Ö½Ú10λ¼ÆÊýÆ÷
volatile unsigned char SimComRxSampleCycle;//λ²ÉÑùÖÜÆÚ¼ÆÊýÆ÷
volatile unsigned char SimComRxBit,SimComRxSampleBuf;
unsigned char SimComSBuf;//½ÓÊܼĴæÆ÷ÔÝ´æ
unsigned char bSimComByteWaitCheck;//Êܵ½Ò»byte,µÈ´ý´¦Àí
volatile unsigned char SimComSendBitCount;//ÒÑ·¢ËÍλÊý¼ÆÊýÆ÷
volatile unsigned char SimComSendBuf;//·¢ËÍ»º³åÇø
unsigned char *ptSimComTxBuf;//·¢ËÍ»º³åÇøÖ¸Õë
unsigned char SimComSendByteCount;//ÒÑ·¢ËÍ×Ö½ÚÊý¼ÆÊýÆ÷
unsigned char SimComOutputA=0xff;
void iousart_init(unsigned char baudrate)
{
DDRTXD|=(1<<BITTXD);
PORTTXD|=(1<<BITTXD);
DDRRXD&=~(1<<BITRXD);
PORTRXD|=(1<<BITRXD);
TCCR0 = 0x00; //stop
Baud=baudrate;
switch (baudrate)
{
case 0: TCNT0 = 0xE0; //set count 0xC0 1200bps @14.7456Mhz
break;
case 1: TCNT0 = 0xF0; //set count 0xE0 2400bps @14.7456Mhz
break;
case 2: TCNT0 = 0xF8; //set count 0xF0 4800bps @14.7456Mhz
break;
case 3: TCNT0 = 0xFC; //set count 0xF8 9600bps @14.7456Mhz
break;
default:TCNT0 = 0xE0; //set count 1200bps @14.7456Mhz
}
TCCR0 = 0x03; //start timer
TIMSK |= (1<<TOIE0);
}
#pragma interrupt_handler timer0_ovf_isr:iv_TIMER0_OVF
void timer0_ovf_isr(void)
{
unsigned char i,j,bitStatu;
//unsigned char SimComOutputTemp;
switch (Baud)
{
case 0: TCNT0 = 0xE0; //set count 1200bps @14.7456Mhz
break;
case 1: TCNT0 = 0xF0; //set count 2400bps @14.7456Mhz
break;
case 2: TCNT0 = 0xF8; //set count 4800bps @14.7456Mhz
break;
case 3: TCNT0 = 0xFC; //set count 9600bps @14.7456Mhz
break;
default:TCNT0 = 0xE0; //set count 1200bps @14.7456Mhz
}
if((SimComOutputA & (1<<BITTXD)))
{
PORTTXD |= (SimComOutputA & (1<<BITTXD));//·¢ËÍ
}
else
{
PORTTXD &= SimComOutputA ; //·¢ËÍ
}
SimComBuf = PINRXD;//½ÓÊÕ
++SimComTxSampleCycle;
if(SimComTxSampleCycle>=3)
{
SimComTxSampleCycle=0;
}
//------½ÓÊÜ-------------------------
bitStatu=(1<<BITRXD);
//------SimCom RX-------
if(((bSimComTxing & bitStatu) == 0)
&& ((bSimComWaitCheck & bitStatu) == 0))
{
if((bSimComRxLoadBit & bitStatu) == 0)
{//¼ì²â¿ªÊ¼Î»
if((bSimComRxDropEdge & bitStatu) == 0)//δ¼ì²âµ½Ï½µÔµ£¬¼ÌÐø¼ì²â
{
if((SimComBuf & bitStatu) == 0)//²ÉÑùΪµ×µçƽ
{
SimComRxBitCount=0;
bSimComRxDropEdge |= bitStatu;
SimComRxSampleCycle=1;
SimComRxBit=0xff;
}
}
else//ÒѼì²âµ½Ï½µÔµ£¬¼ì²éÊÇ·ñΪÒýµ¼Î»
{
SimComRxSampleCycle++;
if(SimComRxSampleCycle==2)
{
if((SimComBuf & bitStatu)==0)//²ÉÑùΪµ×µçƽ
{
SimComRxBit=0;
}
else
{
SimComRxBit=0x80;
}
}
else if(SimComRxSampleCycle>=3)//ÒѲÉÑù3¸öÖÜÆÚ--1λ²ÉÑù½áÊø
{
if(SimComRxBit==0)
{
bSimComRxLoadBit |= bitStatu;//==¡®0¡¯
}
bSimComRxDropEdge &= ~bitStatu;
SimComRxSampleCycle=0;
SimComRxBitCount=0;
}
}
}
else
{//Êý¾ÝλºÍֹͣλ
//-----²ÉÑù1λ-----
SimComRxSampleCycle++;
if(SimComRxSampleCycle==1)
SimComRxBit=0xff;
if(SimComRxSampleCycle==2)
{
if((SimComBuf & bitStatu)==0)//²ÉÑùΪµ×µçƽ
SimComRxBit = 0;
else
SimComRxBit = 0x80;
}
else if(SimComRxSampleCycle >= 3)//ÿλ²ÉÑù3¸öÖÜÆÚ
{
SimComRxSampleCycle = 0;
//-----
++SimComRxBitCount;
if(SimComRxBitCount<=8)
{
SimComRxSampleBuf >>= 1;
SimComRxSampleBuf |= SimComRxBit;
}
else
{
bSimComRxLoadBit &= ~bitStatu;
bSimComRxDropEdge &= ~bitStatu;
if(SimComRxBit==0x80)
{//ÕýÈ·µÄֹͣλ
SimComSBuf=SimComRxSampleBuf;
bSimComByteWaitCheck |= bitStatu;
}
}
}
}
}
//------·¢ËÍÏÂһλ ------------------
if(SimComTxSampleCycle == 0)
{
SimComOutputA = 0xff;
if(bSimComTxing > 0)
{
SimComSendBitCount++;
if(SimComSendBitCount == 1)//Òýµ¼Î»
{
SimComOutputA &= ~bSimComTxing;
SimComSendBuf = *ptSimComTxBuf;
}
else if(SimComSendBitCount < 10)//8¸öÊý¾Ýλ
{
i=SimComSendBuf;
SimComSendBuf >>= 1;
if((i & 0x01) == 0)
SimComOutputA &= ~bSimComTxing;
}
else if(SimComSendBitCount == 10)//ֹͣλ
{
ptSimComTxBuf++;
SimComSendBitCount = 0;
if(SimComSendByteCount > 0)
{
SimComSendByteCount--;
}
if(SimComSendByteCount == 0)
{
bSimComTxing = 0;
}
}
/* else if(SimComSendBitCount >= 11)//ÐÝֹλ
{
SimComSendBitCount = 0;
if(SimComSendByteCount > 0)
{
SimComSendByteCount--;
}
if(SimComSendByteCount == 0)
{
bSimComTxing = 0;
}
} */
}
}
//SimComOutputA &=0x0f;
SEI();
}
unsigned char Get_Char(void)
{
while((bSimComByteWaitCheck&(1<<BITRXD))==0);
bSimComByteWaitCheck=0x00;
return SimComSBuf;
}
unsigned char Soft_Receive_one(void)
{
bSimComByteWaitCheck=0x00;
return SimComSBuf;
}
void Put_String(unsigned char *ptr,unsigned char num)
{
bSimComTxing=(1<<BITTXD);
SimComSendByteCount=num;
ptSimComTxBuf=ptr;
}
/* ÒÔÏÂΪ²âÊÔ
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x01; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main(void)
{
unsigned char TXBUF[10];
init_devices();
iousart_init(3);
while(1)
{
TXBUF[0]=Get_Char();
Put_String(TXBUF,1);
}
}
*/
[/code]
Í·Îļþ£º
[code="c"]
#ifndef __IOSOFTUSART__
#define __IOSOFTUSART__
#define DDRTXD DDRB
#define PORTTXD PORTB
#define BITTXD 6
#define DDRRXD DDRB
#define PORTRXD PORTB
#define PINRXD PINB
#define BITRXD 7
//¶¨Òå 14.7456Mhz ϲ¨ÌØÂʳ£Á¿
#define Baud_1200 0
#define Baud_2400 1
#define Baud_4800 2
#define Baud_9600 3
extern void iousart_init(unsigned char baudrate);
//´øËÀµÈµÄ½ÓÊÕ
extern unsigned char Get_Char(void);
//Ö±½Ó·µ»Ø,ÏÈÅжϺóµ÷ÓÃ,ËüÈ¡ÍêÊýÖ®ºó»á¸Ä±ä±ê־λ
extern unsigned char Soft_Receive_one(void);
//±ê־λ
extern unsigned char bSimComByteWaitCheck;
#define Soft_Receive_flag (bSimComByteWaitCheck&(1<<BITRXD))
extern void Put_String(unsigned char *ptr,unsigned char num);
#endif
[/code]
»¹ÓÐÖжϷ½Ê½µÄ¹æ»®£¬Çëµã»÷ÏÂÃæµÄÄ£Äâ´®¿Ú±êÇ©ÒÔ²éÕÒÏÂÔØÁ´½Ó¡£