c7140 发表于 2005-8-18 10:09:49

请教马老师:TWI采用中断编程的方法

马老师,您好!我是个学生,前段时间拜读过您的那个“URAT(RS232)低层驱动+中间层软件示例”文章后,使我很受启发,在编程上思想上有了比较大改变。

   现在,我学习到TWI编程了,采用查询的方法我已经调试成功了,现在想采用中断的方法,但是感觉跟UART有比较大的差别,更复杂了,有点不知该如何进行的感觉,请您指点一下!能否给个简单的代码举例,谢谢!

c7140 发表于 2005-8-25 14:13:30

我自己仿照Uart编程的方法编了个中断方式的程序,进行双机通讯的,如下,希望大家指点一下(代码片断)



#define Twi_ACK()                (TWCR = (1<<TWEA)|(1<<TWINT)|(1<<TWEN)|(1<<TWIE))

#define Twi_NoACK()        (TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWIE))

发送方:



/*======= TWI中断处理 ==============*/

SIGNAL (SIG_2WIRE_SERIAL)

{

        switch(TW_STATUS)

        {

                case TW_START:

                case TW_REP_START:

                        TWDR = SLA_W;

                        Twi_NoACK();

                        break;

                case TW_MT_SLA_ACK:

                        if(twi_counter)

                        {

                                --twi_counter;

                                TWDR = twi_buf;

                                if(++twi_rd_index == TWI_BUF_SIZE) twi_rd_index = 0;

                        }

                        Twi_NoACK();

                        break;

                case TW_MT_DATA_ACK:

                        if(twi_counter)

                        {

                                --twi_counter;

                                TWDR = twi_buf;

                                if(++twi_rd_index == TWI_BUF_SIZE) twi_rd_index = 0;

                                Twi_NoACK();

                        }

                        else

                                Twi_Stop();

                        break;

                case TW_MT_SLA_NACK:

                        Twi_Stop();

                        break;

                default:

                        Twi_Start();

                        break;

        }

}





/*====== 往TWI口缓冲区中发送数据 =======*/

void PutTwiChar(uchar c)

{

        while(twi_counter == TWI_BUF_SIZE);

        cli();

//--------------------------------------------------------//////////

        if(twi_counter);// ||((TWCR & _BV(TWINT)) == 0));////////// *******

//--------------------------------------------------------//////////

        else

                Twi_Start();



        twi_buf = c;

        if(++twi_wr_index == TWI_BUF_SIZE) twi_wr_index = 0;

        ++twi_counter ;

        sei();

}



接收方:

SIGNAL (SIG_2WIRE_SERIAL)

{

        switch(TW_STATUS)

        {

                case TW_SR_SLA_ACK:

                        Twi_ACK();

                        break;

                case TW_SR_DATA_ACK:

                        twi_buf = TWDR;

                        ++ twi_counter;

                        if(++twi_wr_index == TWI_BUF_SIZE) twi_wr_index = 0;

                        Twi_ACK();

                        break;

                case TW_SR_STOP:

                        Twi_ACK();

                        break;

                default:

                        Twi_ACK();

                        break;

        }

}



单向的数据传输,用起来还可以(做显示用,用一个单片机负责显示,接收主机的数据),只是标注 ******* 的地方,可能不稳定。

if(twi_counter);// ||((TWCR & _BV(TWINT)) == 0))

如果把 ||((TWCR & _BV(TWINT)) == 0)) 这个条件加上,运行有些问题;如果不判断可能会在发送还没有完成时写入Start把数据损坏了,这个地方不是很确定,还请马老师指点一下。也就是说我的问题是在我发送数据还没有结束时(TWINT为低时)如果发送Start命令会不会冲了我正在发送的数据,串口会好像


-----此内容被c7140于2005-08-25,14:21:28编辑过

xuhailun 发表于 2005-9-13 08:38:45

TWI 接口是否可以接8个负载.

greatsnows 发表于 2005-9-19 15:55:29

http://cache.amobbs.com/bbs_upload782111/files_3/armok0170986.JPG



另外,请问TW_STATUS是编译器已经定义好的吗?

greatsnows 发表于 2005-9-19 22:03:57

哦,找到了。的确如此,在avr/include下

imjacob 发表于 2011-6-9 21:56:19

对啊,这个例子马老师说是参考章节末的参考文献,但怎么办都找不到呢

machao 发表于 2011-6-10 12:59:01

教材书附带的光盘中有参考的应用和例程,或直接到ATMEL官网上下载,免费公开的。
页: [1]
查看完整版本: 请教马老师:TWI采用中断编程的方法