搜索
bottom↓
回复: 16

转载个模拟串口

[复制链接]

出0入0汤圆

发表于 2009-4-27 02:59:01 | 显示全部楼层 |阅读模式
http://bbs.21ic.com/club/bbs/list.asp?boardid=9&page=1&t=3315086&tp=%u4F20%u8F7D%u4E00%u4EFD%u7CBE%u5178%u6770%u4F5C

测试了一下效果还真不错哦!

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2009-4-27 03:10:30 | 显示全部楼层
忘了介绍一下了,免得大家再花时间看。代码是一个全双功的模拟串口,还提供FIFO功能。(很少见吧,我也第一次见还不用外部中断的)。看了一下代码质量发现自己很惭愧,特别是代码变量的复用,我们也要多学习学习了一点都不浪费空间。

出0入0汤圆

发表于 2009-4-27 09:28:52 | 显示全部楼层
感谢分享,真是精品

出0入0汤圆

发表于 2009-4-27 09:41:20 | 显示全部楼层
【楼主位】 ssgyk

如果楼主方便的话,请您把手打过的代码粘贴上来,我晚上也做个测试.

省得大家都手打一次代码.

出0入0汤圆

发表于 2009-4-27 13:14:47 | 显示全部楼层
可直接用FOXIT READER把文本COPY出来

出0入0汤圆

 楼主| 发表于 2009-4-27 13:35:20 | 显示全部楼层
to 3楼:
没有什么代码要写得。框架代码是icc直接生成的。只做了简单调用.
int main(void)
{
        init_devices();
        UartInit();   //初始化
        while (1)
        {
                      BYTE len = GetFIFOCount();  //读取fifo内长度
                  if (len)
                  {
                    while (len--) WriteByte(ReadByte()); //读一个字节 发一个字节
                  }
         }
}
就这样了。用sscom不停的发测试就可以了

出0入0汤圆

发表于 2009-4-29 15:46:43 | 显示全部楼层
不多说,这个PDF是做过处理的,COPY出来的并非完全一致.至少我COPY出来的并非完全一致.

为方便大家,附上个人写的程序,今天看了一下我个人的回复,才想起这个帖子.所以进来补上.晚上睡觉之前手打的.尚未测试其实用性.因为比较忙.

可能在"朦胧"中会有笔误.请调试OK的朋友.指正.

下附程序.TimerToUart.c

////////////////////////////////////////////////////////////
//
//                                AVR 一个定时器实现全双工模拟串口
//
//设计原理:        本文通信波特率为9600bps,使用1个定时器(频率38400Hz)
//                        通过3次分频,为TX和RX二个通道同时提供准确的时钟驱动.
//                        RX不需要使用外部中断.直接由定时器进行IO扫描.
//设计模式:        异步操作模式.
//试验环境:        ATmega16(L). 16MHz外部晶振.
//试验结果:        经过24小时不间断随机数据测试无一错误.
//后期扩展:        提供更高的时钟支持更多的串口同时扫描.
//
////////////////////////////////////////////////////////////

#include <API/TYPEOEF.H>        //类型定义

//IO定义
#define GPRS_SET_TX()        PORTD |= (1<<1)
#define GPRS_CLR_TX()        PORTD &=~(1<<1)
#define GPRS_PIN_RX()        PIND&(1<<0)

//38400时钟
#define TIMEBASE OxFE0D

//为RX提供32字节的FIFO支持
#define MAX_FIFO        32

static unsigned char ReceiverFIFO[MAX_FIFO];
static unsigned char FIFOI,FIFOT;

extern unsigned int  TIMEBASE;
extern unsigned char TX_TIME;
static unsigned char RXBIT,TXCOUNT,RXBUF;
static unsigned char TXBIT,TXBUF;

//初始化
void UartInit(void)
{
        ////////////////////////////////
        RXBIT=0;
        RXCOUNT=1;
        FIFOI=0;
        FIFOT=0;
        ////////////////////////////////
        //配置IO模式
        DDRD|= (1<<1);        //TX PD1
        DDRD&=~(1<<0);        //RX PD0
}

//发送一个字节
void WriteByte(unsigned char value)
{
        TXBUF=value;
        TXBIT=0;
        while((TXBIT&0x80)==0);
}

//发送一个字符串
void WriteStr(unsigned char *str)
{
        while(*str)
        {
                WriteByte(*str+);
        }
}

//获取RX FIFO收到的长度
unsigned char GetFIFOCout(void)
{
        if(FIFOI==FIFOT)
        {
                return 0;
        }
        else if(FIFOI>FIFOT)
        {
                FIFOT=0;
                return (FIFOI-FIFOT);
        }
        else
        {
                return ((MAX_FIFO-FIFOT)+FIFOI);
        }
}

//从RX FIFO中获取一个字节
unsigned char ReadByte(void)
{
        unsigned char RET=ReceiverFIFO[FIFOT++];
        if(FIFOT>MAX_FIFO-1)
        {
                FIFOT=0;
                return RET;
        }
}

//AVR Timer中断函数
//注意:为了保证代码在限定的时间下顺利完成,应尽量减少使用乘除法.
#pragma interrupt_handler timer1_ovf_isr:9
void timer1_ovf_isr(void)
{
        char RXB=GPRS_PIN_RX;
        TCNTIH=TIMEBASE/256;
        TCNT1L=TIMEBASE%256;
        ///////////////////////////////////
        //接收部分
        if(RXBIT&0x80)        //判断接收是否完成
        {
                if(RXB)
                {
                        RXBIT=0;
                }
        }
        else if(RXBIT==0&&RXB==0)
        {
                RXBIT=RXCOUNT;
                RXBUF=0;
        }
        else if((RXCOUNT==(RXBIT$0X11))&&RXBIT)
        {
                BYTE rxbitpos=RXBIT>>2;
                switch(rxbitpos)
                {
                        case 0:
                        case 1:
                        case 2:
                        case 3:
                        case 4:
                        case 5:
                        case 6:
                                RXBUF>>1;
                                if(RXB)
                                {
                                        RXBUF|=0x80;
                                }
                                RXBIT=(RXBIT&0x11)|((rxbitpos+1)<<2);
                                break;
                        case 7:
                                RXBUF>>=1;
                                if(RXB)
                                {
                                        RXBUF|=0x80;
                                        RXBIT=0;
                                }
                                else RXBIT=0x80;
                        /////////////////////////////
                                //接收数据存放入FIFO
                                ReceiveFIFO[FIFOI++]=RXBUF;
                                if(FIFOI>MAX_FIFO-1)
                                {
                                        FIFOI=0;
                                }
                                break;
                }
        }
        if(RXCOUN==3)
        {
                RXCOUN=1;
        }
        else RXCOUN++;
        if(TX_TIME==2)
        {
                if((TXBIT&0x80)==0)
                {
                        switch(TXBIT)
                        {
                                case 0:
                                        GPRS_CLR_TX();
                                        break;
                                case 1:
                                case 2:
                                case 3:
                                case 4:
                                case 5:
                                case 6:
                                case 7:
                                case 8:
                                        if(TXBUF&0x01)
                                        {
                                                GPRS_SET_TX();
                                        }
                                        else GPRS_CLR_TX();
                                        TXBUF>>=1;
                                        break;
                                case 9:
                                        GPRS_SET_TX();
                                        break;
                                case 10:
                                        TXBIT|=0x80;
                                        break;
                        }
                        TXBIT++;
                }
                PORTD|=(1<<2);
                TX_TIME=0;
        }
        else
        {
                PORTD&=~(1<<2);
                TX_TIME++;
        }
}

出0入0汤圆

发表于 2009-4-29 16:44:25 | 显示全部楼层
坛友们

这个程序是不是少timer的初始化部分啊

9600bps 也就是 大约0.1ms 一个bit吧

出0入0汤圆

发表于 2011-6-15 15:54:28 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-25 13:37:39 | 显示全部楼层
有点模糊

出0入0汤圆

发表于 2011-12-22 10:26:32 | 显示全部楼层
谢谢6楼

出0入0汤圆

发表于 2014-5-20 15:04:06 | 显示全部楼层
正需要这个

出0入0汤圆

发表于 2014-5-20 15:04:23 | 显示全部楼层
链接打不开啊

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-8-26 10:18

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

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