ATMEGA8A 單片機(jī)I/O口模擬串口
最近調(diào)試GPS的一個(gè)模塊,需要把數(shù)據(jù)從GPS讀取,再通過串口發(fā)送給PC機(jī)等一些功能。要用到2個(gè)串口,我使用了AMTEGA8A單片機(jī),所以用普通IO模擬做了一個(gè)串口?;宋覂蓚€(gè)晚上的時(shí)間,才調(diào)試好模擬串口程序,也遇到不少的問題,今天終于搞定了。但是還只是波特率1200,校驗(yàn)位N 數(shù)據(jù)8 停止1 ,以后再慢慢完善。
本文引用地址:http://www.ex-cimer.com/article/201609/296666.htm模擬串口主要是先要考慮到波特率和數(shù)據(jù)格式。我采用的1200的波特率,所以一個(gè)位的時(shí)間是:1s/1200=833.3333333us .這里我沒用定時(shí)器,我是用延時(shí)來實(shí)現(xiàn)定時(shí)的,一個(gè)位的延時(shí)時(shí)間定為833us,AVR里面的延時(shí)程序還是比較精確的,我用示波器觀察波形,也是正確的。一般串口協(xié)議(校驗(yàn)位N 數(shù)據(jù)8 停止1 )以我現(xiàn)在調(diào)試這個(gè)來說,比較簡單,一個(gè)起始位,8位數(shù)據(jù),一個(gè)停止位,每一位時(shí)間都是833us
以下是我調(diào)試的電路板子:
源程序:
/*******************ATMEGA8A_GPS****************************************/
/*****File Function : I/O模擬串口調(diào)試 *****/
/*****Program Author : ZhengWen(ClimberWin) *****/
/*****MCU : ATMEGA8A 內(nèi)部4M RC/外部4M 晶振 *****/
/*****Compile Date : 2010/10/19 *****/
/*****Edition Info : V1.0 *****/
/****************************************************************************/
//按鍵LED顯示測試OK
//修改時(shí)間:2010.10.20
//編寫模擬串口程序 define:PC3=RXD PC2=TXD
//串口發(fā)送OK,波特率設(shè)置為1200 校驗(yàn)位N 數(shù)據(jù)8 停止1
//修改時(shí)間:2010.10.21
//串口接收數(shù)據(jù)OK,+1后 返回發(fā)送給電腦
#include
#include //延時(shí)程序
#define uchar unsigned char
#define uint unsigned int
//引腳定義
#define IO_RXD 3 //PC3 模擬RXD
#define IO_TXD 2 //PC2 模擬TXD
#define LED1 4 //PD4 LED1
#define LED2 3 //PD3 LED2
#define KEY1 0 //PB0 按鍵1
#define KEY2 1 //PB1 按鍵2
/*位移宏定義*/
#define Set_Bit(val, bitn) (val |=(1<<(bitn))) //位置高
#define Clr_Bit(val, bitn) (val&=~(1<<(bitn))) //位置低
#define Get_Bit(val, bitn) (val &(1<<(bitn)) ) //取某一位的值
void keytest(void); //按鍵測試程序
void IO_int(void); //端口初始化配置
void IO_UART_Sent(uchar TXD_data);//模擬串口發(fā)送程序
uchar IO_UART_Receive(void); //模擬串口接收程序
void IO_int(void)
{
DDRD=0xff;//定義PORTD端口為輸出
DDRB=0xFC;//
DDRC=0xF7;//配置模擬串口輸入輸出
PORTD=0xFF;
PORTB=0xFF;
PORTC=0xFF;
}
void keytest(void) //按鍵測試程序
{
/*********************************************/
if(Get_Bit(PINB,KEY1)==0)
{
Clr_Bit(PORTD,LED1);
IO_UART_Sent(0xaa);
//////////////////
while(Get_Bit(PINB,KEY1)==0) //按鍵去抖
{ _delay_ms(1000);}
}
/**********************************************/
if(Get_Bit(PINB,KEY2)==0)
{
Clr_Bit(PORTD,LED2);
IO_UART_Sent(0x74);
//////////////////
while(Get_Bit(PINB,KEY2)==0) //按鍵去抖
{ _delay_ms(1000);}
}
/******************************************/
Set_Bit(PORTD,LED1);
Set_Bit(PORTD,LED2);
}
///////////////////////模擬串口發(fā)射程序//////////////////
void IO_UART_Sent(uchar TXD_data) //波特率1200
{
uchar i;
uchar Sent_SBUF;
Sent_SBUF=TXD_data;
Clr_Bit(PORTC,IO_TXD);//發(fā)送起始位START
_delay_us(833);
while(i<8) //發(fā)送8位數(shù)據(jù)
{
Clr_Bit(PORTD,LED1);
if(Sent_SBUF & 0x01)
{Set_Bit(PORTC,IO_TXD);}
else
{Clr_Bit(PORTC,IO_TXD);}
Sent_SBUF>>=1;
_delay_us(833);
i++;
Set_Bit(PORTD,LED1);
}
Set_Bit(PORTC,IO_TXD);//發(fā)送STOP信號
_delay_us(833);
}
///////////////////////模擬串口接收程序//////////////////
uchar IO_UART_Receive(void) //波特率1200
{
uchar i;
uchar Recieve_SBUF=0x00;
i=0x00;
while(Get_Bit(PINC,IO_RXD));
_delay_us(833);
while(i<8)
{
Clr_Bit(PORTD,LED2);
Recieve_SBUF>>=1;
if(Get_Bit(PINC,IO_RXD))
{Recieve_SBUF|=0x80;}
i++;
_delay_us(833);
Set_Bit(PORTD,LED2);
}
while(!Get_Bit(PINC,IO_RXD));
return Recieve_SBUF;
}
//////////////////主程序///////////////////////
int main()
{
uchar i;
_delay_ms(100); //開機(jī)延時(shí)
IO_int(); //IO初始化配置
_delay_ms(100);//開機(jī)延時(shí)
IO_UART_Sent(0x55); //發(fā)送0x55測試
while(1)
{
i=IO_UART_Receive();
_delay_ms(20);
IO_UART_Sent(0xaa);
_delay_ms(20);
IO_UART_Sent(i+1); //如果接收到串口數(shù)據(jù)后 ,+1 發(fā)送回給PC機(jī)
}
}
評論