不知道谁做过模拟串口,现在手上有STC的模拟串口,自己也尝试在上面修改,可惜水平有限。

大家做STC的话可以参考下,谁有现成的AVR模拟串口的程序能不能发出来参考下,谢谢

#include

sfr16        DPTR = 0x82;

typedef        unsigned char        INT8U;

typedef        unsigned int        INT16U;

#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   128                  //最大接收长度

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;             //启动定时器

}

void soft_rs232_interrupt( void )

{

/************************ 接收 ****************************/

if (rs_f_RI_enable == 1)

{

if (rs_shift_count == 0)        //移位计数器==0, 表示检测到起始位的起点

{

if ( rs_RXD == 1 )

{

soft_receive_enable (); //起始位错, 从新开始

}

else

{

//下次中断在数据位或停止位中的某时刻发生

rs_timerL += rs_FULL_BIT_L + 0x10;

rs_timerH = rs_FULL_BIT_H;

rs_shift_count++;

rs_BUF = 0;             //清移位缓冲变量

}

}

else

{

rs_timerL += rs_FULL_BIT_L; //下次中断在数据位或停止位中发生

rs_timerH = rs_FULL_BIT_H;

rs_shift_count++;           //2--9:数据位 10:停止位

if ( rs_shift_count == 9)

{

rs_BUF = rs_BUF >> 1;   //接收第8位

rs_BUF_bit7 = rs_RXD;

if( ReceivePoint < rs_RECEIVE_MAX)

{                       //保存收到的字节

rs232buffer[ReceivePoint++] = rs_BUF;

}

else

{

rs_f_RI_enable = 0; //缓冲区满, 禁止接收

}

}

else

{

if (rs_shift_count < 9 ) //收到的是数据位 1 -- 7

{

rs_BUF = rs_BUF >> 1;

rs_BUF_bit7 = rs_RXD;

}

else

{   //收到停止位,继续检测 PC 机发出的下一个起始位

soft_receive_init();

}

}

}

TCON_TFx = 0;                  //清定时器中断标志

}

else

{

/************************ 发送 ****************************/

if (rs_f_TI_enable == 1)

{

rs_timerL += rs_FULL_BIT_L;//下次中断在数据位的末尾时刻

rs_timerH = rs_FULL_BIT_H;

rs_shift_count--;          //0:停止位末尾时刻到

//1:发送停止位

//2--9:发送数据位

if (rs_shift_count > 9)    //错误状态

{

rs_shift_count = 9;

rs_BUF = 0xFF;

}

if (rs_shift_count > 1)    //2--9:发送数据位

{

ACC = rs_BUF;

ACC = ACC >> 1;

rs_TXD = CY;

rs_BUF = ACC;

}

else

{

if (rs_shift_count == 0) //0:停止位末尾时刻到

{

rs_TXD = 1;

rs_f_TI = 1;       //已发送完毕一个字节

}

else

{

rs_TXD = 1;        //1:发送停止位

}

}

}

}

}

//由收转到发时,要先调用 soft_send_enable ()

void rs_send_byte(INT8U SendByte)      //发送一个字节

{

while ( rs_f_TI == 0);             //等待发送完毕前一个字节

rs_TXD = 1;

rs_timerL = rs_START_BIT_L;        //下次中断在起始位的末尾时刻

rs_timerH = rs_START_BIT_H;

rs_BUF = SendByte;

rs_shift_count = 10;

rs_TXD = 0;                        //发送起始位

rs_f_TI = 0;                       //清已发送完毕一个字节的标志

}

void initiate_MCU (void)               //系统初始化

{

soft_rs232_init();                 //串口初始化

EA = 1;                            //开中断

}

void main (void)

{

//首先发送 128 个字节 00H--7FH, 然后等待 PC 机发送的数据。当收到 128

//个字节后,立刻将收到的 128 个数据回发送给 PC 机,然后继续等待下一个

//数据块。

INT8U i;

initiate_MCU();                    //系统初始化

soft_send_enable ();               //允许发送,禁止接收

for (i=0; i < rs_RECEIVE_MAX; i++ )

{

rs_send_byte(i);

}

while ( rs_f_TI == 0)  ;           // 等待最后一个字节发送完毕

while(1)

{

soft_receive_enable ();        //启动并开始接收,禁止发送

while (ReceivePoint < rs_RECEIVE_MAX); // 等待接收缓冲区满

soft_send_enable ();           //允许发送,禁止接收

for (i=0; i < rs_RECEIVE_MAX; i++ )

{

rs_send_byte(rs232buffer);

}

while ( rs_f_TI == 0)  ;       //等待最后一个字节发送完毕

ReceivePoint = 0;

}

}

avr模拟串口通讯c语言,AVR的模拟串口的问题相关推荐

  1. avr模拟串口通讯c语言,AVR简单的串口通信程序

    本例子是学习AVR的串口通信时候编写的一个简单的串口通信的程序,运行的时候先向串口发送一个数据0x12,然后等待接收,当PC机发送一个数据到单片机,单片机就对这个数据进行加1处理,然后发回到PC机显示 ...

  2. avr模拟串口通讯c语言,AVR系列之串口通讯

    昨晚搬动了电脑 今早又瞎忙了一上午 那个汗呀 加上身边环境蛮吵的 那个心烦着呢 现在就抽点时间敲敲键盘写写 算是整理一下此刻糟糕透顶的心情 也算是继续总结 总不能让这个系列的假期总结给落下来 既然说到 ...

  3. plc.单片机的串口通讯的调试方法——通过虚拟串口工具和串口助手来调试串口

    加一个,串口助手和虚拟串口工具统合使用的链接,可以一起看哦~https://blog.csdn.net/qq_32278309/article/details/101384003 博主是新入坑的新人, ...

  4. C++语言程序设计全真模拟试卷,《C++语言程序设计》模拟试卷

    <C++语言程序设计>模拟试卷 一.单选题(21分,每空1.5分) 1.在C++中,函数原型不能标识( ) A.函数的返回类型 B.函数参数的个数 C.函数参数类型 D.函数的功能 2.可 ...

  5. 单片机 多机通讯c语言,单片机多机串口通信.doc

    单片机多机串口通信 摘要 本文详细介绍了基于RS-485总线的单片机与多台单片机间的串行通信原理.实现方法和相应的通信硬件.软件设计.该设计是由单片机与单片机组成的主从控制系统,其中单片 关键词: 单 ...

  6. 51单片机串口通讯c语言程序,如何使用51单片机实现串口通信

    描述 STC51单片机一般带有1个串口,有的带有2个串口,串口一般用于下载程序和串口通信.串口通信特别适合控制设备,所以工控机的电脑上一般都带有串口. 51单片机的串口引脚为P3.0引脚与P3.1引脚 ...

  7. plc和pc串口通讯接线_PC与PLC的串口通信及编程实现

    35 PC 与 PLC 的串口通信及编程实现 黄植功 (广西师范大学物理与电子工程学院,广西  桂林  541004) 摘  要: 在自由口模式下,通信协议由用户自己的梯形图程序控制.用户可以使用梯形 ...

  8. 串口控制74HC164C语言,51单片机74HC164串口控制数码管显示

    一般数码管需要接7个脚才能显示,如果用单片机本身的I/O口,虽然可以但是浪费宝贵的i/O口资源.本例用移位寄存器74HC164作为数码管驱动进行控制. 74HC164特性   是一种8位串转并口的控制 ...

  9. 单片机原理与应用实验——串口(C语言),使用串口发送或接收数据,定时器1作为波特率发生器

    (基于51核的STC12C5A60S2,keil uvision5 mdk 5.25 编译) 1. 定时发送1字节数据给电脑,波特率9600 #include <STC12C5A60S2.h&g ...

最新文章

  1. rsyslog日志管理+LogAnalyzer
  2. 平安智慧城市:与时代同行,坚定数字化之路
  3. Eclipse中Junit测试中@Before不执行
  4. tensorboard出现OSError: [Errno 22] Invalid argument问题解决
  5. Eclipse——e(fx)clipse下载错误导致的安装失败解决方案
  6. 数据分析对企业的重要性
  7. Javascript注释规范
  8. MeteoInfoLab脚本示例:数据投影-FLEXPART
  9. word文件转换成PDF文件
  10. Android Merged manifest 错误
  11. 3天3万视频课程的笔记
  12. win2008R2 不能访问局域网共享\局域网共享中无本机,解决办法
  13. 如何设置微信公众号关注后自动回复多条图文链接
  14. 字典(JSON)数据写入文件并换行,Python
  15. 那些警示良言——韩愈
  16. 一篇学习HTTP状态码的神文:我与依依的橙色岁月
  17. 北京大学计算机科学实验班,北京大学信息科学技术学院2018年拟接收推荐-北京大学研究生院.pdf...
  18. 关于ros提到的那只turtle
  19. python怎么找出列表中的重复数据_python – 如何在列表中找到重复项并使用它......
  20. win2003 sp1 安装声卡Audio 的 UAA 总线驱动程序”出错解决

热门文章

  1. unity中Game视图中实现和Scene视图中一样的摄像机操作
  2. oppoa83t怎么升级android8,OPPO A83t原版系统刷机包_OPPO A83t最新升级包更新下载
  3. vue链接生成二维码
  4. 微信公共平台配置域名提示,协议头非法
  5. java判断200以内的素数_java判断101-200之间的素数并输出
  6. MySQL Deamon少量解读
  7. JAVAWEB常用测试浏览器
  8. 开源魔兽世界私服搭建
  9. Buct oj 1015
  10. 如何选择一款适合你的外贸管理软件