单片机通用模拟串口C程序

上一篇 / 下一篇  2008-10-08 09:32:48

片机通用模拟串口C程序

 //---------------------------------------------------------------------- 
  // UART.C
  // 通用模拟串口程序
  // 资源需求:一个硬件计数器,两个I/O口
  // 硬件计数器的计数时间设定为三倍波特率
  // 定义的两个I/O口,用于发送和接收,分别用在receive()和transmit(char)中
  // 设立了专门的接收缓冲区,用于存储接收数据
  // 注意:必需根据波特率来设定定时器;
  //        每次通信开始必须调用初始化函数init_uart()
  //----------------------------------------------------------------------------------------------------------------
  //----------------------------------管脚定义、库函数声明-------------------------------------------------
  #include <reg51.h>
  #include <stdio.h>
  //端口定义
  sbit RXD3=P1^0;
  sbit TXD3=P1^1;
  //-----------------------------------------------变量声明-----------------------------------------------------
  #define IN_BUF_SIZE 10           //输入缓冲区长度定义
  #define TRUE 1
  #define FALSE 0
  static unsigned char inbuf[IN_BUF_SIZE];  //输入缓冲区
  static unsigned char qin = 0;
  static unsigned char qout = 0;
  static char flag_rx_waiting_for_stop_bit;
  static char flag_rx_off;
  static char rx_mask;
  static char flag_rx_ready;
  static char flag_tx_ready;
  static char timer_rx_ctr;
  static char timer_tx_ctr;
  static char bits_left_in_rx;
  static char bits_left_in_tx;
  static char rx_num_of_bits;
  static char tx_num_of_bits;
  static char internal_rx_buffer;
  static char internal_tx_buffer;
  static char user_tx_buffer;
  //----------------------------------与硬件有关的函数声明------------------------------------------------
  bit get_rx_pin_status();                       //1.返回接收管脚返回的值(0或1)
  void set_tx_pin_high(void);                    //2. 发送管脚置高,输出1
  void set_tx_pin_low();                        //3.发送管脚置低,输出0
  void timer_set();                             //4. 设置定时器的值为波特率的三倍
  void set_timer_interrupt();                     //5. 使能定时器中断
  void  idle();                                //6.等待端口输入时,执行,根据具体应用进行修改
  //-----------------------------------声明与硬件无关的函数-------------------------------------------
  void flush_input_buffer( void );                  // 清空接收缓存区
  char kbhit( void );                             // 判断数据是否正常接收
  char get_char( void );                          // 从接收缓存区读出一个数据
  void turn_rx_on( void );                        // 启动接收函数
  void turn_rx_off( void );                        // 结束接收函数
  extern void put_char( char );                     // 向发送端发送一个数据.
  void timer_isr(void);                          //中断处理函数
  //-------------------------------------------------------------------------------------------------------
  //  函数名称:set_tx_pin_high
  //  功能说明: 置串口发送端口为高,与硬件有关
  //--------------------------------------------------------------------------------------------------------
  void  set_tx_pin_high( void)
  {
  TXD3=1;
  }
  //-------------------------------------------------------------------------------------------------------
  //  函数名称: set_tx_pin_low
  //  功能说明: 置串口发送端口为低,与硬件有关
  //--------------------------------------------------------------------------------------------------------
  void set_tx_pin_low( void)
  {
  TXD3=0;
  }
  //-------------------------------------------------------------------------------------------------------
  //  函数名称:get_rx_pin_status
  //  功能说明: 返回接收端口的状态,高为1,低为0,与硬件有关
  //--------------------------------------------------------------------------------------------------------
  bit get_rx_pin_status()
  {
  return(RXD3);
  }
  //-------------------------------------------------------------------------------------------------------
  //  函数名称: timer_set
  //  功能说明: 设置定时器工作状态,与硬件有关
  //--------------------------------------------------------------------------------------------------------
  void timer_set()
  {
  TMOD=0x22;  //定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装)
  PCON=0x00;
  TR0=0;        //在发送或接收才开始使用
  TF0=0;
  TH0=(256-96);  //9600bps 就是 1000000/9600=104.167微秒 执行的timer是
  //104.167*11.0592/12= 96
  TL0=TH0;
  ET0=1;
  }
  //-------------------------------------------------------------------------------------------------------
  //  函数名称: set_timer_interrupt
  //  功能说明: 打开定时器中断允许,与硬件有关
  //--------------------------------------------------------------------------------------------------------
  void set_timer_interrupt()
  {
  EA=1;
  }
  //-------------------------------------------------------------------------------------------------------
  //  函数名称: IntTimer0
  //  功能说明: 定时器中断函数,与硬件有关,但不做处理,直接调用通用中断处理函数
  //--------------------------------------------------------------------------------------------------------
  void IntTimer0() interrupt 1
  {
  timer_isr();              //调用中断处理函数
  }
  //-------------------------------------------------------------------------------------------------------
  //  函数名称: idle
  //  功能说明: 等待定时器中断时的执行程序,与具体应用有关
  //--------------------------------------------------------------------------------------------------------
  void idle()
  {
  }
  //-------------------------------------------------------------------------------------------------------
  //  函数名称: timer_isr
  //  功能说明: 中断处理函数,与硬件无关,通用函数
  //--------------------------------------------------------------------------------------------------------
  void timer_isr(void)        /*中断服务程序*/
  {
  char mask, start_bit, flag_in;
  //发送程序
  if ( flag_tx_ready )
  {
  if ( --timer_tx_ctr<=0 )
  {
  mask = internal_tx_buffer&1;
  internal_tx_buffer >>= 1;
  if ( mask )
  {
  set_tx_pin_high();
  }
  else
  {
  set_tx_pin_low();
  }
  timer_tx_ctr = 3;
  if ( --bits_left_in_tx<=0 )
  {
  flag_tx_ready = FALSE;
  }
  }
  }
  // 接收程序
  if ( flag_rx_off==FALSE )
  {
  if ( flag_rx_waiting_for_stop_bit )
  {
  if ( --timer_rx_ctr<=0 )
  {
  flag_rx_waiting_for_stop_bit = FALSE;
  flag_rx_ready = FALSE;
  internal_rx_buffer &= 0xFF;
  if ( internal_rx_buffer!=0xC2 )
  {
  inbuf[qin] = internal_rx_buffer;
  if ( ++qin>=IN_BUF_SIZE )
  {
  qin = 0;
  }
  }
  }
  }
  else                            // rx_test_busy接收忙
  {
  if ( flag_rx_ready==FALSE )
  {
  start_bit = get_rx_pin_status();
  // 判断起始位
  if ( start_bit==0 )
  {
  flag_rx_ready = TRUE;
  internal_rx_buffer = 0;
  timer_rx_ctr = 4;
  bits_left_in_rx =
  rx_num_of_bits;
  rx_mask = 1;
  }
  }
  else
  {
  if ( --timer_rx_ctr<=0 )
  {
  timer_rx_ctr = 3;
  flag_in =
  get_rx_pin_status();
  if ( flag_in )
  {
  internal_rx_buffer |= rx_mask;
  }
  rx_mask <<= 1;
  if ( --bits_left_in_rx<=0 )
  {
  flag_rx_waiting_for_stop_bit = TRUE;
  }
  }
  }
  }
  }
  }
  //-------------------------------------------------------------------------------------------------------
  //  函数名称: init_uart
  //  功能说明: 初始化异步串口,与硬件无关,通用函数
  //--------------------------------------------------------------------------------------------------------
  void init_uart( void )
  {
  flag_tx_ready = FALSE;
  flag_rx_ready = FALSE;
  flag_rx_waiting_for_stop_bit = FALSE;
  flag_rx_off = FALSE;
  rx_num_of_bits = 10;
  tx_num_of_bits = 10;
  set_tx_pin_low();
  timer_set();
  set_timer_interrupt();               // 使能计时器中断
  }
  //-------------------------------------------------------------------------------------------------------
  //  函数名称: get_char
  //  输入参数: 无
  //  输出参数: ch,接收数据
  //  功能说明: 接收一个字节,与硬件无关,通用函数
  //--------------------------------------------------------------------------------------------------------
  char get_char( void )
  {
  char ch;
  do
  {
  while ( qout==qin )
  {
  idle();
  }
  ch = inbuf[qout] & 0xFF;
  if ( ++qout>=IN_BUF_SIZE )
  {
  qout = 0;
  }
  }
  while ( ch==0x0A || ch==0xC2 );
  return( ch );
  }
  //-----------------------------------------------------------------------------------------
  //  函数名称: put_char
  //  功能说明: 接收一个字节,与硬件无关,通用函数
  //-----------------------------------------------------------------------------------------
  void put_char( char ch )
  {
  while ( flag_tx_ready );
  user_tx_buffer = ch;
  // 唤醒串口
  timer_tx_ctr = 3;
  bits_left_in_tx = tx_num_of_bits;
  internal_tx_buffer = (user_tx_buffer<<1) | 0x200;
  flag_tx_ready = TRUE;
  }
  //-------------------------------------------------------------------------------------------------------
  //  函数名称: flush_input_buffer
  //  功能说明:初始化缓冲区,与硬件无关,通用函数
  //--------------------------------------------------------------------------------------------------------
  void flush_input_buffer( void )
  {
  qin = 0;
  qout = 0;
  }
  //-----------------------------------------------------------------------------------------
  //  函数名称: kbhit
  //  功能说明: 判断接收指针与发送指针是否相等,与硬件无关,通用函数
  //-----------------------------------------------------------------------------------------
  char kbhit( void )
  {
  return( qin!=qout );
  }
  //-----------------------------------------------------------------------------------------
  //  函数名称: turn_rx_on
  //  功能说明: 开始接收,与硬件无关,通用函数
  //-----------------------------------------------------------------------------------------
  void turn_rx_on( void )
  {
  flag_rx_off = FALSE;
  }
  //-----------------------------------------------------------------------------------------
  //  函数名称: turn_rx_off
  //  功能说明: 停止接收,与硬件无关,通用函数
  //-----------------------------------------------------------------------------------------
  void turn_rx_off( void )
  {
  flag_rx_off = TRUE;
  }
  ;************************************************************

    本文可能所用到的IC型号: UC2827N-1 XC9201D09AKR 2SC4639 SMP402TNC 74LVT00DB AN3915S-E1 AN8488SB-E1 AT49F001ANT-55JU SN104818DBTR MX27C512MC-12

TAG:

 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

日历

« 2008-11-24  
      1
2345678
9101112131415
16171819202122
23242526272829
30      

数据统计

  • 访问量: 2477
  • 日志数: 356
  • 建立时间: 2008-04-22
  • 更新时间: 2008-11-21

RSS订阅

Open Toolbar