打印
[应用方案]

模拟串口C语言程序代码

[复制链接]
223|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tifmill|  楼主 | 2024-6-24 23:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


[code]#include "string.h"   
#include "stdio.h"   
#include   
sfr16   DPTR = 0x82;   
   
typedef unsigned char   INT8U;   
typedef unsigned int    INT16U;   
typedef unsigned char   uint8_t;   
typedef unsigned int    uint16_t;   
typedef unsigned int    uchar;   
typedef unsigned char   byte;   
typedef unsigned int    word;   
   
#define YES   1   
#define NO    0   
   
//定义使用哪个定时器, 只可定义一个      
#define TIMER_0   
//#define TIMER_1   
   
//定义串口收、发送管脚。     
sbit rs_TXD = P2^1;   
sbit rs_RXD = P2^0;   
   
//根据定时器确定参数     
#ifdef TIMER_0   
    #define TMOD_AND_WORD   0xF0;   
    #define TMOD_TIME_MODE  0x01;   
    #define TMOD_COUNT_MODE 0x05;      //设置计数模式位     
    sbit  TCON_ENABLE_TIMER = TCON^4;   
    sbit  TCON_TFx = TCON^5;           //中断标志位     
    sbit  IE_ETx = IE^1;               //中断允许位为 ET0     
    sbit  IP_PTx = IP^1;               //中断优先级     
   
    sfr rs_timerL = 0x8A;              //TL0   
    sfr rs_timerH = 0x8C;              //TH0   
#endif   
   
#ifdef TIMER_1   
    #define TMOD_AND_WORD   0x0F;   
    #define TMOD_TIME_MODE  0x10;   
    #define TMOD_COUNT_MODE 0x50;      //设置计数模式位     
    sbit  TCON_ENABLE_TIMER = TCON^6;  //   
    sbit  TCON_TFx = TCON^7;           //中断标志位     
    sbit  IE_ETx = IE^3;               //中断允许位为 ET1      
    sbit  IP_PTx = IP^4;               //中断优先级     
   
    sfr rs_timerL = 0x8B;              //TL1   
    sfr rs_timerH = 0x8D;              //TH1     
#endif   
   
INT8U   bdata rs_BUF;                  //串行收、发时用的移位暂存器。      
sbit    rs_BUF_bit7 = rs_BUF^7;        //移位暂存器的最高位。   
INT8U   rs_shift_count;                //移位计数器。     
   
INT8U   bdata rsFlags;   
sbit    rs_f_TI        = rsFlags^0;    //0:正在发送; 1: 一个字符完毕     
sbit    rs_f_RI_enable  = rsFlags^1;   //0:禁止接收; 1:允许接收     
sbit    rs_f_TI_enable  = rsFlags^2;   //0:禁止发送; 1:允许发送     
   
//选择以下一个晶体频率   
//#define Fosc 6000000                 //6MHz   
#define Fosc 11059200                  //11.059MHz   
//#define Fosc 12000000   
//#define Fosc 18432000   
//#define Fosc 20000000   
//#define Fosc 24000000   
//#define Fosc 30000000   
//#define Fosc 40000000   
   
//选择以下一个波特率:   
//#efine Baud 300                      //11.059MHz时,baud 最低为 300      
//#define Baud 1200   
//#define Baud 2400   
//#define Baud 4800   
#define Baud 9600   
//#define Baud 14400   
//#define Baud 19200   
//#define Baud 28800   
//#define Baud 38400   
//#define Baud 57600   
   
//收、发一位所需定时器计数      
#define rs_FULL_BIT0 ((Fosc/12) / Baud)   
#define rs_FULL_BIT (65536 - rs_FULL_BIT0)   
#define rs_FULL_BIT_H rs_FULL_BIT >> 8        //收、发一位所需定时器计数高位      
#define rs_FULL_BIT_L (rs_FULL_BIT & 0x00FF)  //收、发一位所需定时器计数低位      
   
//检测起始位的时间间隔所需定时器计数      
#define rs_TEST0 rs_FULL_BIT0 / 4             //波特率较低时可以除以 3 或除以 2      
#define rs_TEST ((~rs_TEST0))   
#define rs_TEST_H rs_TEST >> 8                //高位     
#define rs_TEST_L rs_TEST & 0x00FF            //低位     
   
//发送起始位所需定时器总计数      
#define rs_START_BIT 0xFFFF - (Fosc/12/Baud) + 0x28   
#define rs_START_BIT_H rs_START_BIT >> 8      //发送起始位所需定时器计数高位      
#define rs_START_BIT_L rs_START_BIT & 0x00FF  //发送起始位所需定时器计数低位      
   
#define rs_RECEIVE_MAX   32                  //最大接收长度     
INT8U   idata rs232buffer[rs_RECEIVE_MAX];      //收、发缓冲区   
INT16U  ReceivePoint;                         //接收数据存储指针     
   
void soft_rs232_interrupt( void );   
   
#ifdef TIMER_0   
    void timer0 (void) interrupt 1 using 3   
    {   
        if (rs_RXD == 0 | rs_shift_count > 0)   
        { soft_rs232_interrupt(); }   
        else   
        {   
            rs_timerH = rs_TEST_H;   
            rs_timerL = rs_TEST_L;   
        }   
    }   
#endif   
   
#ifdef TIMER_1   
    void timer1 (void) interrupt 3 using 3   
    {   
        if (rs_RXD == 0 | rs_shift_count > 0)   
        { soft_rs232_interrupt(); }   
        else   
        {   
            rs_timerH = rs_TEST_H;   
            rs_timerL = rs_TEST_L;   
        }   
    }   
#endif   
  
   
void soft_rs232_init (void)            //串口初始化     
{   
    TCON_ENABLE_TIMER = 0;             //停止定时器     
    TMOD &= TMOD_AND_WORD;   
    TMOD |= TMOD_TIME_MODE;   
    rs_RXD = 1;                        //接收脚置成高电平     
    rs_TXD = 1;                        //发射脚置成高电平     
    IP_PTx = 1;                        //置中断优先级为高     
    IE_ETx = 1;                        //允许定时器中断      
}   
   
void soft_receive_init()               //监测起始位     
{   
    TCON_ENABLE_TIMER = 0;             //停止定时器     
    rs_timerH = rs_TEST_H;   
    rs_timerL = rs_TEST_L;   
    rs_shift_count = 0;   
    TCON_ENABLE_TIMER = 1;             //启动定时器     
}   
   
   
void soft_receive_enable()             //允许接收     
{   
    rs_f_RI_enable = 1;                //允许接收     
    rs_f_TI_enable = 0;                //禁止发送      
    soft_receive_init();               //监测起始位, RXD 下降沿触发接收字节过程.        
}   
   
void soft_send_enable (void)           //允许发送     
{   
    TCON_ENABLE_TIMER = 0;             //停止定时器     
    rs_f_TI_enable = 1;                //允许发送     
    rs_f_RI_enable = 0;                //禁止接收     
   
    rs_shift_count = 0;                //清移位计数器     
    rs_f_TI   = 1;                     //发送一个字符完毕标志     
    TCON_ENABLE_TIMER = 1;             //启动定时器   
}   

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

39

主题

1201

帖子

0

粉丝