搜索
bottom↓
回复: 15

C8051F串口中断发送+缓冲区小程序

[复制链接]

出0入0汤圆

发表于 2009-12-10 20:12:18 | 显示全部楼层 |阅读模式
在OURDEV得到很多帮助,不敢藏私,也奉上 我的C8051F采用串口0 中断发送+缓冲区 的方式写的小程序吧~
请大家多多指教~~

主要原理:
上层直接将数据装入缓冲区,若手工发送标记(auto_uart0_tx_flg )为1,则置位串口中断标志TI0,启动发送,直至缓冲区为空(读写指针相等,此时将auto_uart0_tx_flg置0),否则,说明此时缓冲区中仍有数据,不用任何操作。

我的主要功能模块:
/*
********************************************************************************
*
* void UART0_Init (void);
* UART0配置
* Configure the UART0 using Timer1, for <baudrate> and 8-N-1.
*
********************************************************************************
*/

void UART0_Init (void)
{
        SCON0   = 0x50;                     // SCON0: mode 1, 8-bit UART, enable RX
        TMOD    = 0x20;                     // TMOD: timer 1, mode 2, 8-bit reload
        TH1    = -(SYSCLK/BAUDRATE/16);     // set Timer1 reload value for baudrate
        TR1    = 1;                         // start Timer1
        CKCON |= 0x10;                      // Timer1 uses SYSCLK as time base
        PCON  |= 0x80;                      // SMOD00 = 1,倍频
//        PCON  |= (1 << 6);                                        //
//        TI0    = 1;                         // Indicate TX0 ready
        in_uart_tx_buf =  uart_tx_buf;
        out_uart_tx_buf = uart_tx_buf;  
}

/*
********************************************************************************
*
* void UART0_ISR(void);
* USART0中断处理函数.
*
********************************************************************************
*/

void UART0_ISR(void) interrupt iv_UART0
{
        if(RI0)//是接收中断
        {
                RI0 = 0;//清接收中断标志位
                uart_data = SBUF0;//保存接收到的数据
                uart_rcv_data_flag = 1;//标志位置1

        }               

        if(TI0)//是发送中断
        {
                TI0 = 0;//清发送中断标志位,big problem
                uart_out_tx_buf();                         
        }
}

//进入发送中断后调用uart_out_tx_buf进行后续的处理
void uart_out_tx_buf(void)
{
        if(out_uart_tx_buf == in_uart_tx_buf)        //txbuf为空
        {
                ES0 = 0;
                auto_uart0_tx_flg = 1;//本次发送结束,下次还须手动触发
                return;
        }

                SBUF0 = *out_uart_tx_buf;
                out_uart_tx_buf++;
                if(out_uart_tx_buf == (uart_tx_buf + uart_tx_buf_len)) //缓冲区回绕
                        out_uart_tx_buf = uart_tx_buf;
                  
}

//上层程序调用串口发送数据的接口
void uart_in_tx_buf(INT8U *pt,INT8U datalen)
{
        INT8U *t,*p;
        t = in_uart_tx_buf;
        p = pt;
        while(datalen--)
        {
                t++;
                if(t == (uart_tx_buf + uart_tx_buf_len)) //回绕
                        t = uart_tx_buf;
                if(t == out_uart_tx_buf) //txbuf满
                        return;
                *in_uart_tx_buf = *p++;
                in_uart_tx_buf = t;
        }        
       
        uart_tx_start();
}


//手动启动串口发送
void uart_tx_start(void)
{
        if(auto_uart0_tx_flg == 1)
        {
                ES0 = 1;
                TI0 = 1;
                auto_uart0_tx_flg = 0;
        }
}

/*
********************************************************************************
*
*                                  MAIN
*
********************************************************************************
*/

void main(void)
{
        INT8U i;

        ALL_DEVICE_Init();//初始化,开全局中断等

        for(i=0;i<8;i++)
        {
                uart_in_tx_buf("helloworld",10);
//                delay(100);
        }
//        uart_in_tx_buf("helloworld helloworld helloworld",32);
        while(1);          
       
}

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

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2009-12-10 21:26:36 | 显示全部楼层
有多级缓冲的可以参考就好了

出0入0汤圆

 楼主| 发表于 2009-12-10 21:39:19 | 显示全部楼层
呵呵,多级缓冲还没有用过,等我看过多缓的原理了再编~
再一个,其实我上面的程序只处理的发送部分,接收部分目前因为多数为指令,为了确保不丢数据,我程序里面使用了很老土的办法,就是一帧开始后除非一帧结束或者帧超时,否则一直接收~这样虽然不丢数据了,但确实实时性差了很多呀,争取改进,呵呵

出0入0汤圆

发表于 2009-12-10 21:56:10 | 显示全部楼层
藏宝不如献拙

出0入0汤圆

发表于 2010-2-24 22:17:47 | 显示全部楼层
多谢~~~

出0入0汤圆

发表于 2010-2-25 16:55:07 | 显示全部楼层
thanks

出0入0汤圆

发表于 2010-3-9 08:27:28 | 显示全部楼层
good~~~

出0入0汤圆

发表于 2010-3-9 08:54:33 | 显示全部楼层
你可以看看Code Vision AVR编译器给AVR单片机生成的串口中断程序,相当不错的。

出0入0汤圆

发表于 2010-4-12 09:12:16 | 显示全部楼层
回复【7楼】XA144F
-----------------------------------------------------------------------

我这没有,朋友能把这个程序给我一份吗?zj_yang1983@163.com

出0入264汤圆

发表于 2010-4-12 09:33:36 | 显示全部楼层
学习

出0入0汤圆

发表于 2010-4-12 10:48:18 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-10 16:21:53 | 显示全部楼层
请问楼主,用过 340 的串口1吗?我在调串口1 可是只能发送不能接收 郁闷!

请楼主帮忙看下。。。谢谢
/****************************************************************
*
*UART1初始化
*****************************************************************/
void UART1_Init (void)
{
    SBRLL1    =0X8F;
    SBRLH1    =0XFD;    //波特率 9600 内部12M 晶振
    SCON1        =0X30;    //允许接收,准备好接收
    SMOD1        =0X6C;    //8位数据位,无奇偶校验,一位停止位;
        SMOD1       |=0X80;
    SBCON1    =0X43;    //使能UART1,1分频                          
    EIE2      |=0x02;
}
/*****************************************************************
*
*端口初始化函数
*****************************************************************/

void Port_IO_Init(void)
{
    P0SKIP    = 0xC3; //
    P1SKIP    = 0x08;
    XBR0      = 0x05; //P0.4 P0.5接到串口0上,SMBus 连接到P0.2、P0.3口上
    XBR1      = 0x70; //交叉开关、T0、T1使能
    XBR2      = 0x01; //UART1的 RXD1、TDX1分别接到P1.4、P1.2上
  //P1MDOUT   = 0x00;
}
/*****************************************************************
*
*系统初始化
*****************************************************************/
void System_Init(void)
{
//uint i;

PCA0MD    &= ~0x40; //关闭看门狗定时器
OSCICN    |= 0x03; //内部高频振荡器使能且振荡器按编程频率来运行
Port_IO_Init();
//T0_model_2ms_init();
//UART0_Init ();
UART1_Init ();
}

出0入0汤圆

发表于 2010-8-1 09:47:25 | 显示全部楼层
新注册网友等待审核中。。。

出0入0汤圆

发表于 2010-8-1 11:08:33 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-8-1 12:37:04 | 显示全部楼层
mark

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-4-27 07:07

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

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