程序文件
[code="c"]
/*********************************************************************************************************
** AVR軟件 串口驅(qū)動(dòng)
** (c) Copyright 2010, limaokui
** All Rights Reserved
**
** V1.0.0
**
**
**--------------文件信息--------------------------------------------------------------------------------
**文 件 名:iousart.c
**創(chuàng) 建 人: www.avrvi.com
**最后修改日期: 2010年5月7日
**描 述: AVR軟件 串口驅(qū)動(dòng),占用定時(shí)器1,無引腳中斷
**注 意: 軟件耗時(shí)比較多,注意開中斷.
*********************************************************************************************************/
#include "config.h"
unsigned char Baud=0;
volatile unsigned char SimComBuf;
volatile unsigned char SimComTxSampleCycle=0;
volatile unsigned char bSimComTxing;//正在發(fā)送標(biāo)志
unsigned char bSimComWaitCheck;//受到一條命令,等待處理
unsigned char bSimComRxLoadBit;//已接受到開始位
volatile unsigned char bSimComRxDropEdge;//偵測(cè)開始位的第一周期已開始
volatile unsigned char SimComRxBitCount;//接受一個(gè)字節(jié)10位計(jì)數(shù)器
volatile unsigned char SimComRxSampleCycle;//位采樣周期計(jì)數(shù)器
volatile unsigned char SimComRxBit,SimComRxSampleBuf;
unsigned char SimComSBuf;//接受寄存器暫存
unsigned char bSimComByteWaitCheck;//受到一byte,等待處理
volatile unsigned char SimComSendBitCount;//已發(fā)送位數(shù)計(jì)數(shù)器
volatile unsigned char SimComSendBuf;//發(fā)送緩沖區(qū)
unsigned char *ptSimComTxBuf;//發(fā)送緩沖區(qū)指針
unsigned char SimComSendByteCount;//已發(fā)送字節(jié)數(shù)計(jì)數(shù)器
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));//發(fā)送
}
else
{
PORTTXD &= SimComOutputA ; //發(fā)送
}
SimComBuf = PINRXD;//接收
++SimComTxSampleCycle;
if(SimComTxSampleCycle>=3)
{
SimComTxSampleCycle=0;
}
//------接受-------------------------
bitStatu=(1<<BITRXD);
//------SimCom RX-------
if(((bSimComTxing & bitStatu) == 0)
&& ((bSimComWaitCheck & bitStatu) == 0))
{
if((bSimComRxLoadBit & bitStatu) == 0)
{//檢測(cè)開始位
if((bSimComRxDropEdge & bitStatu) == 0)//未檢測(cè)到下降緣,繼續(xù)檢測(cè)
{
if((SimComBuf & bitStatu) == 0)//采樣為底電平
{
SimComRxBitCount=0;
bSimComRxDropEdge |= bitStatu;
SimComRxSampleCycle=1;
SimComRxBit=0xff;
}
}
else//已檢測(cè)到下降緣,檢查是否為引導(dǎo)位
{
SimComRxSampleCycle++;
if(SimComRxSampleCycle==2)
{
if((SimComBuf & bitStatu)==0)//采樣為底電平
{
SimComRxBit=0;
}
else
{
SimComRxBit=0x80;
}
}
else if(SimComRxSampleCycle>=3)//已采樣3個(gè)周期--1位采樣結(jié)束
{
if(SimComRxBit==0)
{
bSimComRxLoadBit |= bitStatu;//==‘0’
}
bSimComRxDropEdge &= ~bitStatu;
SimComRxSampleCycle=0;
SimComRxBitCount=0;
}
}
}
else
{//數(shù)據(jù)位和停止位
//-----采樣1位-----
SimComRxSampleCycle++;
if(SimComRxSampleCycle==1)
SimComRxBit=0xff;
if(SimComRxSampleCycle==2)
{
if((SimComBuf & bitStatu)==0)//采樣為底電平
SimComRxBit = 0;
else
SimComRxBit = 0x80;
}
else if(SimComRxSampleCycle >= 3)//每位采樣3個(gè)周期
{
SimComRxSampleCycle = 0;
//-----
++SimComRxBitCount;
if(SimComRxBitCount<=8)
{
SimComRxSampleBuf >>= 1;
SimComRxSampleBuf |= SimComRxBit;
}
else
{
bSimComRxLoadBit &= ~bitStatu;
bSimComRxDropEdge &= ~bitStatu;
if(SimComRxBit==0x80)
{//正確的停止位
SimComSBuf=SimComRxSampleBuf;
bSimComByteWaitCheck |= bitStatu;
}
}
}
}
}
//------發(fā)送下一位 ------------------
if(SimComTxSampleCycle == 0)
{
SimComOutputA = 0xff;
if(bSimComTxing > 0)
{
SimComSendBitCount++;
if(SimComSendBitCount == 1)//引導(dǎo)位
{
SimComOutputA &= ~bSimComTxing;
SimComSendBuf = *ptSimComTxBuf;
}
else if(SimComSendBitCount < 10)//8個(gè)數(shù)據(jù)位
{
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;
}
/* 以下為測(cè)試
//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);
//直接返回,先判斷后調(diào)用,它取完數(shù)之后會(huì)改變標(biāo)志位
extern unsigned char Soft_Receive_one(void);
//標(biāo)志位
extern unsigned char bSimComByteWaitCheck;
#define Soft_Receive_flag (bSimComByteWaitCheck&(1<<BITRXD))
extern void Put_String(unsigned char *ptr,unsigned char num);
#endif
[/code]
還有中斷方式的方案,請(qǐng)點(diǎn)擊下面的模擬串口標(biāo)簽以查找下載鏈接。