搜索
bottom↓
回复: 28

AVR单片机模拟串口程序 C语言(占一个定时器和两个IO)

[复制链接]

出0入0汤圆

发表于 2007-6-8 17:14:30 | 显示全部楼层 |阅读模式
在这里找了半天,没有一个合用的模拟串口程序, 自己写了一个并已测试通过。 为表示对论坛的支持共享给大家。



点击此处下载armok01157000.txt

出0入0汤圆

发表于 2007-6-8 19:57:26 | 显示全部楼层
谢谢!对楼主的程序很感兴趣,只是不知道怎么用。



要是楼主能给出程序的详细注释及开发编译环境就好了。

出0入0汤圆

发表于 2007-6-8 22:56:27 | 显示全部楼层
wangjxy

介绍一下,谢谢

出0入0汤圆

发表于 2007-6-9 00:48:45 | 显示全部楼层
看看这个,mega16上的,测试通过,http://bbs.avrvi.com/htm_data/33/0705/2678.html



实验2-5-6:IO口软件模拟USART串口



如果想使用两个USART口,而大部分的AVR芯片只有一个USAVR口,可以通过软件在普通的IO口上进行模拟RS232通讯。



这里给出一个范例,程序中为了时序的准确性,用了汇编语言,然后在C语言中调用。



注意:编译时,把.s文件和.c文件同时包含到工程中,在option-》paths的asm include path中加入你的ICC的include文件目录。



说明:为了方便实现功能,不进行其他的连接,我把程序的模拟IO设为了PD0和PD1,这和实际的USART脚一致,只要接好跳线就可以工作了。



但是你要知道,这里并没有启动硬件的USART。

出0入0汤圆

 楼主| 发表于 2007-6-11 15:39:51 | 显示全部楼层
//定时器定义:

// 设置T2 139uS定时中断, 中断时间计算 TCNT0 = 256 - T(S)*Fck(Hz)/分频数

//TCCR2=  0 停止T0; 1 Fck; 2 Fck/8; 3 Fck/64; 4 Fck/256; 5 Fck/1024; 6 外部下降沿; 7外部上升沿

void SetCPUtoT2()

{

    TCNT2=152;             //8M=117, 6M=152

    TCCR2=2;

    TIMSK |= (1<<TOIE2);

    asm("sei");

}







//IO引脚初始化:



    IORxd_PORT |= (1<<IORxd_BIT);      //带上拉输入引脚

    IORxd_DDR  &= ~(1<<IORxd_BIT);



    IOTxd_PORT |= (1<<IOTxd_BIT);     //输出引脚

    IOTxd_DDR  |= (1<<IOTxd_BIT);





主函数检查Uart1_RX_overtimer标志, 当其为0时表示接收到了一帧信息

        if(Uart1_RX_overtimer == 0) {

                Uart1_recv_haveframe = HAVE;

                Uart1_RX_overtimer = 0xff;

                process_Uart1_Recv_frame();

        }



以上的程序都是用IAR软件编译。 因为是用C编写, 不同的编译环境应该只是修改中断的定义就可以了。

提醒楼上的各位朋友, 程序只是用来学习参考,并没有直接使用的价值。

出0入0汤圆

发表于 2007-6-12 03:36:20 | 显示全部楼层
Procyon AVRlib:

(http://hubbard.engr.scu.edu/avr/avrlib/docs/html/index.html)

This uart library emulates the operation of a UART (serial port) using the AVR's hardware timers, I/O pins, and some software.



uartsw.c:

Timer 1 Output Compare A for transmit timing -Timer 1 Output Compare B for receive timing -Timer 1 Input Capture for receive triggering



uartsw2.c:

Timer 2 Output Capture for transmit timing -Timer 0 Output Capture for receive timing -External Interrupt 2 for receive triggering

出0入0汤圆

 楼主| 发表于 2007-6-12 12:04:02 | 显示全部楼层
5楼的朋友, 那样要占用两个定时器, 太占资源了吧! 而且还要用到外部中断做为开始位的检测。  按我上面的程序,只需要一个定时器就够了, 而且要是想实现双工,只要中断部分代码做一点修改就可。



可以利用硬件串口的接收原来来实现, 每一bit都扫描三次, 取多数值。 就样就可以了,何必浪费一个外部中断。 再说中断太多对于系统(特别是大型程序)不是好事情。

出0入0汤圆

发表于 2007-6-12 15:19:14 | 显示全部楼层
晕,希望LZ把Procyon AVRlib的范例看看再评论,不要一上来就贬低别人。



在Procyon AVRlib:里给出了两种方法用硬件模拟串口程序(都是双工)。而且uartsw.c: 中只使用了一个一个定时器和两个IO。



由于使用在两个例子中分别使用Timer 1 Input Capture for receive triggering或者External Interrupt 2 for receive triggering,因此程序的实时性很高。



1.uartsw.c: 中只使用了一个一个定时器和两个IO。

Overview

    This uart library emulates the operation of a UART (serial port) using the

AVR's hardware timers, I/O pins, and some software.



Specifically, this code uses:

-Timer 1 Output Compare A for transmit timing;

-Timer 1 Output Compare B for receive timing;

-Timer 1 Input Capture for receive triggering;



The above resources cannot be used for other purposes while this software UART is

enabled. The overflow interrupt from Timer1 can still be used for other timing,

but the prescaler for Timer1 must not be changed.



Serial output from this UART can be routed to any I/O pin. Serial input for this

UART must come from the Timer1 Input Capture (IC1) I/O pin. These options should

be configured by editing your local copy of "uartswconf.h".



2.uartsw2.c: 中使用了一个两个定时器和两个IO。(这里的资源是占用了比较多一些。)

Overview

    This uart library emulates the operation of a UART (serial port) using the AVR's hardware timers, I/O pins, and some software.



Specifically, this code uses:

-Timer 2 Output Capture for transmit timing

-Timer 0 Output Capture for receive timing

-External Interrupt 2 for receive triggering



The above resources cannot be used for other purposes while this software UART is enabled. The overflow interrupts from Timer0 and Timer2 can still be used for other timing, but the prescalers for these timers must not be changed.



Serial output from this UART can be routed to any I/O pin. Serial input for this UART must come from the External Interrupt 2 (INT2) I/O pin. These options should be configured by editing your local copy of "uartsw2conf.h".

出0入0汤圆

发表于 2007-6-12 21:17:17 | 显示全部楼层
Procyon AVRlib 那个我试过了,不好用啊

出0入0汤圆

发表于 2009-4-8 14:18:58 | 显示全部楼层
MARK!

出0入0汤圆

发表于 2009-4-14 19:50:26 | 显示全部楼层
学习了

出0入0汤圆

发表于 2009-4-20 17:25:19 | 显示全部楼层
收藏

出0入0汤圆

发表于 2009-5-14 15:41:17 | 显示全部楼层
testcode:

我用Procyon的uartsw做模拟串口,M8,7.3728MHz。编译通过,然后在pro***s里模拟,PB1发送的都是0x00。搞不清楚要怎么用这个uartsw库。

代码如下,请帮忙看一下,调用是不是有问题。

/* uartswconf.h */

#ifndef UARTSWCONF_H
#define UARTSWCONF_H

// constants/macros/typdefs

#define UARTSW_RX_BUFFER_SIZE        0x20        ///< UART receive buffer size in bytes

#define UARTSW_INVERT                                        ///< define to invert polarity of RX/TX signals
// when non-inverted, the serial line is appropriate for passing though
// an RS232 driver like the MAX232.  When inverted, the serial line can
// directly drive/receive RS232 signals to/from a DB9 connector.  Be sure
// to use a current-limiting resistor and perhaps a diode-clamp circuit when
// connecting incoming RS232 signals to a microprocessor I/O pin.

// if non-inverted, the serial line idles high (logic 1) between bytes
// if inverted, the serial line idles low (logic 0) between bytes


// UART transmit pin defines
#define UARTSW_TX_PORT                        PORTB        ///< UART Transmit Port
#define UARTSW_TX_DDR                        DDRB        ///< UART Transmit DDR
#define UARTSW_TX_PIN                        PB1                ///< UART Transmit Pin

// UART receive pin defines
// This pin must correspond to the
// Timer1 Input Capture (ICP or IC1) pin for your processor
#define UARTSW_RX_PORT                        PORTB        ///< UART Receive Port
#define UARTSW_RX_DDR                        DDRB        ///< UART Receive DDR
#define UARTSW_RX_PORTIN                         PINB        ///< UART Receive Port Input
#define UARTSW_RX_PIN                        PB0                ///< UART Receive Pin

#endif

====================
/* main.c */

//----- Include Files ---------------------------------------------------------
#include <avr/io.h>                // include I/O definitions (port names, pin names, etc)
#include <avr/interrupt.h>        // include interrupt support

#include "global.h"                // include our global settings
#include "uartsw.h"                // include uart function library
#include "rprintf.h"        // include printf function library
//#include "timer.h"                // include timer function library (timing, PWM, etc)

void rprintfTest(void);

//----- Begin Code ------------------------------------------------------------
int main(void)
{
        // initialize our libraries
        // initialize the UART (serial port)
        uartswInit();

        uartswInitBuffers();

        // set the baud rate of the UART for our debug/reporting output
        uartswSetBaudRate(9600);

        // initialize rprintf system
        // - use uartSendByte as the output for all rprintf statements
        //   this will cause all rprintf library functions to direct their
        //   output to the uart
        // - rprintf can be made to output to any device which takes characters.
        //   You must write a function which takes an unsigned char as an argument
        //   and then pass this to rprintfInit like this: rprintfInit(YOUR_FUNCTION);
        rprintfInit(uartswSendByte);

        // run the test
        rprintfTest();

        return 0;
}

void rprintfTest(void)
{
        // print single characters
        rprintfChar('H');
        rprintfChar('e');
        rprintfChar('l');
        rprintfChar('l');
        rprintfChar('o');
        rprintfChar(' ');
        rprintfChar('W');
        rprintfChar('o');
        rprintfChar('r');
        rprintfChar('l');
        rprintfChar('d');

        // print a carriage return, line feed combination
        //rprintfCRLF();
        // note that using rprintfCRLF() is more memory-efficient than
        // using rprintf("\r\n"), especially if you do it repeatedly
}

出0入0汤圆

发表于 2010-8-13 11:38:01 | 显示全部楼层

出0入0汤圆

发表于 2010-8-20 21:26:56 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-12 11:43:10 | 显示全部楼层
ji

出0入0汤圆

发表于 2011-4-1 21:04:27 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-4-26 22:09:00 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-5-12 01:18:32 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-18 13:56:16 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-22 10:22:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-23 13:04:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-23 14:23:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-7-14 16:02:27 | 显示全部楼层
mark        

出0入0汤圆

发表于 2013-8-27 14:25:56 | 显示全部楼层
mark 正准备用

出0入0汤圆

发表于 2014-11-3 11:55:46 | 显示全部楼层
avrio模拟串口!学习了!

出0入0汤圆

发表于 2014-11-7 23:40:06 | 显示全部楼层
谢谢分享!!!!!

出0入0汤圆

发表于 2014-11-10 16:33:46 | 显示全部楼层
maik
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-8 23:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表