通用GPIO模擬串列埠,提供原始碼,本人經過測試OK。(第一版)
--------------------------serial.h------------------------------------------
#ifndef _SERIAL_H_
#define _SERIAL_H_
#define my_board
#ifdef my_board //只需修改這裡,就可移植到STM32等多種支援定時器的微控制器中。
void rx_timer_inter(void);
void tx_timer_inter(void);
void init_timer(void);
void start_tx_timer(void);//接收和傳送分別採用一個定時器
void start_rx_timer(void);
void stop_rx_timer(void);
void stop_rx_timer(void);
//GPIO模組串列埠TX
//GPIO模擬串列埠RX
void init_gpio(void); //配置TX為輸出,RX為輸入管腳,並設定TX管腳的初始狀態為1
unsigned char read_rx_line(void);
void write_tx_line(unsigned char dat);
#endif
//串列埠資訊的結構體
struct serial_t{
unsigned char digital;
unsigned char parriy; //none even odd
unsigned char stop;
unsigned char baud;
};
static struct serial_t serial;
static unsigned char tx_flag=0; //定時器修改此標誌
static unsigned char rx_flag=0; //
unsigned char make_odd_bit(unsigned char ch);
unsigned char make_even_bit(unsigned char ch);
unsigned char odd_check(unsigned char ch,unsigned char check);
unsigned char even_check(unsigned char ch,unsigned char check);
void serial_init(void);
unsigned char recv_one_bit(void);
unsigned char is_start_bit(void);
unsigned char is_stop_bit(void);
unsigned char recv_one_byte(unsigned char *ch);
unsigned char recv_n_byte(unsigned char *buf);
void send_one_byte(unsigned char ch);
void send_n_byte(unsigned char *buf,unsigned char num);
#endif
------------------------------------------------------------------
----------------------------serial.c--------------------------------
#include "serial.h"
#include "global.h"
#ifdef my_board
void rx_timer_inter(void)//中斷服務程式
{
rx_flag = 1;
}
void tx_timer_inter(void)//中斷服務程式
{
tx_flag = 1;
}
void init_timer(void)
{
STR_FP_ISR_CALLBACK fp;
fp = GetOldIsrCallback();
fp.Timer0 = tx_timer_inter;
RegIsrCallback(fp);
TimerInit(TIMER0,13334,0,INT);
fp = GetOldIsrCallback();
fp.Timer1 = rx_timer_inter;
RegIsrCallback(fp);
TimerInit(TIMER1,2667,0,INT);
}
void start_tx_timer(void)
{
StartTimer(TIMER0);
tx_flag = 0;
}
void start_rx_timer(void)
{
StartTimer(TIMER1);
rx_flag = 0;
}
void stop_tx_timer(void)
{
StopTimer(TIMER0);
}
void stop_rx_timer(void)
{
StopTimer(TIMER1);
}
//GPIO模組串列埠TX
//GPIO模擬串列埠RX
void init_gpio(void)
{
GpioInit(GPIOC,1,OUTPUT);
GpioBitOut(GPIOC,1,1);
GpioInit(GPIOC,2,INPUT);
}
unsigned char read_rx_line(void)
{
return GpioBitIn(GPIOC,2);
}
void write_tx_line(unsigned char dat)
{
GpioBitOut(GPIOC,1,dat);
}
void serial_init(void)
{
serial.digital = 8;
serial.stop = 1;
serial.parriy = 0;
serial.baud = 1; // BAUD = baud / 9600
init_timer();
init_gpio();
}
#endif
unsigned char make_odd_bit(unsigned char ch)
{
unsigned char check,i;
for(i=0;i<8;i++)
{
check += ( (ch & (1<<i)) >> i );
}
if(check % 2 == 0)
return 0;
else
return 1;
}
unsigned char make_even_bit(unsigned char ch)
{
unsigned char check,i;
for(i=0;i<8;i++)
{
check += ( (ch & (1<<i)) >> i );
}
if(check % 2 == 0)
return 1;
else
return 0;
}
unsigned char odd_check(unsigned char ch,unsigned char check)
{
unsigned char temp;
temp = make_odd_bit(ch);
if(temp == check)
return 1;
else
return 0;
}
unsigned char even_check(unsigned char ch,unsigned char check)
{
unsigned char temp;
temp = make_even_bit(ch);
if(temp == check)
return 1;
else
return 0;
}
unsigned char recv_one_bit(void)
{
unsigned char ch;
while(!rx_flag);
rx_flag = 0;
while(!rx_flag);
rx_flag = 0;
while(!rx_flag);
rx_flag = 0;
ch = read_rx_line();
while(!rx_flag);
rx_flag = 0;
while(!rx_flag);
rx_flag = 0;
return ch;
}
unsigned char is_start_bit(void)
{
unsigned char start_bit=1;
if(!rx_flag)
return 0;
rx_flag =0;
start_bit = read_rx_line(); //第一次取樣RX
if(start_bit)
return 0;
while(!rx_flag);
rx_flag = 0;
start_bit = read_rx_line(); //第二次取樣RX
if(start_bit)
return 0;
while(!rx_flag);
rx_flag = 0;
start_bit = read_rx_line(); //第三次取樣RX
if(start_bit)
return 0;
while(!rx_flag); //第4次
rx_flag = 0;
while(!rx_flag); //第5次
rx_flag = 0;
return 1;
}
unsigned char is_stop_bit(void)
{
return recv_one_bit();
}
unsigned char recv_one_byte(unsigned char *ch)
{
unsigned char i=0,temp=0;
unsigned char parriy_bit=0;
*ch =0;
if(!is_start_bit())
return 0;
for(;i<8;i++)
{
temp |= (recv_one_bit() << i);
}
if(serial.parriy == 0)
{
}
else if(serial.parriy == 1)
{
parriy_bit = recv_one_bit();
if(!even_check(temp,parriy_bit))
return 0;
}
else if(serial.parriy == 2)
{
parriy_bit = recv_one_bit();
if(!odd_check(temp,parriy_bit))
return 0;
}
else //Default:None
{
}
if(serial.stop == 1)
{
if(!is_stop_bit())
return 0;
}
else if(serial.stop == 2)
{
if(!is_stop_bit())
return 0;
if(!is_stop_bit())
return 0;
}
else //Default : stop =1
{
if(!is_stop_bit())
return 0;
}
*ch = temp;
return 1;
}
unsigned char recv_n_byte(unsigned char *buf)
{
unsigned int i=0;
unsigned int count=0;
unsigned int timeout = 200000;
unsigned char ch=0;
while(1)
{
if(recv_one_byte(&ch))
{
buf[i++] = ch;
count = 0;
}
else
{
count++;
if(count > timeout)
break;
}
}
return i;
}
void send_one_byte(unsigned char ch)
{
unsigned char i=0,parriy_bit;
tx_flag = 0;
start_tx_timer();
write_tx_line(1);
while(!tx_flag);
tx_flag = 0;
write_tx_line(0);
for(;i<8;i++)
{
while(!tx_flag);
if(ch & (1<< i))
write_tx_line(1);
else
write_tx_line(0);
tx_flag = 0;
}
if(serial.parriy == 0)
{
}
else if(serial.parriy == 1 )
{
parriy_bit = make_even_bit(ch);
while(!tx_flag);
write_tx_line(parriy_bit);
tx_flag = 0;
}
else if(serial.parriy == 2 )
{
parriy_bit = make_odd_bit(ch);
while(!tx_flag);
write_tx_line(parriy_bit);
tx_flag = 0;
}
else
{
;
}
if(serial.stop == 1)
{
while(!tx_flag);
write_tx_line(1);
tx_flag = 0;
}
else if(serial.stop == 2)
{
while(!tx_flag);
write_tx_line(1);
tx_flag = 0;
while(!tx_flag);
write_tx_line(1);
tx_flag = 0;
}
else
{
while(!tx_flag);
write_tx_line(1);
tx_flag = 0;
}
while(!tx_flag);
tx_flag = 0;
stop_tx_timer();
}
void send_n_byte(unsigned char *buf,unsigned char num)
{
unsigned char i=0;
for(i=0;i<num;i++)
{
send_one_byte(buf[i]);
}
}
-----------------------------main.c------------------------------
void main(void)
{
SetSysClk(PLL_CLK_128MHz);//
while(1)
{
send_n_byte("hello world !\r\n",sizeof("hello world !\r\n"));
_delay_ms(1000);
while(1)
{
ret = recv_n_byte(buf);
if(ret)
{
send_n_byte(buf,ret);
}
}
}
}