1. 程式人生 > >通用GPIO模擬串列埠,提供原始碼,本人經過測試OK。(第一版)

通用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);
      }      
     }     
    }   

}