| 单片机通用模拟串口C程序 |
| 类别:单片机/DSP |
| //----------------------------------------------------------------------
// 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; } ;************************************************************ |
- pic16单片机应..
- 2008-1-9
- 基于单片机的某车型..
- 2008-1-7
- 基于ARM的FPG..
- 2008-1-7
- 基于单片机的电热水..
- 2007-11-15
- 一种基于单片机的汽..
- 2007-11-15
- 基于单片机的电子导..
- 2007-11-8
- 51单片机边沿触发..
- 2007-11-8
- 如何选择细纱机主电..
- 2007-11-5
- 单片机编程技巧
- 2007-9-14
- 空压机变频改造技术..
- 2007-9-3
- 运用定点DSP实现..
- 2007-8-7
- 基于TMS320C..
- 2007-8-9
- 一种用于图像认证的..
- 2007-7-29
- TMS320F20..
- 2007-8-9
- 多DSP系统互连方..
- 2007-8-9
- C5402 DSP..
- 2007-8-9
- 具有高可靠性的高速..
- 2007-8-9
- 基于DSP的实时M..
- 2007-8-7
- 带ARM核的双CP..
- 2007-8-9
- 基于TMS320V..
- 2007-8-9



