AVR软件模拟串口程序来源:coldra资料室 作者:coldra
输出:用定时器控制普通IO口输出位
输入:用外部中断+定时器,判断位的宽度
好几天没休息,利用闲暇写的,也没找到别人的参考程序,不过终于算是稳定了,其实还应该有很多其它的方法可以试一下,比如用PWM输出串行数据,用输入捕获接收数据,或定时查询,或用任意一个IO口中断,则每个引脚都有可能
现在还有些问题,全双工同时收发时发送偶尔出错,占用两个定时器有些浪费,以后再修改吧,最好加上各种波率
本程序为直接摘出部分,删了无关的部分,在此可能有些变量没用,或有段落遗漏,请谅
#include
#include
#include
#include
#define Sbit1() PORTD =1<#define Sbit0() PORTD&=~(1<
volatile unsigned int
eep_ms,//毫秒计时
keytime, //等待时间
SoundOnTime; ////
volatile unsigned char
rdata,
key,
start=0,
keycode, //
*TxPoint,
rtime,
INT0_time, //中断次数
RxLength=0, //接收长度
RUDR, //摸拟串口接收的数据
TxLength, //串口发送数据长度
SUDR; //串口发送的数据
unsigned char arr[10],DispBuff[10];
void Initial_IO(void)//IO口初始化
{
DDRD = 0X82; //PD1串口输出,PD0串口输入,PD2模拟串口输入(INT0)
PORTD = 0X82; //PD1输出高电平
}
void Initial_INT0(void)
{
EICRA =(1< EIMSK =1< }
void Initial_timer0(void) //定时器0初始化
{
TCCR0B =(1< TIMSK0 =(1< }
void Initial_timer1(void)
{
TCCR1A=(1< TCCR1B=(1< ICR1=1000;
TIMSK1 =(1< }
void Initial_timer2(void)
{
TCCR2B=(1< TIMSK2 =(1< }
void Initial_WDR(void) //看门狗初始化
{
wdt_enable(WDTO_1S);
wdt_reset();
}
void Initial(void)
{
Initial_IO();
Initial_timer0();
Initial_timer1();
Initial_timer2();
Initial_INT0();
Initial_WDR();
sei();
}
/*启动串口发送*/
void SendData(unsigned char *P,unsigned char DataLength)
{
TxLength=DataLength;
TxPoint=P;
start=0;
}
int main (void)
{
Initial();
while(1)
{
wdt_reset();
if((rdata)&&(eep_ms>10))//收到数据延时10mS后启动发送,回送验证数据
{
key=0;
SendData(&DispBuff[0],9);//发送DispBuff[0]的9位数据
while(TxLength);//等待发送完成
rdata=0;
eep_ms=0;
}
}
}